Explain Codes LogoExplain Codes Logo

How can I color Python logging output?

python
logging
colorama
colorlog
Alex KataevbyAlex Kataev·Sep 18, 2024
TLDR

Add some color to your Python logging output by creating a custom Formatter subclass, using ANSI escape codes to change text colors:

import logging class ColoredFormatter(logging.Formatter): # You've heard of RGB, now get ready for CYWREM (Cyan, Yellow, White, Red, and Magenta) COLORS = {'DEBUG': '\033[94m', 'INFO': '\033[92m', 'WARNING': '\033[93m', 'ERROR': '\033[91m', 'CRITICAL': '\033[95m'} def format(self, record): # Spice up those log messages with a rainbow of colors log_fmt = f"{self.COLORS.get(record.levelname, '')}%(message)s\033[0m" formatter = logging.Formatter(log_fmt) return formatter.format(record) logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:', handlers=[logging.StreamHandler()]) logging.getLogger().handlers[0].setFormatter(ColoredFormatter()) logging.info("Info message - Easy peasy lemon squeezy") logging.warning("Warning message - Houston, we have a situation") logging.error("Error message - It's not a bug, it's a feature")

The code directly integrates color information into the logging output so it's easier to distinguish between different logging levels.

Make it work everywhere: Cross-platform compatibility

Beat Windows at its own game

While ANSI escape codes add a bit of spice to your console output, they don't always get along with Windows terminals right off the bat. To make sure everyone can join the color party, use the colorama module:

from colorama import init, Fore, Back, Style init() # Replace COLORS with colorama attributes, Windows won't know what hit it class ColoredFormatter(logging.Formatter): COLORS = { 'DEBUG': Fore.CYAN, 'INFO': Fore.GREEN, 'WARNING': Fore.YELLOW, 'ERROR': Fore.RED, 'CRITICAL': Fore.MAGENTA } # ... rest of the class remains same # Now, the formatter will work on both Windows and *NIX terminals. Good job, Colorama!

Don't forget to kick-start colorama.init() at the beginning of your script to set up ANSI escape code emulation on Windows.

Outsource the work: Plug-and-play solutions

When in doubt, colorlog it out

If you want a ready-to-use solution that offers customization options, roll out the red carpet for colorlog:

  1. Install colorlog:

    pip install colorlog
    
  2. Set up a ColoredFormatter with colorlog:

    from colorlog import ColoredFormatter # Define your custom format with color attributes LOG_FORMAT = "%(log_color)s%(levelname)s:%(reset)s %(message)s" # Set up the formatter with colorlog's ColoredFormatter formatter = ColoredFormatter(LOG_FORMAT) # ...rest of your logging setup

colorlog takes on the heavy lifting of managing color mapping and gracefully shifts gears to non-colored output for color-blind terminals.

Show your true colors: Customize log levels

Light up each log level with unique colors. Use logging.addLevelName() to color-code your logs:

# Because DEBUG and ERROR deserve their spotlight logging.addLevelName(logging.DEBUG, "\033[94m%s" % logging.getLevelName(logging.DEBUG)) logging.addLevelName(logging.ERROR, "\033[91m%s" % logging.getLevelName(logging.ERROR)) # Reset to default after lighting up your logs RESET_SEQ = "\033[0m" logging.debug("This is a debug message" + RESET_SEQ)

Pull out the big guns: Advanced logging features

Custom logger class for the win

If you're working on something where multipurpose logging is essential, it's time to create a custom logger class. Setting up multiple handlers with diverse formats becomes a cakewalk:

class MyLogger(logging.Logger): # ... setup your handlers here # Somewhere in your code logger = MyLogger('my_logger')

Use actively-maintained libraries

Make it a point to choose libraries that are maintained regularly for continual compatibility and updates. Libraries like colorlog and Rich offer not just color logging but also varied formatting options.

Structure your logs

When crafting your log format, include essentials like timestamps, file names, function names for a convenient bird's eye view of your application's workings:

LOG_FORMAT = "%(asctime)s — %(name)s — %(levelname)s — %(funcName)s:%(lineno)d — %(message)s"

Preconfigured formats give you a ton of valuable data without bombarding you with irrelevant details.

Expand your arsenal: Explore alternative tools

Sometimes, third-party libraries can offer additional functionalities on top of Python's logging module. The Rich library, for example, offers table rendering, progress bars, and markdown support, all of which can seriously level up your debugging and monitoring game.

To use Rich for logging:

  1. Install Rich:

    pip install rich
    
  2. Set up Rich logging:

    from rich.logging import RichHandler logging.basicConfig( level='INFO', format="%(message)s", datefmt="[%X]", handlers=[RichHandler()] ) logger = logging.getLogger("rich")

Using Rich can give your logs a sophisticated touch with minimal configuration.