【问题标题】:Django Setup Default LoggingDjango 设置默认日志记录
【发布时间】:2011-07-23 06:11:22
【问题描述】:

我似乎不知道如何为我的 Django 安装设置“默认”记录器。我想在settings.py 中使用Django 1.3 的新LOGGING 设置。

我查看了Django Logging Doc's example,但在我看来,他们只设置了将为特定记录器进行记录的处理程序。在他们的示例中,他们为名为“django”、“django.request”和“myproject.custom”的记录器设置了处理程序。

我要做的就是设置一个默认的logging.handlers.RotatingFileHandler,它将默认处理所有记录器。即,如果我在项目的某处创建了一个新模块,并用类似的东西表示:my_app_name.my_new_module,我应该能够做到这一点,并将所有日志记录转到旋转文件日志中。

# In file './my_app_name/my_new_module.py'
import logging
logger = logging.getLogger('my_app_name.my_new_module')
logger.debug('Hello logs!') # <-- This should get logged to my RotatingFileHandler that I setup in `settings.py`!

【问题讨论】:

    标签: python django logging


    【解决方案1】:

    我做了一个快速示例来检查在配置字典中同时引用root 键和空的'' 记录器时使用的配置。

    import logging.config
    
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'fmt1': {
                'format': '[FMT1] %(asctime)-15s %(message)s',
            },
            'fmt2': {
                'format': '[FMT2] %(asctime)-15s %(message)s',
            }
        },
        'handlers': {
            'console1': {
                'level': 'INFO',
                'class': 'logging.StreamHandler',
                'formatter': 'fmt1',
            },
            'console2': {
                'level': 'INFO',
                'class': 'logging.StreamHandler',
                'formatter': 'fmt2',
            },
        },
        # First config for root logger: console1 -> fmt1
        'root': {
            'handlers': ['console1'],
            'level': 'DEBUG',
            'propagate': True,
        },
        'loggers': {
            # Second config for root logger: console2 -> fmt2
            '': {
                'handlers': ['console2'],
                'level': 'DEBUG',
                'propagate': True,
            },
        },
    }
    
    logging.config.dictConfig(LOGGING)
    
    l1 = logging.getLogger()
    l2 = logging.getLogger('')
    root = logging.root
    
    l1.info("l1")
    l2.info("l2")
    root.info("root logger")
    

    打印以下结果:

    [FMT1] 2018-12-18 17:24:47,691 l1
    [FMT1] 2018-12-18 17:24:47,691 l2
    [FMT1] 2018-12-18 17:24:47,691 root logger
    

    表示root 键下的配置具有最高优先级。如果块被移除,结果是:

    [FMT2] 2018-12-18 17:25:43,757 l1
    [FMT2] 2018-12-18 17:25:43,757 l2
    [FMT2] 2018-12-18 17:25:43,757 root logger
    

    在这两种情况下,我都能够调试并确定所有三个记录器(l1l2root)都引用了相同的记录器实例,即根记录器。

    希望对像我一样对配置根记录器的 2 种不同方法感到困惑的其他人有所帮助。

    【讨论】:

      【解决方案2】:
      import logging
      logger = logging.getLogger(__name__)
      

      添加后:

      logging.basicConfig(
          level = logging.DEBUG,
          format = '%(name)s %(levelname)s %(message)s',
      )
      

      我们可以将格式更改为:

      format = '"%(levelname)s:%(name)s:%(message)s"  ',
      

      format = '%(name)s %(asctime)s %(levelname)s %(message)s',
      

      【讨论】:

        【解决方案3】:

        想通了……

        您通过使用空字符串引用它来设置“catch all”记录器:''

        例如,在以下设置中,我将所有日志事件保存到logs/mylog.log,但django.request 日志事件除外,它将保存到logs/django_request.log。因为我的django.request 记录器的'propagate' 设置为False,所以日志事件永远不会到达“捕获所有”记录器。

        LOGGING = {
            'version': 1,
            'disable_existing_loggers': True,
            'formatters': {
                'standard': {
                    'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
                },
            },
            'handlers': {
                'default': {
                    'level':'DEBUG',
                    'class':'logging.handlers.RotatingFileHandler',
                    'filename': 'logs/mylog.log',
                    'maxBytes': 1024*1024*5, # 5 MB
                    'backupCount': 5,
                    'formatter':'standard',
                },  
                'request_handler': {
                    'level':'DEBUG',
                    'class':'logging.handlers.RotatingFileHandler',
                    'filename': 'logs/django_request.log',
                    'maxBytes': 1024*1024*5, # 5 MB
                    'backupCount': 5,
                    'formatter':'standard',
                },
            },
            'loggers': {
                '': {
                    'handlers': ['default'],
                    'level': 'DEBUG',
                    'propagate': True
                },
                'django.request': {
                    'handlers': ['request_handler'],
                    'level': 'DEBUG',
                    'propagate': False
                },
            }
        }
        

        【讨论】:

        • 克里斯,这方面的 Django 文档并不令人困惑。谢谢你。
        • 微小的更正:评论暗示 sql 日志记录会受到 django.request 记录器的影响。要重定向 sql 日志记录,您需要为 'django.db' 定义一个记录器。 django.request 记录器处理 5xx 和 4xx http 响应。
        • 这有助于像我这样的其他菜鸟:记录器将创建日志文件,但您必须先创建 logs/ 文件夹:-)。否则在运行./manange.py runserver 时会出现错误。 @Chris W。感谢您的示例日志记录设置。这对我帮助很大!
        • @arindamroychowdhury 使用上述配置,如果您执行logger = logging.getLogger('foo'); logger.warn('bar');,则default 处理程序将捕获该日志记录,而&lt;time&gt; WARN: foo: bar 之类的内容将在logs/mylog.log 中结束
        • 谢谢,这个“”似乎是根记录器。在 Django 文档中找不到这条有用的信息。
        【解决方案4】:

        正如你在your answer 中所说,Chris,定义默认记录器的一种选择是使用空字符串作为其键。

        但是,我认为预期的方法是在日志配置字典的root 键下定义一个特殊的记录器。我在Python documentation 中找到了这个:

        root - 这将是根记录器的配置。除了propagate 设置不适用之外,配置的处理将与任何记录器一样。

        您的答案中的配置更改为使用root 键:

        LOGGING = {
            'version': 1,
            'disable_existing_loggers': True,
            'formatters': {
                'standard': {
                    'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
                },
            },
            'handlers': {
                'default': {
                    'level':'DEBUG',
                    'class':'logging.handlers.RotatingFileHandler',
                    'filename': 'logs/mylog.log',
                    'maxBytes': 1024*1024*5, # 5 MB
                    'backupCount': 5,
                    'formatter':'standard',
                },  
                'request_handler': {
                    'level':'DEBUG',
                    'class':'logging.handlers.RotatingFileHandler',
                    'filename': 'logs/django_request.log',
                    'maxBytes': 1024*1024*5, # 5 MB
                    'backupCount': 5,
                    'formatter':'standard',
                },
            },
            'root': {
                'handlers': ['default'],
                'level': 'DEBUG'
            },
            'loggers': {
                'django.request': {
                    'handlers': ['request_handler'],
                    'level': 'DEBUG',
                    'propagate': False
                },
            }
        }
        

        公平地说,我看不出两种配置之间的行为有任何差异。似乎用空字符串键定义记录器将修改根记录器,因为logging.getLogger('') 将返回根记录器。

        我更喜欢'root' 而不是'' 的唯一原因是它明确地修改了根记录器。如果您好奇,'root' 会覆盖 ''(如果您同时定义两者),因为根条目是最后处理的。

        【讨论】:

        • 是的,没错,有误请见谅!虽然使用 '' 而不是 'root' 在某种程度上是合乎逻辑的,但我仍然发现在从 2.6 fileConfig 逻辑到 2.7 dictConfig 的平滑过渡的过程中将 root 条目移动到 dict 的根目录中有点不一致。跨度>
        猜你喜欢
        • 2014-04-17
        • 2016-11-02
        • 1970-01-01
        • 1970-01-01
        • 2017-03-29
        • 2018-11-13
        • 2019-01-07
        • 2013-09-11
        • 2019-08-15
        相关资源
        最近更新 更多