In built-in python's logging module you create a logger and log messages:
import logging
log = logging.getLogger('mylogger')
log.info('starting!')
You can also pass extras to the log message that will be used later by the formatter:
user = 'john doe'
log.info('starting!', extra={'user': 'john doe'})
However it's quite tedious to do it explicitly with every message. Is it possible to set extras for the whole logger, so they would be passed with every log?
Something like:
log = logging.getLogger('mylogger')
log.extras = {'user': 'john doe'}
log.info('starting!')
Currently the only way it seems is to monkey patch log() method:
def patch_default_extras(logger, extras):
original_log = logger.log
def log_with_extras(level, msg, *args, **kwargs):
kwargs['extra'] = {**extras, **kwargs.get('extra', {})}
return original_log(level, msg, *args, **kwargs)
logger.log = log_with_extras
mylog = logging.getLogger('mylogger')
patch_default_extras(mylog, {'user': 'john doe'})
mylog = logging.getLogger('mylogger')
mylog.log(logging.ERROR, 'hello')
Which is rather ugly, but unless I'm missing something ‒ it's the only way?
The builtin way to do this is using a logging adapter. A filter would also work but for your described use-case adapters are perfect.
import logging
logging.basicConfig(level=logging.DEBUG, format='user: %(user)s - message: %(msg)s')
logger = logging.getLogger()
logger_with_user = logging.LoggerAdapter(logger, {'user': 'jane doe'})
logger_with_user.info('test') # user: jane doe - message: test
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With