When using the logging
module in python, displaying the logging level makes them all different lengths. With using a formatting string of "[%(levelname)s] - %(message)s"
, the log file looks like this:
[DEBUG] - Message
[INFO] - Message
[WARNING] - Message
[ERROR] - Message
[CRITICAL] - Message
However, I would really like it if the log levels took up the same amount of space. Is there a way to make the output look similar to this:
[ DBUG ] - Message
[ INFO ] - Message
[ WARN ] - Message
[ EROR ] - Message
[CRITICAL] - Message
Whether that entails shortening the level names, or just adding padding to the sides of the names doesn't really matter to me. Just some way of getting everything to line up after the level name is what I'm after.
CodePudding user response:
If you know the longest log level name in advance, for example, if you are only going to use the standard log levels, a simple solution might be to set the formatter, as in the first code block below (output same as flexible solution):
# Set logging format and lowest logging level
logging.basicConfig(format='[{levelname:^8s}] - {message:s}',
style='{',
level=logging.DEBUG)
for i,nm in logging._levelToName.items():
logging.log(i, f"This is a {nm.lower().strip()} level message")
A flexible solution, where the names of the logging levels
are not known in advance, is to rename the numeric log
levels of the logging
module. This solution is
demonstrated in the code below.
The code sets a basic formatter to replicate the requested output messages, and sets the logging level to the lowest level.
After determining the longest logging level name, it sets all logging level names to their original names, centered, with extra padding.
# Set logging format and lowest logging level
logging.basicConfig(format='[%(levelname)s] - %(message)s',
level=logging.DEBUG)
# Determine longest loggging name
longest = max(logging._levelToName.items(), key=lambda x: len(x[1]))
maxLen = len(longest[1].strip())
# Reformat logging level names
for i,nm in logging._levelToName.items():
# See https://stackoverflow.com/a/69630856/5660315
logging.addLevelName(i, "{0:^{width}}".format(nm, width=maxLen))
logging.log(i, f"This is a {nm.lower().strip()} level message")
Output:
[CRITICAL] - This is a critical level message
[ ERROR ] - This is a error level message
[WARNING ] - This is a warning level message
[ INFO ] - This is a info level message
[ DEBUG ] - This is a debug level message
CodePudding user response:
As a developer who never coded python I managed to done this. It works like you wanted
def labelize(label, max_len, message):
fixed = "["
len_to_cut = len(label) - 1 if len(label) % 2 == 1 else len(label)
for i in range(int((max_len - len_to_cut) / 2)):
fixed = " "
fixed = (label[0:len_to_cut])
for i in range(int((max_len - len_to_cut) / 2)):
fixed = " "
return fixed "] " message
print(labelize("DEBUG", 10, "Message"))
print(labelize("INFO", 10, "Message"))
print(labelize("WARNING", 10, "Message"))
print(labelize("ERROR", 10, "Message"))
print(labelize("CRITICAL", 10, "Message"))
[ DEBU ] Message
[ INFO ] Message
[ WARNIN ] Message
[ ERRO ] Message
[ CRITICAL ] Message