3

I want to add session_id to every log message. So I can do it in every request this way.

log.info('[%s] my message', self.session_id);

or even a handler. But it requires to pass %s and session variable to log method every time when I log something. Well, to skip the dirty job I can create a filter:

class ContextFilter(logging.Filter):
  def filter(self, record):
    record.my_session = 'LOL'
    return True

I'm using django + tornado so I modify LOGGING variable in settings.py:

'filters': {
  'user_filter': {
    '()': 'my_package.ContextFilter',
   }
},

'formatters': {
'verbose': {
        'format':  '[%(asctime)s %(my_session)s] %(message)s',
    },
},

And when if I write something like that:

class A(object):

  def __init__(self):
    self.session_id = random(1024)

  def process(self):
    log.info('hello')

I would get:

[11:23 LOL] hello.

Fine, now I want to inject A.session_id to filter instead of LOL. Note that session_id is defined in scope of A every time I log something. Sure I can wrap every single logger method (trace, info, debug ...) and add there session functionality but this will break line number.

I would do something like a static variable and a static setter in ContextFilter, but unfortunately I'm using using tornado (request are run in the same thread), which means I can't event use thread local context. Is filter the only workaround to get a custom variable for log entry?

2 Answers 2

2

Just found the answer. I should use LoggingAdapter instead of Filter.

class A(object):

  def __init__(self):
    self.logger = logging.LoggerAdapter(log, {'session_id': random(1024)})

  def process(self):
    self.logger.info('hello')
Sign up to request clarification or add additional context in comments.

Comments

1

I actually used the Context Filter and it worked well for me. Here's a file I import (filters.py) which contains my Context filter:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.