Python logging.Formatter(): is there any way to fix the width of a field and justify it left/right?

16.7k views Asked by At

Here's a sample of log records from the logging tutorial:

2005-03-19 15:38:55,977 - simpleExample - DEBUG - debug message
2005-03-19 15:38:55,979 - simpleExample - INFO - info message
2005-03-19 15:38:56,054 - simpleExample - WARNING - warn message
2005-03-19 15:38:56,055 - simpleExample - ERROR - error message
2005-03-19 15:38:56,130 - simpleExample - CRITICAL - critical message

This trailing jaggedness annoys me to no end.

I really want to be able to format like this:

2005-03-19 15:38:55,977 - simpleExample -    DEBUG - debug message
2005-03-19 15:38:55,979 - simpleExample -     INFO - info message
2005-03-19 15:38:56,054 - simpleExample -  WARNING - warn message
2005-03-19 15:38:56,055 - simpleExample -    ERROR - error message
2005-03-19 15:38:56,130 - simpleExample - CRITICAL - critical message

I've attempted the following for my logger, which doesn't work (abbreviated code):

fmt = "{0:>8}"
formatter = logging.Formatter("%(asctime)s %(filename)s: " + fmt.format("%(levelname)s") + " %(message)s", "%Y/%m/%d %H:%M:%S")

This executes fine and prints the level name as always, but it doesn't implement the width format.

Ex.

logger.debug("testing debug message")
logger.info("some random info")
logger.critical("oh crap!")

Actual result:

2013/12/16 13:43:10 logtester: DEBUG testing debug message
2013/12/16 13:43:10 logtester: INFO some random info
2013/12/16 13:43:10 logtester: CRITICAL oh crap!

Desired result:

2013/12/16 13:43:10 logtester:    DEBUG testing debug message
2013/12/16 13:43:10 logtester:     INFO some random info
2013/12/16 13:43:10 logtester: CRITICAL oh crap!

Any hints to implement a fixed width of a field in a logging.Formatter()?

Using Python 2.6.9.

EDIT: second attempt using another method:

formatter = logging.Formatter("%(asctime)s %(filename)s: " + "%(foo)5s" % {"foo" : "(%(levelname)s)"} + " %(message)s", "%Y/%m/%d %H:%M:%S")

Still results in:

2013/12/16 13:43:10 logtester: DEBUG testing debug message
2013/12/16 13:43:10 logtester: INFO some random info
2013/12/16 13:43:10 logtester: CRITICAL oh crap!

Maybe I'm just doing something boneheaded.

2

There are 2 answers

2
Amber On BEST ANSWER

Field width can be specified by adding a number in front of the type specifier:

>>> "%(foo)8s" % {'foo': 'bar'}
'     bar'

You can use this in your format string passed to the formatter. For your example, that'd be:

"%(asctime)s %(filename)s: %(levelname)8s %(message)s"
1
Manuel Fedele On

Logging (as of 3.2) provides improved support for bracket string format styles. For example, you can now use this kind of formatting:

fomatter = logging.Formatter('{asctime} {name} {levelname:^8s} {message}', style='{')

Which produces center aligned log level. I don't think this is possibile with % formatted strings.

2021-10-19 14:27:05,799 __main__  DEBUG   Debug message
2021-10-19 14:27:05,800 __main__   INFO   Info message
2021-10-19 14:27:05,800 __main__ WARNING  Warning message
2021-10-19 14:27:05,801 __main__  ERROR   Error message

and

'{asctime} {name} {levelname:<8s} {message}' to align right

2021-10-19 14:26:45,408 __main__    DEBUG Debug message
2021-10-19 14:26:45,409 __main__     INFO Info message
2021-10-19 14:26:45,410 __main__  WARNING Warning message
2021-10-19 14:26:45,410 __main__    ERROR Error message

or

'{asctime} {name} {levelname:>8s} {message}' to align left

2021-10-19 14:26:25,761 __main__ DEBUG    Debug message
2021-10-19 14:26:25,761 __main__ INFO     Info message
2021-10-19 14:26:25,762 __main__ WARNING  Warning message
2021-10-19 14:26:25,762 __main__ ERROR    Error message