为什么日志记录在python中是这样的

2024-05-26 09:20:31 发布

您现在位置:Python中文网/ 问答频道 /正文

所以,最近,我在我的项目中遇到了一些奇怪的行为,所以我做了一个小测试来重现这种行为。以下是完整的代码:

import logging
from logging import config

config.dictConfig({
    'version': 1,
    'formatters': {
        'fmt_root':    {'format': '[ /        ] - %(levelname)s - %(name)s - %(message)s'},
        'fmt_pkg':     {'format': '[ /pkg     ] - %(levelname)s - %(name)s - %(message)s'},
        'fmt_pkg_sub': {'format': '[ /pkg/sub ] - %(levelname)s - %(name)s - %(message)s'},
    },
    'handlers': {
        'hnd_root': {
            'class': 'logging.StreamHandler',
            'level': logging.DEBUG,
            'stream': 'ext://sys.stdout',
            'formatter': 'fmt_root',
        },
        'hnd_pkg': {
            'class': 'logging.StreamHandler',
            'level': logging.DEBUG,
            'stream': 'ext://sys.stdout',
            'formatter': 'fmt_pkg',
        },
        'hnd_pkg_sub': {
            'class': 'logging.StreamHandler',
            'level': logging.DEBUG,
            'stream': 'ext://sys.stdout',
            'formatter': 'fmt_pkg_sub',
        },
    },
    'root': {
        'handlers': ['hnd_root'],
        'level': logging.DEBUG,
    },
    'loggers': {
        'pkg': {
            'handlers': ['hnd_pkg'],
            'level': logging.WARNING,
            'propagate': True,
        },
        'pkg.sub': {
            'handlers': ['hnd_pkg_sub'],
            'level': logging.INFO,
            'propagate': True,
        },
    },
})

logging.getLogger().info('message 1')
logging.getLogger('pkg').info('message 2')
logging.getLogger('pkg.sub').info('message 3')

这个小程序的输出是:

^{pr2}$

现在,这不是我所期望的结果。为什么“消息2”没有记录在根日志记录器上(消息级别是info,root接受调试级别),为什么“message 3”登录到'pkg'logger(消息级别是info,pkg接受警告)?在

我做了一些研究,我发现消息级别只针对消息直接发布到的记录器进行检查-所有父级记录器级别(直到根)都不会被检查,只检查它们的处理程序级别。这在我看来很奇怪。对此有何解释?它为什么会这样?这有哪些用例?

PS:我期望从这段代码中得到的行为正是我在切换处理程序和记录器级别时得到的结果:

[ /        ] - INFO - root - message 1
[ /        ] - INFO - pkg - message 2
[ /pkg/sub ] - INFO - pkg.sub - message 3
[ /        ] - INFO - pkg.sub - message 3

Tags: debuginfoformat消息messagelogginghandlerspkg
1条回答
网友
1楼 · 发布于 2024-05-26 09:20:31

首先使用记录器的电平,作为通过/不通过检查。这是因为一个记录器可以有多个处理程序。例如,您可以有一个FileHandler写入磁盘INFO和一个{a2}只发送CRITICAL
如果它通过了检查,那么日志将被发送到loggers处理程序,当propagate设置为True时,它也会发送到您调用的日志的父日志记录器的处理程序,忽略这些日志记录器中的级别检查。在

这样,message 2根本不会被打印,因为它没有通过记录器的级别检查,但是message 3将打印3次,因为该记录器设置为低于INFO'的级别,\pkg和{}的处理程序设置在低于{}的级别。在

简而言之,logger级别意味着“我应该把这个发送给处理程序吗?”处理程序级别的意思是“我应该把这个写到磁盘/控制台/套接字等吗?”。在

例1。在

Logger  | Logger level | Handler Level
/       | CRITICAL     | DEBUG
pkg     | CRITICAL     | DEBUG
pkg.sub | DEBUG        | DEBUG

使用logging.getLogger('pkg.sub').debug('message 3')将打印:

^{pr2}$

例2。在

Logger  | Logger level | Handler Level
/       | CRITICAL     | INFO
pkg     | CRITICAL     | DEBUG
pkg.sub | DEBUG        | DEBUG

使用logging.getLogger('pkg.sub').debug('message 3')将打印:

^{4}$

例3。在

Logger  | Logger level | Handler Level
/       | CRITICAL     | DEBUG
pkg     | CRITICAL     | INFO
pkg.sub | DEBUG        | DEBUG

使用logging.getLogger('pkg.sub').debug('message 3')将打印:

[ /pkg/sub ] - DEBUG - pkg.sub - message 3
[ /        ] - DEBUG - pkg.sub - message 3

为了获得您想要的结果,您需要以下设置:

Logger  | Logger level | Handler Level
/       | DEBUG        | DEBUG
pkg     | INFO         | WARNING
pkg.sub | INFO         | DEBUG

相关问题 更多 >