Padding multiple fields together in python logger

Question:

Is there anyway to combine several logging values together in the formatter so that they can be padded as a single item?

My log formatter looks like this:

'%(asctime)s %(module)s:%(funcName)s:%(lineno)-15d %(levelname)-8s %(name)s: %(message)s'

I would like it to pad the module, funcName, and lineno fields together. Running with this formatter produces this output:

2017-09-01 21:06:29,299 app:main:48              INFO     pub: main start
2017-09-01 21:06:29,434 app:push_data:36              INFO     pub: push data

But I want it to be like:

2017-09-01 21:06:29,299 app:main:48           INFO     pub: main start
2017-09-01 21:06:29,434 app:push_data:36      INFO     pub: push data
Asked By: John

||

Answers:

I had a similar issue recently and solved it by making a custom logging.Formatter.

In your ini file, add the following line under the formatter block:

class=my_log_formatter.MyLogFormatter

Also you should remove the line that starts with format= if it exists. It will look something like this:

format=%(asctime)s %(name)-40s:%(lineno)-4s %(levelname)-8s %(message)s

Then make a new class:

import logging
class MyLogFormatter(logging.Formatter):
    def format(self, record):
        location = '%s.%s:%s' % (record.name, record.funcName, record.lineno)
        msg = '%s %-60s %-8s %s' % (self.formatTime(record), location, record.levelname, record.msg)
        record.msg = msg
        return super(MyLogFormatter, self).format(record)
Answered By: drifting

Here’s an inspiration from the logging cookbook (sec. Customizing LogRecord).

Essentially, you can set a custom attribute on every LogRecord object.

old_factory = logging.getLogRecordFactory()

def record_factory(*args, **kwargs):
    record = old_factory(*args, **kwargs)
    record.origin = f'{record.module}:{record.funcName}:{record.lineno}'
    return record

logging.setLogRecordFactory(record_factory)

You can then change the formatter to format this custom attribute.

'%(asctime)s %(origin)-15d %(levelname)-8s %(name)s: %(message)s'
Answered By: nikhilweee
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.