调用"日志记录"会干扰其他模块



假设我有以下a.py,它调用b.py

b.py

import logging

logging.info('11111 in b')     
def do():                      
logging.info('2222222 in b')  

a.py

import logging
import sys
import b
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.info('11111111 in a')
b.do()

当我执行a.py时,没有任何东西被记录到stdout,但当我从b.py注释掉logging.info('11111 in b')时,如下所示:

b.py

import logging

# logging.info('11111 in b')     
def do():                      
logging.info('2222222 in b')  

我可以看到日志输出:

INFO:root:11111111 in a
INFO:root:2222222 in b

很明显,这与注释行有关,但我本以为basicConfig()会在导入b模块后设置一些内容,但事实并非如此。

有人能解释一下这里发生了什么吗?

在配置日志记录系统之前,导入语句import b已触发日志记录事件。当使用未配置的日志记录系统记录事件时,它会使用默认配置自动配置:stderr上级别为WARNING的流处理程序。

如果根记录器已经配置了处理程序,则随后的basicConfig调用将不执行任何操作。因此,INFO级别的事件被过滤掉,因为根记录器配置了一个阈值更高的WARNING处理程序。

正确的解决方案是确保在配置日志记录系统之前不记录事件。通常这意味着避免记录事件或在全局(模块级别(范围内进行任何工作。

然而,由于Python 3.8,有一种变通方法可以强制重新配置日志系统:

logging.basicConfig(stream=sys.stdout, level=logging.INFO, force=True)

在较旧的Python版本中,您可以手动清除根日志处理程序:

del logging.getLogger().handlers[:]
logging.basicConfig(stream=sys.stdout, level=logging.INFO)

我怀疑这与如何配置输出有关。我不认为在.py中设置它会为两个文件都设置它,有点像你必须在两个文件中导入日志记录,否则会出错。

如果您将basicConfig行添加到b.py,那么您可以保留logging.info('11111 in b')并看到它被打印出来。

最新更新