LogRecord没有期望的字段

red*_*ish 3 python logging

在使用“日志记录”模块的Python中,文档保证LogRecord实例将具有许多属性,这些属性在文档中明确列出。

但是,似乎并非总是如此。当我不使用日志记录模块的'basicConfig()'方法时,下面的程序显示在传递给LogHandler的'emit'方法的LogRecords中不存在属性'asctime'和'message'。

import logging

class LoggingHandler(logging.Handler):
    def __init__(self):
        logging.Handler.__init__(self)
    def emit(self, record):
        assert isinstance(record, logging.LogRecord)
        print("LoggingHandler received LogRecord: {}".format(record))

        # List of LogRecord attributes expected when reading the
        # documentation of the logging module:

        expected_attributes = \
            "args,asctime,created,exc_info,filename,funcName,levelname," \
            "levelno,lineno,module,msecs,message,msg,name,pathname," \
            "process,processName,relativeCreated,stack_info,thread,threadName"

        for ea in expected_attributes.split(","):
            if not hasattr(record, ea):
                print("UNEXPECTED: LogRecord does not have the '{}' field!".format(ea))


loggingHandler = LoggingHandler()
rootLogger = logging.getLogger()
rootLogger.addHandler(loggingHandler)

# emit an WARNING message
logging.warning("WARNING MESSAGE")
Run Code Online (Sandbox Code Playgroud)

在Python 3上运行可以得到:

$python3 test_logging.py
LoggingHandler received LogRecord: <LogRecord: root, 30, test_logging.py, 28, "WARNING MESSAGE">
UNEXPECTED: LogRecord does not have the 'asctime' field!
UNEXPECTED: LogRecord does not have the 'message' field!
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?我是否误解了文档?需要做什么来确保LogRecord实例具有承诺的'asctime'和'message'属性?

Ste*_*o M 5

Formatter设置是负责的asctimemessage因此在调用之前self.format(record),这些属性是未定义的。从format方法的文档中:

记录的属性字典用作字符串格式化操作的操作数。返回结果字符串。在格式化字典之前,需要执行几个准备步骤。使用msg%args计算记录的message属性。如果格式化字符串包含“(asctime)”,则调用formatTime()格式化事件时间。

由于您的示例代码未调用self.format(record),因此可以预料,未定义这些属性。

messageasctime设置,必须先调用self.format(record)内部emit方法。请试试

import logging

class LoggingHandler(logging.Handler):
    def emit(self, record):
        assert isinstance(record, logging.LogRecord)
        print("LoggingHandler received LogRecord: {}".format(record))

        self.format(record)

        # List of LogRecord attributes expected when reading the
        # documentation of the logging module:

        expected_attributes = \
            "args,asctime,created,exc_info,filename,funcName,levelname," \
            "levelno,lineno,module,msecs,message,msg,name,pathname," \
            "process,processName,relativeCreated,stack_info,thread,threadName"

        for ea in expected_attributes.split(","):
            if not hasattr(record, ea):
                print("UNEXPECTED: LogRecord does not have the '{}' field!".format(ea))


formatter = logging.Formatter("%(asctime)s")
loggingHandler = LoggingHandler()
loggingHandler.setFormatter(formatter)
rootLogger = logging.getLogger()
rootLogger.addHandler(loggingHandler)

# emit an WARNING message
logging.warning("WARNING MESSAGE")
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的回答,它解释了正在发生的事情。然而,我必须不同意所观察到的行为是预期的行为;属性列表根本没有提到这个先决条件。此外,引用的文档片段没有提到“asctime”属性。 (2认同)