Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么在python中日志记录是这样的_Python_Logging - Fatal编程技术网

为什么在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