4

我知道根记录器具有lastResort打印到控制台的处理程序,如果未配置根记录器处理程序logging.basicConfig并且用户使用logging.info/debug/warning/error/critical("some msg") Orlogger = logging.gerLogger()后跟logger.info/debug/warning/error/critical("some msg")

但是对于使用创建的子记录器logger = logging.getLogger("someName"),当我们编写logger.info/debug/warning/error/critical("some msg"),并且没有配置处理程序时propagate = true,子记录器是否有任何默认处理程序?还是回退到祖先的处理程序,然后到根记录器的处理程序,如果祖先/根记录器没有处理程序,然后到根记录器lastResort处理程序?

如果将propagate 设置为false,那么是否会为子记录器分配一些默认处理程序?

4

1 回答 1

3

简短回答:logging.lastResort

长答案:

根据文档,如果没有提供日志配置,那么:

该事件使用存储在 logging.lastResort 中的“最后的处理程序”输出。这个内部处理程序不与任何记录器相关联,并且像 StreamHandler 一样将事件描述消息写入 sys.stderr 的当前值(因此尊重任何可能有效的重定向)。没有对消息进行格式化 - 只打印裸事件描述消息。处理程序的级别设置为警告,因此将输出此严重性和更高严重性的所有事件。

还根据日志记录源代码

class Logger(Filterer):
    # ...
    def callHandlers(self, record):
        # ...
        # found is the number of handlers
        if (found == 0):
            if lastResort:
                if record.levelno >= lastResort.level:
                    lastResort.handle(record)

因此,如果没有处理程序,它将调用lastResort,无论它是根记录器还是子记录器。lastResort实际上是_StderrHandler(WARNING),这是:

class _StderrHandler(StreamHandler):
    """
    This class is like a StreamHandler using sys.stderr, but always uses
    whatever sys.stderr is currently set to rather than the value of
    sys.stderr at handler construction time.
    """
    def __init__(self, level=NOTSET):
        """
        Initialize the handler.
        """
        Handler.__init__(self, level)

    @property
    def stream(self):
        return sys.stderr

所以你可以看到它实际上是一个带有 WARNING 级别的 StreamHandler

于 2019-12-19T05:38:13.103 回答