Velimir M. February 2016

How to set width of combined fields in Python logging

In Python logging, is there a way to set the width of two combined fields?

I'm looking to combine filenames and line numbers to produce output similar to:

2011-10-14 13:47:51 main.py:12       DEBUG - Initializing cluster
2011-10-14 13:47:51 cluster.py:364   DEBUG - Starting cluster
2011-10-14 13:47:51 cluster.py:98    INFO  - Starting simulation
2011-10-14 13:47:51 simulation.py:79 DEBUG - Computing parameters

How would I modify the formatting string below, to achieve this?

logging.Formatter('%(asctime)s %(filename)s:%(lineno)s %(levelname)5s - %(msg)s 

UPDATE:

As @jonrsharpe points out, no out-of-the-box way to do this, so have customize the formatting.

Solution: @alecxe recommends a custom Filter, and here is a complete example:

import logging
import logging.config

class FilenameLinenoFilter(logging.Filter):
    def filter(self, record):
        record.filename_lineno = '{}:{}'.format(record.filename, record.lineno)
        return True

LOG_SETTINGS = {
    'version': 1,
    'filters': {
        'filename_lineno_filter': {
            '()': FilenameLinenoFilter,
        },
    },
    'formatters': {
        'standard': {
            'format': '%(asctime)s %(filename_lineno)-18s %(levelname)5s - %(msg)s',
        },
    },
    'handlers': {
        'default': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'filters': ['filename_lineno_filter'],
            'formatter': 'standard',
            },
    },
    'loggers': {
        '': { 
            'handlers': ['default'],
            'level': 'DEBUG',
        },
    }
}

logging.config.dictConfig(LOG_SETTINGS)
logger = logging.getLogger()
logger.debug('Debug output goes here.')
logger.info('Informational goes here.')

Answers


alecxe February 2016

You can make a combined field with the help of a custom filter:

import logging

class MyFilter(logging.Filter):
    def filter(self, record):
        record.filename_lineno = "%s:%d" % (record.filename, record.lineno)
        return True

Then, you can reference the %(filename_lineno)s placeholder in the formatting string.

Post Status

Asked in February 2016
Viewed 3,568 times
Voted 12
Answered 1 times

Search




Leave an answer