我正在使用自定义格式化程序和线程本地存储来执行此操作:
from collections import defaultdict
import logging
import threading
class ContextAwareFormatter(logging.Formatter):
"""
Makes use of get_context() to populate the record attributes.
"""
def format(self, record):
# Using defaultdict to avoid KeyErrorS when a key is not in the context.
def factory():
return ""
record.__dict__ = defaultdict(factory, record.__dict__)
for k, v in get_context().iteritems():
if not hasattr(record, k):
setattr(record, k, v)
return logging.Formatter.format(self, record)
THREADLOCAL_ATTR = "logging_context"
_threadlocal = threading.local()
def get_context():
result = getattr(_threadlocal, THREADLOCAL_ATTR, None)
if result is None:
result = {}
setattr(_threadlocal, THREADLOCAL_ATTR, result)
return result
def set_context(**context):
c = get_context()
c.clear()
c.update(**context)
return c
def update_context(**context):
c = get_context()
c.update(**context)
return c
然后在记录器配置中:
"formatters": {
"default": {
"()": "log.ContextAwareFormatter",
"format": "%(asctime)s %(levelname)s [%(request_id)s] %(message)s (%(module)s:%(lineno)d)",
},
}
在记录上下文之前填充:
update_context(request_id=request_id)
request_id
您可能希望在日志记录中可能不需要的应用程序的不同部分使用不同的格式化程序。