Reputation: 9699
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?
Upvotes: 2
Views: 4482
Reputation: 839
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
Upvotes: 1
Reputation: 9699
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')
Upvotes: 2