背景
近期我们的 Django 项目引入了 Jeager 做调用链监控,希望将调用链的 trace 信息和业务日志进行关联,以便能在出问题的业务尽快查询到对应的业务日志.
所以将 Jeager 的 trace_id 和 span_id 引入 Django 的日志是目前的改造方向.
Log过滤器
对于在日志输出中增加上下文信息, Python 的 logging 库提供了 Filters 的功能.
Filter 实例可以改变传入的 LogRecords ,比如添加附加属性后使用合适的 Formatter 输出。
这里我们实现一个 JeagerFilter, 通过 get_current_span() 方法我们拿到当前上下文的 span, 并且将 trace_id 和 span_id 添加到 LogRecords 中.
最后必须返回 True .逻辑是 Filter.filter 函数返回 True 的时候,这条日志才会被输出.
from opentracing_instrumentation import get_current_span
class JeagerFilter(logging.Filter):
def filter(self, record):
span = get_current_span()
record.trace_id = span.trace_id
record.span_id = span.span_id
return True
Django日志配置
接下来我们配置 Django 的 LOGGING
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'jeager': {
'()': 'utils.tracing_utils.JeagerFilter'
}
},
'formatters': {
'simple': {
'format': '[django] trace_id=%(trace_id)x span_id=%(span_id)x %(asctime)s %(levelname)s [%(process)d:%(processName)s] %(pathname)s %(module)s %(filename)s %(funcName)s %(lineno)d "%(message)s"'
},
},
'handlers': {
'null': {
'class': 'logging.NullHandler',
'level': 'DEBUG'
},
'console': {
'class': 'logging.StreamHandler',
'filters': ['jeager'],
'level': 'DEBUG',
'formatter': 'simple'
},
},
'loggers': {
'custom': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False
},
},
'root': {
'handlers': ['null'],
'level': 'DEBUG'
},
可以看到在 filters 增加了一个自定义的 utils.tracing_utils.JeagerFilter,别名 jeager
然后在 console 这个 handler 中使用 jeager 这个 Filter 接下来使用 console 这个 handler 的日志中就会增加 trace_id 和 span_id 这两个字段了.
我们配置一下对应的 formatter 增加: trace_id=%(trace_id)x span_id=%(span_id)x
查看一下对应的输出:
[django] trace_id=2ddd108598ae190a span_id=fd08137be979e9a9 2020-01-15 13:27:19,951 INFO [400:MainProcess] ./custom/views.py views views.py list 83 "custom message"
这里Django日志和Jeager信息的关联就改造完成了.