Python子记录器应该向根记录器报告,而不是应用自己的日志记录配置

时间:2016-04-07 16:14:51

标签: python logging

如前所述https://stackoverflow.com/a/4150322/1526342。当记录到子记录器时,它会将消息传递给其父记录,并且其父记录将消息传递给根记录器。 现在考虑以下示例

import logging
import logging.handlers
child_logger = logging.getLogger(__name__)
f = logging.Formatter(
        fmt='%(asctime)s; %(name)s; % (filename)s:%(lineno)d:%(message)s',
        datefmt="%Y-%m-%d %H:%M:%S")
handler = logging.handlers.RotatingFileHandler('/tmp/info.log',
                                               encoding='utf8',
                                               maxBytes=500000000,
                                               backupCount=5)
handler.setFormatter(f)
child_logger.setLevel(logging.INFO)
child_logger.addHandler(handler)
child_logger.info('1 + 1 is %d', 1+1)

child_logger应该报告回根记录器,而不是将输出打印到child_logger的日志文件。

我很困惑。

2 个答案:

答案 0 :(得分:2)

this logging flow chart所示,记录器将日志记录传递给自己的处理程序到父记录器对象。尝试将处理程序添加到父记录器,您将看到正在处理日志记录。

答案 1 :(得分:0)

在这种情况下,您的'child_logger'是您的根记录器。如果你这样初始化它:

logger = getLogger('root')
child_logger = getLogger('root.child')

child_loggerlogger的孩子,定义如下:

  

该名称可能是一个以句点分隔的层次结构值,例如foo.bar.baz(例如,它也可能只是普通的foo)。在分层列表中较低的记录器是列表中较高的记录器的子项。例如,给定一个名为foo的记录器,名称为foo.bar,foo.bar.baz和foo.bam的记录器都是foo的后代。记录器名称层次结构类似于Python包层次结构,如果使用推荐的构造logging.getLogger(__name__)在每个模块的基础上组织记录器,则与其相同。那是因为在模块中,__name__是Python包命名空间中的模块名称。

如果您不希望孩子传播,您可以设置logger.propagate = False

此外,如果您只希望将某些级别写入您的子记录器文件(即仅调试),但您希望更高级别仍然传播,则可以创建处理程序的子类,如我的所在:

from logging import DEBUG, INFO, WARN, ERROR, CRITICAL, handlers

class DebugRotatingFileHandler(handlers.RotatingFileHandler):
    def __init__(self, filename, mode, maxBytes, backupCount, encoding, delay):
        super(DebugRotatingFileHandler, self).__init__(
                  self, filename, mode, maxBytes, backupCount, encoding, delay)

    def emit(self, record):
        if record.levelno != DEBUG:
            return
        super(DebugRotatingFileHandler, self).emit(self, record)

(是的,我知道可以做一些改进,这是旧代码。)

例如,执行debug_logger.info("Info Message")将不会向debug_logger的指定文件打印任何内容,但是,如果将root_logger的级别设置为info或debug,则会将其打印在其文件中。我使用它进行调试日志记录,同时仍保留让记录器进行错误消息调用并将其打印到根日志的能力。