How can I color Python logging output? How can I color Python logging output? python python

How can I color Python logging output?

I already knew about the color escapes, I used them in my bash prompt a while ago. Thanks anyway.
What I wanted was to integrate it with the logging module, which I eventually did after a couple of tries and errors.
Here is what I end up with:

BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)#The background is set with 40 plus the number of the color, and the foreground with 30#These are the sequences need to get colored ouputRESET_SEQ = "\033[0m"COLOR_SEQ = "\033[1;%dm"BOLD_SEQ = "\033[1m"def formatter_message(message, use_color = True):    if use_color:        message = message.replace("$RESET", RESET_SEQ).replace("$BOLD", BOLD_SEQ)    else:        message = message.replace("$RESET", "").replace("$BOLD", "")    return messageCOLORS = {    'WARNING': YELLOW,    'INFO': WHITE,    'DEBUG': BLUE,    'CRITICAL': YELLOW,    'ERROR': RED}class ColoredFormatter(logging.Formatter):    def __init__(self, msg, use_color = True):        logging.Formatter.__init__(self, msg)        self.use_color = use_color    def format(self, record):        levelname = record.levelname        if self.use_color and levelname in COLORS:            levelname_color = COLOR_SEQ % (30 + COLORS[levelname]) + levelname + RESET_SEQ            record.levelname = levelname_color        return logging.Formatter.format(self, record)

And to use it, create your own Logger:

# Custom logger class with multiple destinationsclass ColoredLogger(logging.Logger):    FORMAT = "[$BOLD%(name)-20s$RESET][%(levelname)-18s]  %(message)s ($BOLD%(filename)s$RESET:%(lineno)d)"    COLOR_FORMAT = formatter_message(FORMAT, True)    def __init__(self, name):        logging.Logger.__init__(self, name, logging.DEBUG)                        color_formatter = ColoredFormatter(self.COLOR_FORMAT)        console = logging.StreamHandler()        console.setFormatter(color_formatter)        self.addHandler(console)        returnlogging.setLoggerClass(ColoredLogger)

Just in case anyone else needs it.

Be careful if you're using more than one logger or handler: ColoredFormatter is changing the record object, which is passed further to other handlers or propagated to other loggers. If you have configured file loggers etc. you probably don't want to have the colors in the log files. To avoid that, it's probably best to simply create a copy of record with copy.copy() before manipulating the levelname attribute, or to reset the levelname to the previous value, before returning the formatted string (credit to Michael in the comments).

Years ago I wrote a colored stream handler for my own use. Then I came across this page and found a collection of code snippets that people are copy/pasting :-(. My stream handler currently only works on UNIX (Linux, Mac OS X) but the advantage is that it's available on PyPI (and GitHub) and it's dead simple to use. It also has a Vim syntax mode :-). In the future I might extend it to work on Windows.

To install the package:

$ pip install coloredlogs

To confirm that it works:

$ coloredlogs --demo

To get started with your own code:

$ python> import coloredlogs, logging> coloredlogs.install()>"It works!")2014-07-30 21:21:26 peter-macbook root[7471] INFO It works!

The default log format shown in the above example contains the date, time, hostname, the name of the logger, the PID, the log level and the log message. This is what it looks like in practice:

Screenshot of coloredlogs output

NOTE: When using Git Bash w/ MinTTY

Git Bash on windows has some documented quirks:Winpty and Git Bash

Which for ANSI escape codes and for ncurses style character rewriting and animations, you need to prefix commands with winpty.

$ winpty coloredlogs --demo$ winpty python

2021 solution, no additional packages required, Python 3

Define a class

import loggingclass CustomFormatter(logging.Formatter):    grey = "\x1b[38;21m"    yellow = "\x1b[33;21m"    red = "\x1b[31;21m"    bold_red = "\x1b[31;1m"    reset = "\x1b[0m"    format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)"    FORMATS = {        logging.DEBUG: grey + format + reset,        logging.INFO: grey + 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)

Instantiate logger

# create logger with 'spam_application'logger = logging.getLogger("My_app")logger.setLevel(logging.DEBUG)# create console handler with a higher log levelch = logging.StreamHandler()ch.setLevel(logging.DEBUG)ch.setFormatter(CustomFormatter())logger.addHandler(ch)

And use!

logger.debug("debug message")"info message")logger.warning("warning message")logger.error("error message")logger.critical("critical message")

Resultenter image description here

The full color schemeenter image description here

For windows

This solution works on Mac OS, IDE terminals. Looks like the Windows command prompt doesn't have colors at all by default. Here are instructions on how to enable them, which I haven't try