How do I add custom field to Python log format string?
You could use a LoggerAdapter so you don't have to pass the extra info with every logging call:
import logging
extra = {'app_name':'Super App'}
logger = logging.getLogger(__name__)
syslog = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s %(app_name)s : %(message)s')
syslog.setFormatter(formatter)
logger.setLevel(logging.INFO)
logger.addHandler(syslog)
logger = logging.LoggerAdapter(logger, extra)
logger.info('The sky is so blue')
logs (something like)
2013-07-09 17:39:33,596 Super App : The sky is so blue
Filters can also be used to add contextual information.
import logging
class AppFilter(logging.Filter):
def filter(self, record):
record.app_name = 'Super App'
return True
logger = logging.getLogger(__name__)
logger.addFilter(AppFilter())
syslog = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s %(app_name)s : %(message)s')
syslog.setFormatter(formatter)
logger.setLevel(logging.INFO)
logger.addHandler(syslog)
logger.info('The sky is so blue')
produces a similar log record.
Python3
As of Python3.2 you can now use LogRecordFactory
import logging
logging.basicConfig(format="%(custom_attribute)s - %(message)s")
old_factory = logging.getLogRecordFactory()
def record_factory(*args, **kwargs):
record = old_factory(*args, **kwargs)
record.custom_attribute = "my-attr"
return record
logging.setLogRecordFactory(record_factory)
>>> logging.info("hello")
my-attr - hello
Of course, record_factory
can be customized to be any callable and the value of custom_attribute
could be updated if you keep a reference to the factory callable.
Why is that better than using Adapters / Filters?
- You do not need to pass your logger around the application
- It actually works with 3rd party libraries that use their own logger (by just calling
logger = logging.getLogger(..)
) would now have the same log format. (this is not the case with Filters / Adapters where you need to be using the same logger object) - You can stack/chain multiple factories