在 Django 中添加自定义日志记录

Add custom log records in Django

我已将以下日志记录配置添加到我的 Django 应用程序的 settings.py 文件中:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
        },
    },
}

现在,我只是想在 views.py 中的一个视图中添加一些自定义日志记录,但记录器似乎是 NOTSET,这意味着只有 warning 级别及以上记录:

import logging
from django.http import JsonResponse

logger = logging.getLogger(__name__)

def testing(request):
    logger.info("Doesn't show...")
    logger.warning(f"Log Level: {logger.level} = {logging.getLevelName(logger.level)}")
    return JsonResponse({"Hello": "World"})

上面的代码片段记录了以下内容:

Log Level: 0 = NOTSET

我是不是做错了什么?为什么没有设置记录器的级别(即使我在 settings.py 中明确设置了它)?

由于您为 'django' 配置了记录器并且您的模块(大概)不在 django 包中,您需要明确地获取 'django' 记录器:

# logger = logging.getLogger(__name__)
logger = logging.getLogger('django')

否则,您会得到一个未配置的记录器,因此 logger.levelNOTSET

但是,Django 将使用您的日志记录配置。

来自https://docs.python.org/3/library/logging.html

The logger name hierarchy is analogous to the Python package hierarchy, and identical to it if you organise your loggers on a per-module basis using the recommended construction logging.getLogger(__name__). That’s because in a module, __name__ is the module’s name in the Python package namespace.

为什么会出现这种行为?

logging.getLogger(__name__) 语句将使用 指向当前模块的虚线路径初始化 python 记录器。在您的情况下,它将是 my_app.views。 Django 无法理解您从 views.py 创建的日志,因为您的记录器名称是 my_app.views未在 settings.py 中列出。如果您没有相应地指定 logger name/logger-name pattern,Django 将不会对日志做任何事情。

如何显示 warning 日志?

我希望如此 post 这解释得很好,Python logging not outputting anything

解决方案

选项-1

settings.py[=23= 中更改您的 记录器名称 ]

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        <b>'my_app.views':</b> {
            'handlers': ['console'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
        },
    },
}

密钥更改: 我已将记录器名称 django 更改为 my_app.views

选项-2

getLogger方法中指定记录器名称

logger = logging.getLogger(<b>'django'</b>)

要点:logger的名字和Django Settings模块中定义的logger的名字要一致

因为 logging.getLogger(__name__) 创建一个 python 带有当前模块路径的记录器,并且由于您没有在您的设置中注册这个记录器,Django 无法理解您拥有的记录器从 views.py 创建。一种解决方案是像@JPG 之前所说的那样在您的设置中注册它。另一种解决方案是手动创建它。例如,您可以创建一个 Utils.py 文件并创建此函数来创建您的记录器。

import logging
def get_view_logger(view_name):
    logger = logging.getLogger(view_name)
    logger.setLevel(logging.INFO)
    handler = TimedRotatingFileHandler(os.path.join(BASE_DIR, 'log/' + view_name + '.log'),
                                       when='midnight', backupCount=20, encoding="utf8")
    formatter = logging.Formatter('%(asctime)s [%(levelname)s] : %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    return logger

您可以自定义记录器的每个组件,如处理程序、格式化程序等。