Package rainbowlog

Rainbow Log

Format your python logs with colours based on the log levels.

Installation

You can instll the package with pip.

$ pip install rainbowlog
$ conda install rainbowlog -c abrahammurciano

Usage

Here's a basic example of a script that logs colorfully to the console, but regularly to a file.

import logging
import rainbowlog

logger = logging.getLogger(__name__)

# This one will write to the console
stream_handler = logging.StreamHandler()

# This one will write to a file
file_handler = logging.FileHandler("output.log")

# Here we decide how we want the logs to look like
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")

# We want the stream handler to be colorful
stream_handler.setFormatter(rainbowlog.Formatter(formatter))

# We don't want the file handler to be colorful
file_handler.setFormatter(formatter)

# Finally we add the handlers to the logger
logger.addHandler(stream_handler)
logger.addHandler(file_handler)

if __name__ == "__main__":
    logger.debug("This is a debug message")
    logger.info("This is an info message")
    logger.warning("This is a warning message")
    logger.error("This is an error message")
    logger.critical("This is a critical message")

If you want to change the format of the logs for each log level, you can use any callable that takes a string and returns the same string with ANSI codes surrounding it. There are many libraries you can use to provide such callables.

import logging
from rainbowlog import Formatter

# Here are some libraries you can use to get a style callable without dealing with ANSI codes
from constyle import Style, Attributes as Attrs
import termcolor
from functools import partial


formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
color_formatter = Formatter(
    formatter,
    log_styles={
        logging.DEBUG: Style(Attrs.BLUE, Attrs.FAINT), # An example using constyle
        logging.INFO: lambda s: f"\033[32m{s}\033[0m", # An example using lambdas
        logging.WARNING: termcolor.red, # An example using termcolor's predifined functions
        logging.ERROR: partial(termcolor.colored, color="red", on_color="on_white", attrs=["bold"]), # An example using functools.partial
        logging.CRITICAL: Attrs.RED + Attrs.ON_YELLOW + Attrs.BOLD + Attrs.UNDERLINE, # An example using constyle's added attributes
    }
    exception_style=lambda s: f"{Attrs.RED + Attrs.ON_WHITE + Attrs.BOLD}{s}{Attrs.RESET}" # An example using lambdas and constyle,
    stack_style=Attrs.RED, # An example using a single constyle attribute
)

Classes

class Formatter (inner_formatter: logging.Formatter = <logging.Formatter object>, log_styles: Mapping[int, Callable[[str], str]] = {10: FAINT, 20: GREEN, 30: YELLOW, 40: RED, 50: Style(31, 1, 4)}, exception_style: Optional[Callable[[str], str]] = None, stack_style: Optional[Callable[[str], str]] = None)

This log formatter wraps a given formatter and adds color to the output.

If you want to use different colors from the default ones, you can pass a mapping to the log_styles argument in the constructor. This mapping should be from log levels (ints) to style callable.

A style callable is a one which takes a string and returns a string. It should return the given string with the desired ANSI codes surrounding it. For example [constyle.Style](https://abrahammurciano.github.io/python-constyle/constyle/#constyle.Style) and ansicolors.red, ansicolors.green, etc. objects are good candidates.

You can also create your own easily by using functools.partial or lambdas with any other library you want, or using functions which wrap a string in ANSI escape codes directly.

Args

inner_formatter
The formatter to use for the log messages. Defaults to a formatter that shows just the log messages.
log_styles
A mapping from log levels to a style callable. Defaults to sensible colours.
exception_style
The style callable for exceptions. Defaults to log_styles[logging.CRITICAL].
stack_style
The style callable for stack traces. Defaults to log_styles[logging.ERROR].

Ancestors

  • logging.Formatter

Methods

def format(self, record: logging.LogRecord) ‑> str

Format the specified record as text.

The record's attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message.

def formatException(self, exc_info)

Format and return the specified exception information as a string.

This default implementation just uses traceback.print_exception()

def formatStack(self, stack_info)

This method is provided as an extension point for specialized formatting of stack information.

The input data is a string as returned from a call to :func:traceback.print_stack, but with the last trailing newline removed.

The base implementation just returns the value passed in.