Django日志关联Jeager信息

背景

近期我们的 Django 项目引入了 Jeager 做调用链监控,希望将调用链的 trace 信息和业务日志进行关联,以便能在出问题的业务尽快查询到对应的业务日志.

所以将 Jeagertrace_idspan_id 引入 Django 的日志是目前的改造方向.

Log过滤器

对于在日志输出中增加上下文信息, Pythonlogging 库提供了 Filters 的功能.

Filter 实例可以改变传入的 LogRecords ,比如添加附加属性后使用合适的 Formatter 输出。

这里我们实现一个 JeagerFilter, 通过 get_current_span() 方法我们拿到当前上下文的 span, 并且将 trace_idspan_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日志配置

接下来我们配置 DjangoLOGGING

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_idspan_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信息的关联就改造完成了.

Python装饰器与partial

Golang变量初始化