Django休息框架在不同的文件上记录不同的级别

时间:2018-03-07 11:23:33

标签: python django logging error-logging

我正在处理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!')

现在所有内容都记录在stdout上(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上。我想我需要应用一些过滤或其他东西。我会试着弄明白。

1 个答案:

答案 0 :(得分:2)

下面:

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

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

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

其他一些说明:

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

  2. 'filename': LOGGING_ROOT + "/info.log"这种使用os.path的全部内容失败了 - 您希望os.path.join(LOGGING_ROOT, "info.log")代替