Home Ask Login Register

Developers Planet

Your answer is one click away!

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


Quote of the day: live life