是否可以将变量注入python logger过滤器

时间:2015-08-18 19:00:38

标签: python logging

我想在每条日志消息中添加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中执行类似静态变量和静态设置器的操作,但不幸的是我正在使用龙卷风(请求在同一个线程中运行),这意味着我不能使用线程本地事件上下文。过滤器是获取日志条目的自定义变量的唯一解决方法吗?

2 个答案:

答案 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