我正在尝试编写一个logging.Logger
基本可以正常工作的自定义子类,但是在尝试使用logging.Formatter
包含自定义格式的插值值的子类时遇到问题%(filename)
,它会打印我的自定义子类所在的文件名,而不是调用日志记录函数的代码的文件名。
我找到了很多关于 Logger 子类化的教程,但是没有一个能解决它对文件名插值的影响。有没有一种无需重写大量代码的直接解决方案logging.Logger
?
定义我的自定义记录器的示例代码:
#-------------------------------------
# custom_logger.py
#-------------------------------------
import logging
import io
class CustomLogger(logging.Logger):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setLevel(logging.DEBUG)
# create the record format
formatter = logging.Formatter(fmt = "%(filename)s - %(message)s")
# create the handler
self.stream = io.StringIO()
handler = logging.StreamHandler(self.stream)
handler.setFormatter(formatter)
self.addHandler(handler)
def debug(self, msg, *args, **kwargs):
super().debug(msg, *args, **kwargs)
# do some other stuff
...
#-------------------------------------
# test.py
#-------------------------------------
from custom_logger import CustomLogger
import logging
logging.setLoggerClass(CustomLogger)
myLog = logging.getLogger("myLog")
myLog.debug("hello world")
print(myLog.stream.getvalue())
预期输出:
>>> test.py - hello world
实际产量:
>>> custom_logger.py - hello world
这个问题已经在https://stackoverflow.com/a/59492341/2138700中得到解答
解决方案是在 custom_logger 代码中调用时使用 stacklevel 关键字参数。以下是文档
super().debug
中的相关部分所以修改后的代码应该是
现在输出将是
test.py - hello world