0

我有一个自定义 python 记录器

# logger.py

import logging
#logging.basicConfig(level=logging.DEBUG)

logger = logging.getLogger(__name__)

c_handler = logging.StreamHandler()
c_handler.setLevel(logging.DEBUG)

c_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
c_handler.setFormatter(c_format)

logger.addHandler(c_handler)

我已将级别设置为调试,但只显示警告(及以上)

from ..logger import logger
...
logger.debug('this is a debug log message')
logger.warning('too hot to handle')
...

my_module.logger:太热而无法处理

如果我取消注释该行

logging.basicConfig(level=logging.DEBUG)

然后我得到了 DEBUG 级别,但是消息的两个副本

my_module.logger - 调试 - 这是调试日志消息

DEBUG:my_module.logger:这是一条调试日志消息

my_module.logger - 警告 - 太热而无法处理

警告:my_module.logger:太热而无法处理

我没有在包中的任何其他位置导入日志记录

我应该如何配置记录器?

4

2 回答 2

1

TL;DR 使用logger.setLevel(logging.DEBUG)


根据Python 文档,处理程序处理级别等于或高于处理程序设置为 (via .setLevel()) 的消息。

但也要注意,强调我的:

创建记录器时,级别设置为NOTSET(当记录器是根记录器时会处理所有消息,或者当记录器是非根记录器时会委托给父级)。请注意,根记录器是使用 level 创建的WARNING

因此,如果没有logging.basicConfig,则程序启动时没有“根记录器”,您首先getLogger()会创建一个具有默认级别 WARNING 的存根根记录器,并且您的记录器具有级别 NOTSET(回退到根记录器的级别)。结果,您的logger.debug消息在处理之前就被丢弃了。

使用logging.basicConfig,您可以显式创建具有给定级别的根记录器具有默认 Formatter的 StreamHandler。您的 newgetLogger()附加到根记录器,并且任何日志记录都传播到根记录器 - 因此使用不同的格式化程序(确实是默认的)打印两次。

第一次调用创建的存根根记录器getLogger()没有附加任何处理程序,因此不会打印出任何传播的记录。

如果您想完全控制您的日志记录工具,最好给您的记录器一个明确的级别basicConfig,而不是依赖于创建一个您可能不想要的根记录器:

logger.setLevel(logging.DEBUG)
于 2021-10-13T15:11:55.913 回答
0

再次阅读文档后,我意识到传播是我需要用来关闭祖先日志输出的属性。所以我的记录器变成了

# logger.py

import logging
logging.basicConfig(level=logging.DEBUG)
logger.propagate = False

logger = logging.getLogger(__name__)

c_handler = logging.StreamHandler()
c_handler.setLevel(logging.DEBUG)

c_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
c_handler.setFormatter(c_format)

logger.addHandler(c_handler)

我只收到一条日志消息,并且使用了调试级别

于 2021-10-13T15:12:43.960 回答