我有一些记录器用于多个程序,每个程序都在一个"__main__"
记录器中配置了多个处理程序,另一个包创建了一个"__main__.package"
记录器,所以它使用该配置来处理它的消息.我没有控制程序的记录器,只有我的包.我的包应该使用记录器设置.我可以假设每个使用我包的程序都配置了一个.
我想从main继承格式化程序,但在将消息/格式发送到格式化程序之前修改它.一些非常类似的this问题,除了我正在与一个子元素日志(log)记录器而不是家长日志(log)直接工作.
例如:
main.py
import logging
import mypackage
logger = logging.getLogger("__main__")
logger.setLevel(logging.DEBUG)
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
stream_formatter = logging.Formatter('%(levelname)s:%(filename)s:%(lineno)d:%(message)s')
stream_handler.setFormatter(stream_formatter)
logger.addHandler(stream_handler)
def main():
a=1
logger.info("message from main")
b = mypackage.MyClass("EXTRA INSTANCE INFO")
b.mymodule(a)
c = mypackage.MyClass("EXTRA INSTANCE INFO2")
c.mymodule(a+1)
main()
我try 添加此信息是为了修改邮件,方法是添加在邮件输出之前修改邮件的筛选器:
mypackage.py
import logging
logger = logging.getLogger(f"__main__.{__name__}")
class _PackageContextFilter(logging.Filter):
def __init__(self, needed_info_from_my_package):
self.needed_info_from_my_package=needed_info_from_my_package
def filter(self, record):
record.msg = f"({self.needed_info_from_my_package}) " + record.msg
return True
class MyClass():
def __init__(self,init_cond) -> None:
self.data=[]
self.needed_info_from_my_package = [init_cond]
# I think the issue arises here because a single logger object gets multiple filters
logger.addFilter(_PackageContextFilter(self.needed_info_from_my_package))
def mymodule(self,data):
self.data.append(data)
logger.info(f"message from mymodule about {self.data}")
输出:
INFO:main.py:13:message from main
INFO:mypackage.py:24:(['EXTRA INSTANCE INFO']) message from mymodule about [1]
INFO:mypackage.py:24:(['EXTRA INSTANCE INFO2']) (['EXTRA INSTANCE INFO']) message from mymodule about [2]
我想要的输出是
INFO:main.py:13:message from main
INFO:mypackage.py:24:(['EXTRA INSTANCE INFO']) message from mymodule about [1]
INFO:mypackage.py:24:(['EXTRA INSTANCE INFO2']) message from mymodule about [2]
我认为这是重复的,因为我一直在向同一个日志(log)对象添加过滤器.我看到在logging cookbook中有一个创建上下文变量来处理某个类的两个实例的示例,但当我查找有关上下文变量是什么的文档时,它似乎与线程更相关.我不确定创建它们来解决这个问题是不是一个"好主意".
我想我可以做的另一种 Select 是将每一个输入包装到日志(log)消息中,如logging.info(self.format_message_instance(msg))
,但我认为有一个已知的最佳实践