I am currently working on some Python code that will be executed by a larger C# web project. The C# code uses NLog to create log files. I have got my Python logger logging to the same file. Also, I have it matching the output format being used by NLog almost exactly by using the following setup:
format='%(asctime)s.%(msecs)04d - %(levelname)8s - %(module)s, Line %(lineno)d - %(message)s\n',
datefmt='%Y-%m-%d %H:%M:%S'
The only issue is that the logging level names don't match. Obviously, Python doesn't have Trace
, which is fine: I have decided to just include the kinds of things that would be Trace
messages in the C# code as Debug
messages in the Python code. However, Warn
in NLog is Warning
in Python and Fatal
is Critical
.
Users of my app actually choose their logging level through the UI, and the choices presented to them use the NLog levels, so I want the log file to consistently show levels that match the options presented to the user. Also, the NLog entries right-justify the log level within a 5-character-wide space so that logging messages align vertically after the date, time, and level info. (No NLog logging level is more than 5 characters long.)
As you can see in my code above, I am right-justifying my Python log levels within an 8-character-wide space because 'critical' is 8 characters long. This means the Python logging messages will always align with each other, but never align with the NLog messages within the same log file.
So is there some way in the Python logger formatting to conditionally override the levelname? Really, all I need is something like levelname == "CRITICAL" ? "FATAL" : (levelname == "WARNING" ? "WARN" : levelname)
, but I have no idea how to work that into the format
property (or if it's even possible).
You can use logging.addLevelName
to change the name of an existing logging level:
import logging
logging.warning('foo')
logging.addLevelName(logging.WARN, 'WARN')
logging.warning('bar')
This outputs:
WARNING:root:foo
WARN:root:bar
Demo here