Python默认日志记录器已禁用。

12

由于某种原因,在我试图修改的 Python 应用程序中,记录器没有记录任何内容。我追踪了错误到 logging/__init__.py

def handle(self, record):
    """
    Call the handlers for the specified record.

    This method is used for unpickled records received from a socket, as
    well as those created locally. Logger-level filtering is applied.
    """
    if (not self.disabled) and self.filter(record):
        self.callHandlers(record)

我不确定为什么,但是self.disabled的值是True。在应用程序中没有任何地方设置过这个值,我也不认为任何软件包正在更改它。日志记录器像往常一样实例化:logger = logging.getLogger(__name__)。当在实际记录日志之前(在调用logger.info()之前)设置了logger.disabled = False时,日志记录器打印预期的日志文本。但如果没有设置,它将在handle()中返回而不记录任何内容。

有没有办法调试这个问题?也许可以更改Logger类,使得每当disabled被写入时调用某个函数...

2个回答

21

通常在使用配置模式时,会遇到这个问题,默认情况下disable_existing_loggersTrue,因此未包含在该模式中的所有记录器都将被禁用。

顺便提一句,Martin Pieters的答案非常好,在任何情况下都可以使用,当你卡住了的时候。


21

如果你需要追踪哪段代码可能将handler.disabled设置为True(默认为0,因此为false),你可以用属性替换该属性:

如果需要追踪 handler.disabled 被设置为 True 的代码(默认为 0,即 False),可以将该属性替换为一个属性:

import logging
import sys

@property
def disabled(self):
    try:
        return self._disabled
    except AttributeError:
        return False

@disabled.setter
def disabled(self, disabled):
    if disabled:
        frame = sys._getframe(1)
        print(
            f"{frame.f_code.co_filename}:{frame.f_lineno} "
            f"disabled the {self.name} logger"
        )
    self._disabled = disabled

logging.Logger.disabled = disabled

交互解释器的演示:

>>> import logging
>>> logging.getLogger('foo.bar').disabled = True
<stdin>:1 disabled the foo.bar logger

如果您想要查看完整的堆栈信息,请添加from traceback import print_stack,并在if disabled:块内使用print_stack(frame)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接