Django rest框架在不同文件上记录不同级别

Posted

技术标签:

【中文标题】Django rest框架在不同文件上记录不同级别【英文标题】:Django rest framework logging different levels on different files 【发布时间】:2018-08-15 11:37:50 【问题描述】:

我正在处理Django REST framework,我希望有单独的文件来记录数据。

我想要一个简单交易的文件,例如GET、PUT、POST 等以及一个包含错误的文件,我将在出现错误时收集这些文件。

我一直在阅读Django Logging Documentation 并且想出了一些关于如何记录信息数据的配置。配置示例如下:

settings.py

STATIC_URL = '/static/'
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')
LOGGING_ROOT = os.path.join(STATIC_ROOT, 'logging')

LOGGING = 
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': 
        'file': 
            'level': 'INFO',
            'class': 'logging.FileHandler',
            'filename': LOGGING_ROOT + "/info.log",
        ,
    ,
    'loggers': 
        'django': 
            'handlers': ['file'],
            'level': 'INFO',
            'propagate': True,
        ,
    ,

它作为文件中预期的数据样本工作:

"PUT /upload/dat.txt HTTP/1.1" 204 14
"OPTIONS / HTTP/1.1" 200 10020
"GET / HTTP/1.1" 200 9916

我尝试在 settings.py 文件中应用另一个处理程序,例如:

LOGGING = 
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': 
        'fileInfo': 
            'level': 'INFO',
            'class': 'logging.FileHandler',
            'filename': LOGGING_ROOT + "/info.log",
        ,
        'fileDebug': 
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': LOGGING_ROOT + "/debbug.log",
        ,
    ,
    'loggers': 
        'django': 
            'handlers': ['fileInfo'],
            'level': 'INFO',
            'propagate': True,
        ,
        'django': 
            'handlers': ['fileDebug'],
            'level': 'DEBUG',
            'propagate': True,
        ,
    ,

我没有按预期工作,现在我在同一个文件 debug.log 上获取所有数据(INFO 和 DEBUG)。所以我决定通过日志库采用另一种方法。我想不通的是如何将这些日志错误的输出通过管道传输到目录中,例如(路径/errors.log)。

来自文档:

# import the logging library
import logging

# Get an instance of a logger
logger = logging.getLogger(__name__)

def my_view(request, arg1, arg):
    ...
    if bad_mojo:
        # Log an error message
        logger.error('Something went wrong!')

我发现了这个类似的问题No handlers could be found for logger,如果我应用以下内容,它就会起作用:

import logging
logging.basicConfig()
logger = logging.getLogger(__name__)
logger.error('Something went wrong!')

现在一切都记录在标准输出上(INFO 和 ERROR)。有没有办法组合这些配置?

我想将所有请求记录到 info.log 文件中,并在我选择文件时在 error.log 文件中记录错误。

更新:

bruno desthuilliers 提供的解决方案示例如下:

settings.py

LOGGING = 
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': 
        'fileInfo': 
            'level': 'INFO',
            'class': 'logging.FileHandler',
            'filename': os.path.join(LOGGING_ROOT, "info.log"),
        ,
        'fileDebug': 
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': os.path.join(LOGGING_ROOT, "debug.log")
        ,
        'console': 
            'class': 'logging.StreamHandler',
        ,
    ,
    'loggers': 
        'django': 
            'handlers': ['console', 'fileInfo', 'fileDebug'],
            'level': 'DEBUG',
            'propagate': True,
        ,
    ,

我还找到了Making Python loggers output all messages to stdout in addition to log。我当前的修改示例:

import logging
from thanosTest import settings
logging.basicConfig(filename=os.path.join(settings.LOGGING_ROOT, "error.log"))
stderrLogger = logging.StreamHandler()
stderrLogger.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
logging.getLogger().addHandler(stderrLogger)
logging.error('Something went wrong!')

现在所有内容都记录在 error.log 中。我想我需要应用一些过滤或其他东西。我会努力弄清楚的。

【问题讨论】:

查看python中的日志记录级别,低于级别的日志消息将被忽略;具有严重级别或更高级别的日志消息将由为该记录器提供服务的任何一个或多个处理程序发出,除非处理程序的级别已设置为比级别更高的严重级别。参考:docs.python.org/3/library/logging.html#levels 上面提到的情况:Debug 文件也会有 Info 日志,但是 Info 文件不会有 Debug 日志 【参考方案1】:

这里:

'loggers': 
    'django': 
        'handlers': ['fileInfo'],
        'level': 'INFO',
        'propagate': True,
    ,
    'django': 
        'handlers': ['fileDebug'],
        'level': 'DEBUG',
        'propagate': True,
    ,

你定义了 'django' 键两次,所以第二个会覆盖第一个。

作为一般规则,如果您想要给定记录器的特定设置,请将其配置为不同的记录器(即每个包或 django 应用程序一个记录器)。另请注意,记录器的“处理程序”是列表,因此每个记录器可以有多个处理程序(即一个用于调试,一个用于信息)。 logging 库有点复杂,但花时间去read the full doc 尝试一下是值得的,真的。

其他几点说明:

    为多进程应用程序使用文件处理程序(在生产中,django 通常由多进程前端服务器提供服务)通常不是一个坏主意(对文件的并发写入访问永远不会真正起作用)。

    这种'filename': LOGGING_ROOT + "/info.log" 有点违背了使用os.path 的全部意义——你想要os.path.join(LOGGING_ROOT, "info.log") 代替

【讨论】:

它按预期工作,但我仍然有一个小问题,我无法用 logger.error('Error message') 解决。我将更新我的问题以提供更多信息和发现。

以上是关于Django rest框架在不同文件上记录不同级别的主要内容,如果未能解决你的问题,请参考以下文章

django rest框架-如何在根级别停止子重复

如何在 Django 中使用 RESTful API

如何使用 Django Rest Framework 在 Django 中进行操作日志记录

如何在带有 Django Rest 框架的 React 前端使用 Django 用户组和权限

如何在 django rest 框架中的嵌套序列化器相关对象上使用 prefetch_related?

ViewSet方法的Django rest框架permission_classes