使用额外的字典字段自定义Python记录器会产生带有KeyError的外部模块的回溯

问题描述

对于我的模块,我定义了一个自定义类记录器:

class MyCustomLogger(Logger):
    def _log(self,level,msg,args,exc_info=None,extra=None):
        if not extra: # try intercepting extra not being set
            extra = {"class_name": "External Module"}
        super(MyCustomLogger,self)._log(level,exc_info,extra)

然后我在MyClassExample类中使用它:

from logging import getLogger,LoggerAdapter,setLoggerClass

from mymodule.loggerconfig import MyCustomLogger

class MyClassExample(object):
    def __init__(self):
        ...
        setLoggerClass(MyCustomLogger)
        loggingName = "%s-%s-%s" % (self.__class__.__name__,self._property1,self._property2)
        self.logger = getLogger()
        self.logger = LoggerAdapter(self.logger,{'class_name': loggingName})

然后在驱动程序中,我会这样做:

$ cat driver.py
#!/usr/bin/python3 -tt -u

def setupLogging(name,scriptName):
    basicConfig(format="%(asctime)s: %(levelname)-8s {0}[%(process)d] %(class_name)s: %(message)s".format(scriptName),level=INFO)
    logger = getLogger()
    loggingHandler = SysLogHandler()
    logger.addHandler(loggingHandler)
    logger = LoggerAdapter(logger,extra)

if __name__ == "__main__":
    scriptName = path.splitext(path.basename(argv[0]))[0]
    logger = setupLogging(__name__,scriptName)

    logger.info("%s version %s (library distribution version %s)" % (scriptName,__version__,packageVersion()))

    m = MyClassExample()
    m.methodA()

如果我想在MyClassExample内记录自己的消息,这非常有用。

但是,我随import引入的所有其他模块也希望记录一些消息,并使用KeyError进行回溯,因为它们显然没有extra class_name信息:

--- Logging error ---
Traceback (most recent call last):
File "/path/to/python/lib/python3.8/logging/__init__.py",line 436,in format
    return self._format(record)
File "/path/to/python/lib/python3.8/logging/__init__.py",line 432,in _format
    return self._fmt % record.__dict__
KeyError: 'class_name'

During handling of the above exception,another exception occurred:

Traceback (most recent call last):
File "/path/to/python/lib/python3.8/logging/__init__.py",line 1081,in emit
    msg = self.format(record)
File "/path/to/python/lib/python3.8/logging/__init__.py",line 925,in format
    return fmt.format(record)
File "/path/to/python/lib/python3.8/logging/__init__.py",line 667,in format
    s = self.formatMessage(record)
File "/path/to/python/lib/python3.8/logging/__init__.py",line 636,in formatMessage
    return self._style.format(record)
File "/path/to/python/lib/python3.8/logging/__init__.py",line 438,in format
    raise ValueError('Formatting field not found in record: %s' % e)
ValueError: Formatting field not found in record: 'class_name'

那么我如何满足其他模块的日志记录格式,同时又为模块中的类保留自己的自定义格式?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)