为什么basicConfig中的python日志记录级别无效? [英] why does python logging level in basicConfig have no effect?

查看:273
本文介绍了为什么basicConfig中的python日志记录级别无效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

import logging

# root logger
root = logging.getLogger()      # root
ch = logging.StreamHandler()
ch.setLevel(logging.WARN)
formatter = logging.Formatter('[root] %(levelname)s - %(message)s')
ch.setFormatter(formatter)
root.addHandler(ch)

# logging as child
c = logging.getLogger('mod')
c.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('[mod] - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
c.addHandler(ch)

c.error('foo')
c.warning('foo')
c.info('foo')
c.debug('foo')

输出:

[mod] - ERROR - foo
[root] ERROR - foo
[mod] - WARNING - foo
[root] WARNING - foo
[mod] - INFO - foo
[mod] - DEBUG - foo

没关系.根目录的级别为WARN,因此不会打印根目录的INFODEBUG. 但是当我使用basicConfig:

It's OK. Level of root is WARN, so INFO and DEBUG of root is not printed. But when I use basicConfig:

import logging

# config root logger
logging.basicConfig(level=logging.WARN, format='[root] %(levelname)s - %(message)s')

# logging as child
c = logging.getLogger('mod')
c.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('[mod] - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
c.addHandler(ch)

c.error('foo')
c.warning('foo')
c.info('foo')
c.debug('foo')

输出:

[mod] - ERROR - foo
[root] ERROR - foo
[mod] - WARNING - foo
[root] WARNING - foo
[mod] - INFO - foo
[root] INFO - foo
[mod] - DEBUG - foo
[root] DEBUG - foo

basicConfig的级别是WARN,为什么可以打印root的INFODEBUG级别?

The level of basicConfig is WARN, why level INFO and DEBUG of root can be printed?

当我使用logging.info时,它会生效.

And when I use logging.info, it effects.

推荐答案

您正在查看这些[root]信息和调试消息,因为您对logging.basicConfig的调用会创建根级别为 Handler NOTSET.级别为NOTSET的处理程序将输出其收到的任何消息(请参见 Handler.setLevel ).

You are seeing those [root] info and debug messages because your call to logging.basicConfig creates a root Handler with a level of NOTSET. A handler with a level of NOTSET will output any message it receives (see Handler.setLevel).

>>> import logging
>>> logging.basicConfig(level=logging.WARN, format='[root] %(levelname)s - %(message)s')
>>> [handler.level == logging.NOTSET for handler in logging.getLogger().handlers]
[True]

这与您的第一个示例不同,因为在您的第一个示例中,您正在创建级别为WARN的根处理程序.

This differs from your first example because in your first example you are creating a root handler with a level of WARN.

logging.basicConfiglevel=参数用于设置根 Logger 的级别,而不是根 Handler 的级别.

The level= parameter for logging.basicConfig is used to set the level of the root Logger not any root Handler.

日志消息将传播到父级Logger,但不考虑任何父级Logger的级别.决定所有输出"的是处理程序的级别.

Log messages are propagated up to parent Loggers but the level of any parent Loggers is not considered. It is the level of any Handlers that decides what gets "outputted".

针对 logging.Logger.propagate 的文档:

消息直接传递给祖先记录器的处理程序-既不考虑所讨论祖先记录器的级别也没有过滤器.

Messages are passed directly to the ancestor loggers’ handlers - neither the level nor filters of the ancestor loggers in question are considered.

那么,什么是Logger.level?

记录器使用其级别来决定是否将消息传播到其记录器和任何父记录器的处理程序.

What is Logger.level for then?

A Logger uses it's level to decide if to propagate a message to its and any parent loggers' handlers.

如果Logger没有设置级别,则它会询问其祖先Logger的级别并使用该级别(请参阅

If a Logger does not have a level set then it asks its ancestor Loggers for their level and uses that (see logging.Logger.setLevel).

因此,仅当您未在子记录器上设置级别时,根记录器的级别才有意义.

So, the root logger's level is only relevant if you have not set the level on your child logger.

这篇关于为什么basicConfig中的python日志记录级别无效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆