为什么在python中日志记录是这样的
所以,最近,我在我的项目中遇到了一些奇怪的行为,所以我做了一个小测试来重现这种行为。以下是完整的代码:为什么在python中日志记录是这样的,python,logging,Python,Logging,所以,最近,我在我的项目中遇到了一些奇怪的行为,所以我做了一个小测试来重现这种行为。以下是完整的代码: import logging from logging import config config.dictConfig({ 'version': 1, 'formatters': { 'fmt_root': {'format': '[ / ] - %(levelname)s - %(name)s - %(message)s'},
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')
这个小程序的输出是:
[ / ] - INFO - root - message 1
[ /pkg/sub ] - INFO - pkg.sub - message 3
[ /pkg ] - INFO - pkg.sub - message 3
[ / ] - INFO - pkg.sub - message 3
现在,这不是我自然期望的结果。为什么“消息2”未登录到根记录器(消息级别为info,根接受调试级别),为什么“消息3”登录到“pkg”记录器(消息级别为info,pkg接受警告)
我做了一些研究,发现消息级别只针对消息直接发布到的记录器进行检查-不检查所有父记录器级别(直到根),只检查它们的处理程序级别<这对我来说似乎很奇怪。对此有何解释?为什么会这样?这有哪些使用案例?
PS:如果我切换处理程序和记录器级别,我期望从这段代码中得到的行为正是我所得到的:
[ / ] - INFO - root - message 1
[ / ] - INFO - pkg - message 2
[ /pkg/sub ] - INFO - pkg.sub - message 3
[ / ] - INFO - pkg.sub - message 3
首先使用记录器的液位,作为通过/不通过检查。这是因为一个记录器可以有多个处理程序。例如,您可以有一个写入磁盘
INFO
及更高版本的,以及一个只发送电子邮件CRITICAL
如果它通过了该检查,那么日志将被发送到记录器处理程序,并且当“传播”设置为
True
,它也将被发送到您调用的日志的父记录器的处理程序,忽略这些记录器中的级别检查
这样,消息2
就不会被打印,因为它没有通过记录器的级别检查,但是消息3
将打印3次,因为记录器的级别设置低于INFO'
,并且\
的处理程序,pkg
和pgk.sub
的设置级别低于INFO
简而言之,记录器级别意味着“我应该将其发送给处理程序吗?”而处理程序级别意味着“我应该将其写入磁盘/控制台/套接字等吗?”
例1
Logger | Logger level | Handler Level
/ | CRITICAL | DEBUG
pkg | CRITICAL | DEBUG
pkg.sub | DEBUG | DEBUG
使用logging.getLogger('pkg.sub').debug('message 3')
将打印:
[ /pkg/sub ] - DEBUG - pkg.sub - message 3
[ /pkg ] - DEBUG - pkg.sub - message 3
[ / ] - DEBUG - pkg.sub - message 3
[ /pkg ] - DEBUG - pkg.sub - message 3
[ / ] - DEBUG - pkg.sub - message 3
[ /pkg/sub ] - DEBUG - pkg.sub - message 3
[ / ] - DEBUG - pkg.sub - message 3
例2
Logger | Logger level | Handler Level
/ | CRITICAL | INFO
pkg | CRITICAL | DEBUG
pkg.sub | DEBUG | DEBUG
使用logging.getLogger('pkg.sub').debug('message 3')
将打印:
[ /pkg/sub ] - DEBUG - pkg.sub - message 3
[ /pkg ] - DEBUG - pkg.sub - message 3
[ / ] - DEBUG - pkg.sub - message 3
[ /pkg ] - DEBUG - pkg.sub - message 3
[ / ] - DEBUG - pkg.sub - message 3
[ /pkg/sub ] - DEBUG - pkg.sub - message 3
[ / ] - DEBUG - pkg.sub - message 3
例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
[ /pkg ] - DEBUG - pkg.sub - message 3
[ / ] - DEBUG - pkg.sub - message 3
[ /pkg ] - DEBUG - pkg.sub - message 3
[ / ] - DEBUG - pkg.sub - 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