John
John

Reputation: 43

Padding multiple fields together in python logger

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

Upvotes: 4

Views: 1352

Answers (2)

nikhilweee
nikhilweee

Reputation: 4539

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'

Upvotes: 0

drifting
drifting

Reputation: 24

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)

Upvotes: 0

Related Questions