最近工作中有个需求就是个logger日志的输出都要打印消息中的一个uuid,便于全流程追踪。
但是,这个报文会再新创建的线程中流转并处理,意识不知该如何使用简单的方式处理,总不能每次打印日志的时候都加上这个uuid吧。
还好在看ncclient源码的时候发现了LoggerAdapter。之前的问题自然迎刃而解啦,原来还可以这样玩儿!
talk is cheap,show me code.
from logging import LoggerAdapter
import logging
logger = logging.getLogger(__name__)
class SesssionLoggerAdapter(LoggerAdapter):
def process(self, msg, kwargs):
if 'session' not in self.extra or self.extra['session'] is None:
return msg, kwargs
session = self.extra['session']
if hasattr(session, 'request_id'):
msg += ', request_id({})'.format(session.request_id)
if 'extra' not in kwargs:
kwargs["extra"] = self.extra
else:
kwargs['extra'].update(self.extra)
return super().process(msg, kwargs)
class Session():
def __init__(self):
super().__init__()
@property
def request_id(self):
return self._request_id
@request_id.setter
def request_id(self, request_id):
self._request_id = request_id
session = Session()
logger.warning('abc')
logger = SesssionLoggerAdapter(logger, {'session': session})
session.request_id = '0'
logger.warning('hello world')
session.request_id = '1'
logger.warning('hello world')
关键点
- 继承LoggerAdapter,并重写process方法,将需要添加的内容从self.extra中读取出来,self.extra中最好存储一个对象,这样方便打印各种你需要打印的数据。
- 创建新的适配器logger,将对象以key:value的形式存储。
- 每次进需要在消息到达时,修改uuid的值即可。(此处的uuid就是代码中的request_id)
python官网
之前也学习了官网的文档,但是并没有掌握精髓,还是理解力不够。其实官网已经说的很清楚了,关于LoggerAdapter的介绍:
https://docs.python.org/zh-cn...
- LoggerAdapter的重要功能就是实现输出上下文信息。
下属代码时LoggerAdapter的一段实现:
def debug(self, msg, *args, **kwargs):
"""
Delegate a debug call to the underlying logger, after adding
contextual information from this adapter instance.
"""
msg, kwargs = self.process(msg, kwargs)
self.logger.debug(msg, *args, **kwargs)
通过process整理之后再通过logger进行打印
总结
- 阅读官方文档一定要仔细,对于不甚理解的东西多读多理解几遍,不要盲目跳过。
- talk is cheap, show me cheap.
- 专注Focus
- Read and write English word is important.
初学python,请各位大神多多指教。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。