我可以扩展Logger类而不更改已记录的模块名称/函数名称/行号吗?

时间:2018-12-24 15:49:50

标签: python logging

我想避免编写类似logger.debug(msg, extra=self.extra)的代码。到目前为止,我已经尝试通过两种方式(扩展Logger和decorator)来做到这一点,但是都没有成功。

如果我扩展Logger类并实现如下所示的debug方法:

def debug(self, msg, *args, **kwargs):
    self._update_kwargs(**kwargs)
    super(ExtendedLogger, self).debug(msg, *args, **kwargs)

记录的模块/功能名称/行号不是ExtendedLogger.debug的调用站点,而是调用super(ExtendedLogger, self).debug(msg, *args, **kwargs);即它们始终是相同的值。如果我尝试使用装饰器实现类似的功能,则会遇到相同的问题。

我知道这是由于调用了该文件https://github.com/python/cpython/blob/2.7/Lib/logging/init.py(R.1284)中findCaller中的_log而引起的。是否有可能记录这些额外的数据,而基本上不复制粘贴Logger的实现并对其进行微调?

1 个答案:

答案 0 :(得分:2)

这似乎是LoggerAdapter存在的确切目的:

  

LoggerAdapter实例用于方便地将上下文信息传递到记录调用中。

您甚至可能不需要继承任何子类,只需直接使用LoggerAdapter

logger = logging.getLogger(__name__)
logger = logging.LoggerAdapter(logger, extra={'extra_key': 'extra_value'})

如果要动态提供额外的值,则可以轻松地将LoggerAdapter子类化并覆盖其process方法,以将额外的值添加到所有日志记录方法中。

这避免了需要覆盖所有面向级别的日志记录方法(debuginfowarning等),并且很好地避开了findCaller问题同时。