Search code examples
pythonloggingformattingpython-logging

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


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.


Solution

  • 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"