我想在每条日志消息中添加session_id
。所以我可以通过这种方式在每个请求中做到这一点。
log.info('[%s] my message', self.session_id);
甚至是handler。但每当我记录某些内容时,它需要将%s
和会话变量传递给log方法。好吧,为了跳过肮脏的工作,我可以创建一个filter:
class ContextFilter(logging.Filter):
def filter(self, record):
record.my_session = 'LOL'
return True
我正在使用django + tornado,因此我修改了LOGGING
中的settings.py
变量:
'filters': {
'user_filter': {
'()': 'my_package.ContextFilter',
}
},
'formatters': {
'verbose': {
'format': '[%(asctime)s %(my_session)s] %(message)s',
},
},
如果我写这样的东西:
class A(object):
def __init__(self):
self.session_id = random(1024)
def process(self):
log.info('hello')
我会得到:
[11:23 LOL] hello
。
很好,现在我想注入A.session_id
来过滤而不是LOL
。请注意,session_id
在每次登录时都在A
的范围内定义。当然,我可以包装每一个记录器方法(跟踪,信息,调试...)并添加会话功能,但这将打破行号。
我会在ContextFilter
中执行类似静态变量和静态设置器的操作,但不幸的是我正在使用龙卷风(请求在同一个线程中运行),这意味着我不能使用线程本地事件上下文。过滤器是获取日志条目的自定义变量的唯一解决方法吗?
答案 0 :(得分:2)
刚刚找到answer。我应该使用LoggingAdapter而不是Filter。
class A(object):
def __init__(self):
self.logger = logging.LoggerAdapter(log, {'session_id': random(1024)})
def process(self):
self.logger.info('hello')
答案 1 :(得分:0)
我实际上使用了上下文过滤器,它对我来说效果很好。这是我导入的文件(filters.py
),其中包含我的上下文过滤器:
import logging
from flask import request
class SessionFilter(logging.Filter):
'''
This class acts as a context filter for logs. If an action is executed as part of a request, this filter
adds the session ID associated with the request to the log.
'''
def filter(self, record):
try:
record.session_id = request.headers['Cookie'].lstrip('session=')
except:
record.session_id = None
return True