【问题标题】:Add custom log records in Django在 Django 中添加自定义日志记录
【发布时间】:2020-04-02 21:48:27
【问题描述】:

我已将以下日志记录配置添加到我的 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"})

上面的 sn-p 记录了以下内容:

Log Level: 0 = NOTSET

我做错了吗?为什么没有设置logger的级别(虽然我在settings.py中明确设置了)?

【问题讨论】:

    标签: django logging django-settings django-logging


    【解决方案1】:

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

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

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

    然而,Django 将使用您的日志记录配置。

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

    记录器名称层次结构类似于 Python 包层次结构,如果您使用推荐的构造 logging.getLogger(__name__) 在每个模块的基础上组织记录器,则与它相同。这是因为在模块中,__name__ 是 Python 包命名空间中的模块名称。

    【讨论】:

      【解决方案2】:

      为什么会有这种行为?

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

      warning 日志如何显示?

      我希望这个所以这个帖子解释得很好,Python logging not outputting anything

      解决方案

      选项-1

      settings.py

      中更改您的 记录器名称
      LOGGING = {
          'version': 1,
          'disable_existing_loggers': False,
          'handlers': {
              'console': {
                  'class': 'logging.StreamHandler',
              },
          },
          'loggers': {
              'my_app.views': {
                  'handlers': ['console'],
                  'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
              },
          },
      }

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

      选项-2

      getLogger 方法中指定 记录器名称

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

      重点:记录器的名称和Django设置模块中定义的记录器名称应该相同。

      【讨论】:

        【解决方案3】:

        因为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
        

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

        【讨论】:

        • Django is not able to understand the logs → Django 在“理解”日志中没有任何作用。 Python 的logging 库只返回一个未配置的记录器。
        • Django 在理解 logger 方面也没有任何作用。甚至可以准确地说 Django 在这种情况下根本不参与。
        猜你喜欢
        • 2015-12-15
        • 1970-01-01
        • 2018-10-06
        • 1970-01-01
        • 1970-01-01
        • 2016-04-23
        • 1970-01-01
        • 1970-01-01
        • 2016-08-29
        相关资源
        最近更新 更多