我设置了一个自定义格式化程序,将我的数据以 JSON 格式记录到文本文件中:
class CustomJsonFormatter(jsonlogger.JsonFormatter):
def add_fields(self, log_record, record, message_dict):
super(CustomJsonFormatter, self).add_fields(log_record, record, message_dict)
log_record['timestamp'] = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%fZ')
log_record['level'] = record.levelname
log_record['location'] = record.name
我希望能够自动访问这种格式的请求对象,因为我有一个“唯一的请求标识符”,我想将其添加到我的日志中。这样我就知道哪些日志行属于哪个请求。
class CustomJsonFormatter(jsonlogger.JsonFormatter):
def add_fields(self, log_record, record, message_dict):
super(CustomJsonFormatter, self).add_fields(log_record, record, message_dict)
log_record['timestamp'] = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%fZ')
log_record['level'] = record.levelname
log_record['location'] = record.name
log_record['request_id'] = request.uuid <--- Something like this
有没有一种方法可以实现此目的,而无需手动将请求对象传递到每个日志行?
提前非常感谢
您可以使用中间件将请求附加到线程上下文,然后通过 threadlocals 在格式化程序中访问它:
class RequestMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
self.process_request(request)
response = self.get_response(request)
self.process_response(request, response)
return response
def process_request(self, request):
Thread.currentThread().request = request
def process_response(self, request, response):
if hasattr(Thread.currentThread(), 'request'):
del Thread.currentThread().request
return response
然后在你的格式化程序中:
threadlocals.request.uuid
请注意,这使用线程本地存储,因此只有当您的 Django 应用程序使用线程而不是多进程时,这才能正常工作。
或者,您可以将请求作为额外参数显式传递给记录器:
logger.info('message', extra={'request': request})
然后在格式化程序中将其作为 message_dict['request'] 访问。这也将跨进程工作。