How do I add custom field to Python log format string?

logging, python, python-logging

Solution

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

Problem

My current format string is: ``` formatter = logging.Formatter('%(asctime)s : %(message)s') ``` and I want to add a new field called `app_name` which will have a different value in each script that contains this formatter. ``` import logging formatter = logging.Formatter('%(asctime)s %(app_name)s : %(message)s') syslog.setFormatter(formatter) logger.addHandler(syslog) ``` But I'm not sure how to pass that `app_name` value to the logger to interpolate into the format string. I can obviously get it to appear in the log message by passing it each time but this is messy. I've tried: ``` logging.info('Log message', app_name='myapp') logging.info('Log message', {'app_name', 'myapp'}) logging.info('Log message', 'myapp') ``` but none work.

Original source

Related problems