logging.getLogger与logger的父子关系

2020年5月24日 / 141次阅读 / Last Modified 2020年5月24日
logging模块

我们用logging.getLogger创建logger,通过logger的名字,我们可以实现不同logger的层次关系,或父子关系。

def getLogger(name=None):
    """
    Return a logger with the specified name, creating it if necessary.

    If no name is specified, return the root logger.
    """
    if name:
        return Logger.manager.getLogger(name)
    else:
        return root

getLogger这个函数如果不带参数,返回的就是默认的root logger.

Logging is performed by calling methods on instances of the Logger class (hereafter called loggers). Each instance has a name, and they are conceptually arranged in a namespace hierarchy using dots (periods) as separators. For example, a logger named ‘scan’ is the parent of loggers ‘scan.text’, ‘scan.html’ and ‘scan.pdf’. Logger names can be anything you want, and indicate the area of an application in which a logged message originates.

def getLogger(self, name):
        """
        Get a logger with the specified name (channel name), creating it
        if it doesn't yet exist. This name is a dot-separated hierarchical
        name, such as "a", "a.b", "a.b.c" or similar.

        If a PlaceHolder existed for the specified name [i.e. the logger
        didn't exist but a child of it did], replace it with the created
        logger and fix up the parent/child references which pointed to the
        placeholder to now point to the logger.
        """
        rv = None
        if not isinstance(name, str):
            raise TypeError('A logger name must be a string')
        _acquireLock()
        try:
            if name in self.loggerDict:
                rv = self.loggerDict[name]
                if isinstance(rv, PlaceHolder):
                    ph = rv
                    rv = (self.loggerClass or _loggerClass)(name)
                    rv.manager = self
                    self.loggerDict[name] = rv
                    self._fixupChildren(ph, rv)
                    self._fixupParents(rv)
            else:
                rv = (self.loggerClass or _loggerClass)(name)
                rv.manager = self
                self.loggerDict[name] = rv
                self._fixupParents(rv)
        finally:
            _releaseLock()
        return rv

层次化的实现,就是通过在名称上加点(.)。

>>> log_1 = logging.getLogger('1')
>>> log_12 = logging.getLogger('1.2')
>>> log_12.parent
<Logger 1 (WARNING)>
>>> log_1.parent
<RootLogger root (WARNING)>

层次化的logger有个特性,子logger的日志默认要传递给父节点处理,会一直传递下去直到root。默认logger.propagate=True,这个开始用来控制传递。

关于日志传递,我看网上有很多人都发现这个特性很容易导致重复记录。我想说另一个细节,传递的时候,是直接传递给父logger的handler,而handler的默认level是NOTSET。

-- EOF --

本文链接:https://www.pynote.net/archives/1995

留言区

电子邮件地址不会被公开。 必填项已用*标注


前一篇:
后一篇:

More


©Copyright 麦新杰 Since 2019 Python笔记

go to top