divinedragon
divinedragon

Reputation: 5356

Fixed Length Formatting for Combination of Fields in Python logging modules

I am using the Python logging module in my application. Here is my current format.

LOGGER_FORMAT = '%(asctime)s %(levelname)-5s [%(threadName)-10s] %(name)s.%(module)s.%(funcName)s : %(message)s'
logging.basicConfig(level=logging.INFO, format=LOGGER_FORMAT)

And a sample output:

2018-03-14 11:35:27,257 INFO  [Thread-2  ] my_app.util.get_login_info : Log line 1
2018-03-14 11:35:27,257 INFO  [Thread-2  ] my_app.cache.call : Log line 2
2018-03-14 11:35:27,257 INFO  [Thread-2  ] my_app.web.parse_response : Log line 3

What I am looking for is that I get the message displayed from the fixed position instead of varying start points.

I am able to configure the fixed length for each individual attribute, but I wanted to configure a fixed length for the entire name.module.funcName part, so that my output is like below:

2018-03-14 11:35:27,257 INFO  [Thread-2  ] my_app.util.get_login_info : Log line 1
2018-03-14 11:35:27,257 INFO  [Thread-2  ] my_app.cache.call          : Log line 2
2018-03-14 11:35:27,257 INFO  [Thread-2  ] my_app.web.parse_response  : Log line 3

Is it possible, and how can I configure this?

Upvotes: 3

Views: 1687

Answers (1)

Vinay Sajip
Vinay Sajip

Reputation: 99405

Your best bet would be to use a logging.Filter such as:

class MyFilter(logging.Filter):
    def filter(self, record):
        record.expandedFuncName = '%s.%s.%s' % (record.name, record.module, record.funcName)
        return True

and then use a format string something like

%(asctime)s %(levelname)-5s [%(threadName)-10s] %(expandedFuncName)-20.20s : %(message)s

You'd need to ensure that an instance of this filter was applied to every handler which uses a formatter with expandedFuncName in the format string. You can't do this with basicConfig, so I'd recommend using the dictConfig logging configuration API instead.

Note that the logger name will generally include the module name if you use the convention logger = logging.getLogger(__name__) as recommended in the logging documentation, though this won't apply exactly in the case of the __main__ module.

Upvotes: 2

Related Questions