Python logging with ✨pretty colors🌸
Logging is useful, because all python code can use the same standard, allowing you to centrally control:
A python "module" is simply just the name for a .py file. e.g. the file
database_handler.py
is a module calleddatabase_handler
import logging
class ColorFormatter(logging.Formatter):
grey = "\x1b[90;20m"
cyan = "\x1b[96;20m"
yellow = "\x1b[33;20m"
red = "\x1b[31;20m"
bold_red = "\x1b[31;1m"
reset = "\x1b[0m"
format = "%(asctime)s,%(msecs)03d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s"
FORMATS = {
logging.DEBUG: grey + format + reset,
logging.INFO: cyan + format + reset,
logging.WARNING: yellow + format + reset,
logging.ERROR: red + format + reset,
logging.CRITICAL: bold_red + format + reset
}
def format(self, record):
log_fmt = self.FORMATS.get(record.levelno)
formatter = logging.Formatter(log_fmt)
return formatter.format(record)
logger = logging.getLogger(__name__) # Instantiate a logger to be used in this module
# Display every message Change this to INFO to see INFO and above (filter out DEBUG)
# See: https://docs.python.org/3/howto/logging.html#logging-levels
logger.root.setLevel(logging.DEBUG)
stream_handler = logging.StreamHandler() # This catches and handles log messages on the root handler
stream_handler.setFormatter(ColorFormatter())
logger.root.addHandler(stream_handler)
logger.debug("debug message")
logger.info("info message")
logger.warning("warning message")
logger.error("error message")
logger.critical("critical message")
Code snippet is modified, but based on: stackoverflow.com - How can I color Python logging output?. Used and credited as per stackoverflow.com - CC BY-SA 4.0 content license
$ python /tmp/1.py 2024-03-17 14:09:06,411,411 DEBUG [1.py:37] debug message 2024-03-17 14:09:06,411,411 INFO [1.py:38] info message 2024-03-17 14:09:06,411,411 WARNING [1.py:39] warning message 2024-03-17 14:09:06,411,411 ERROR [1.py:40] error message 2024-03-17 14:09:06,411,411 CRITICAL [1.py:41] critical message
In subsequent modules, do the following:
import logging
logger = logging.getLogger(__name__) # Set the logger name, to the name of the module
logger.debug("debug message")
logger.info("info message")
logger.warning("warning message")
logger.error("error message")
logger.critical("critical message")
Wish to change the colors? Color codes can be found here: wikipedia.org - ANSI escape codes
Okay, but why do we need to do it this way?
Because logging is hieratical, these 2 loggers will be siblings under the root logger (see following tree structure). Therefore we set a handler on the root logger which ensures all logging will hit our formatting code.
$ root ├── main └── module_a
You can set a breakpoint and inspect logger.parent
to see this structure:
>>> logger.parent
<RootLogger root (DEBUG)>
Read more: docs.python.org - Logging HOWTO