微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决使用额外的字典字段自定义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 举报,一经查实,本站将立刻删除。