Skip to content

Module dlr.ki.logging.formatter

View Source
# SPDX-FileCopyrightText: 2024 Benedikt Franke <benedikt.franke@dlr.de>
# SPDX-FileCopyrightText: 2024 Florian Heinrich <florian.heinrich@dlr.de>
#
# SPDX-License-Identifier: Apache-2.0

from .colored_console import ColoredConsoleFormatter
from .term_escape_code import TermEscapeCodeFormatter


__all__ = ["ColoredConsoleFormatter", "TermEscapeCodeFormatter"]

Sub-modules

Classes

ColoredConsoleFormatter

class ColoredConsoleFormatter(
    *args,
    **kwargs
)

Formatter to support ANSI color codes and print colorful logs to the console.

View Source
class ColoredConsoleFormatter(Formatter):
    """
    Formatter to support ANSI color codes and print colorful logs to the console.
    """

    MAPPING: Dict[str, AnsiGraphic] = {
        "DEBUG":    ansi.fx.bold + ansi.fg.grey,
        "INFO":     ansi.fx.bold + ansi.fg.green,
        "WARNING":  ansi.fx.bold + ansi.fg.yellow,
        "ERROR":    ansi.fx.bold + ansi.fg.red,
        "CRITICAL": ansi.fx.bold + ansi.fg.black + ansi.bg.red,
    }
    """
    ANSI Code mapping for each log level.
    """

    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)

        # create a dict with all ansi functions to provide them while formating
        self.ansi_dict = {}
        for key, value in ansi.fx.__dict__.items():
            if isinstance(value, AnsiGraphic):
                self.ansi_dict[f"ansi.fx.{key}"] = value
        for key, value in ansi.fg.__dict__.items():
            if isinstance(value, AnsiGraphic):
                self.ansi_dict[f"ansi.fg.{key}"] = value
        for key, value in ansi.bg.__dict__.items():
            if isinstance(value, AnsiGraphic):
                self.ansi_dict[f"ansi.bg.{key}"] = value
        self.ansi_dict.pop("ansi.fg.bold")
        self.ansi_dict.pop("ansi.bg.bold")

    def format(self, record):
        colored_record = copy(record)
        colored_record.levelcolor = ColoredConsoleFormatter.MAPPING.get(
            colored_record.levelname,
            ColoredConsoleFormatter.MAPPING["DEBUG"]
        )
        colored_record.colorreset = ansi.fx.reset
        colored_record.clearline = erase_line() + "\r"
        colored_record.__dict__.update(self.ansi_dict)
        return super().format(colored_record)

Ancestors (in MRO)

  • logging.Formatter

Class variables

MAPPING
default_msec_format
default_time_format

Methods

converter

def converter(
    ...
)

localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,

tm_sec,tm_wday,tm_yday,tm_isdst)

Convert seconds since the Epoch to a time tuple expressing local time. When 'seconds' is not passed in, convert the current time instead.

format

def format(
    self,
    record
)

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.

View Source
    def format(self, record):
        colored_record = copy(record)
        colored_record.levelcolor = ColoredConsoleFormatter.MAPPING.get(
            colored_record.levelname,
            ColoredConsoleFormatter.MAPPING["DEBUG"]
        )
        colored_record.colorreset = ansi.fx.reset
        colored_record.clearline = erase_line() + "\r"
        colored_record.__dict__.update(self.ansi_dict)
        return super().format(colored_record)

formatException

def formatException(
    self,
    ei
)

Format and return the specified exception information as a string.

This default implementation just uses traceback.print_exception()

View Source
    def formatException(self, ei):
        """
        Format and return the specified exception information as a string.

        This default implementation just uses
        traceback.print_exception()
        """
        sio = io.StringIO()
        tb = ei[2]
        # See issues #9427, #1553375. Commented out for now.
        #if getattr(self, 'fullstack', False):
        #    traceback.print_stack(tb.tb_frame.f_back, file=sio)
        traceback.print_exception(ei[0], ei[1], tb, None, sio)
        s = sio.getvalue()
        sio.close()
        if s[-1:] == "\n":
            s = s[:-1]
        return s

formatMessage

def formatMessage(
    self,
    record
)
View Source
    def formatMessage(self, record):
        return self._style.format(record)

formatStack

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

View Source
    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.
        """
        return stack_info

formatTime

def formatTime(
    self,
    record,
    datefmt=None
)

Return the creation time of the specified LogRecord as formatted text.

This method should be called from format() by a formatter which wants to make use of a formatted time. This method can be overridden in formatters to provide for any specific requirement, but the basic behaviour is as follows: if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used. The resulting string is returned. This function uses a user-configurable function to convert the creation time to a tuple. By default, time.localtime() is used; to change this for a particular formatter instance, set the 'converter' attribute to a function with the same signature as time.localtime() or time.gmtime(). To change it for all formatters, for example if you want all logging times to be shown in GMT, set the 'converter' attribute in the Formatter class.

View Source
    def formatTime(self, record, datefmt=None):
        """
        Return the creation time of the specified LogRecord as formatted text.

        This method should be called from format() by a formatter which
        wants to make use of a formatted time. This method can be overridden
        in formatters to provide for any specific requirement, but the
        basic behaviour is as follows: if datefmt (a string) is specified,
        it is used with time.strftime() to format the creation time of the
        record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used.
        The resulting string is returned. This function uses a user-configurable
        function to convert the creation time to a tuple. By default,
        time.localtime() is used; to change this for a particular formatter
        instance, set the 'converter' attribute to a function with the same
        signature as time.localtime() or time.gmtime(). To change it for all
        formatters, for example if you want all logging times to be shown in GMT,
        set the 'converter' attribute in the Formatter class.
        """
        ct = self.converter(record.created)
        if datefmt:
            s = time.strftime(datefmt, ct)
        else:
            s = time.strftime(self.default_time_format, ct)
            if self.default_msec_format:
                s = self.default_msec_format % (s, record.msecs)
        return s

usesTime

def usesTime(
    self
)

Check if the format uses the creation time of the record.

View Source
    def usesTime(self):
        """
        Check if the format uses the creation time of the record.
        """
        return self._style.usesTime()

TermEscapeCodeFormatter

class TermEscapeCodeFormatter(
    fmt=None,
    datefmt=None,
    style='%',
    validate=True,
    *,
    defaults=None
)

A class to strip the escape codes from the message.

View Source
class TermEscapeCodeFormatter(Formatter):
    """
    A class to strip the escape codes from the message.
    """

    def formatMessage(self, record):
        """
        Format message and strip the escape codes.

        Args:
            record: message record to be formatted

        Returns:
            str: formatted message
        """
        msg = super().formatMessage(record)
        return non_ansi(msg)

Ancestors (in MRO)

  • logging.Formatter

Class variables

default_msec_format
default_time_format

Methods

converter

def converter(
    ...
)

localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,

tm_sec,tm_wday,tm_yday,tm_isdst)

Convert seconds since the Epoch to a time tuple expressing local time. When 'seconds' is not passed in, convert the current time instead.

format

def format(
    self,
    record
)

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.

View Source
    def format(self, record):
        """
        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.
        """
        record.message = record.getMessage()
        if self.usesTime():
            record.asctime = self.formatTime(record, self.datefmt)
        s = self.formatMessage(record)
        if record.exc_info:
            # Cache the traceback text to avoid converting it multiple times
            # (it's constant anyway)
            if not record.exc_text:
                record.exc_text = self.formatException(record.exc_info)
        if record.exc_text:
            if s[-1:] != "\n":
                s = s + "\n"
            s = s + record.exc_text
        if record.stack_info:
            if s[-1:] != "\n":
                s = s + "\n"
            s = s + self.formatStack(record.stack_info)
        return s

formatException

def formatException(
    self,
    ei
)

Format and return the specified exception information as a string.

This default implementation just uses traceback.print_exception()

View Source
    def formatException(self, ei):
        """
        Format and return the specified exception information as a string.

        This default implementation just uses
        traceback.print_exception()
        """
        sio = io.StringIO()
        tb = ei[2]
        # See issues #9427, #1553375. Commented out for now.
        #if getattr(self, 'fullstack', False):
        #    traceback.print_stack(tb.tb_frame.f_back, file=sio)
        traceback.print_exception(ei[0], ei[1], tb, None, sio)
        s = sio.getvalue()
        sio.close()
        if s[-1:] == "\n":
            s = s[:-1]
        return s

formatMessage

def formatMessage(
    self,
    record
)

Format message and strip the escape codes.

Parameters:

Name Type Description Default
record None message record to be formatted None

Returns:

Type Description
str formatted message
View Source
    def formatMessage(self, record):
        """
        Format message and strip the escape codes.

        Args:
            record: message record to be formatted

        Returns:
            str: formatted message
        """
        msg = super().formatMessage(record)
        return non_ansi(msg)

formatStack

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

View Source
    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.
        """
        return stack_info

formatTime

def formatTime(
    self,
    record,
    datefmt=None
)

Return the creation time of the specified LogRecord as formatted text.

This method should be called from format() by a formatter which wants to make use of a formatted time. This method can be overridden in formatters to provide for any specific requirement, but the basic behaviour is as follows: if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used. The resulting string is returned. This function uses a user-configurable function to convert the creation time to a tuple. By default, time.localtime() is used; to change this for a particular formatter instance, set the 'converter' attribute to a function with the same signature as time.localtime() or time.gmtime(). To change it for all formatters, for example if you want all logging times to be shown in GMT, set the 'converter' attribute in the Formatter class.

View Source
    def formatTime(self, record, datefmt=None):
        """
        Return the creation time of the specified LogRecord as formatted text.

        This method should be called from format() by a formatter which
        wants to make use of a formatted time. This method can be overridden
        in formatters to provide for any specific requirement, but the
        basic behaviour is as follows: if datefmt (a string) is specified,
        it is used with time.strftime() to format the creation time of the
        record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used.
        The resulting string is returned. This function uses a user-configurable
        function to convert the creation time to a tuple. By default,
        time.localtime() is used; to change this for a particular formatter
        instance, set the 'converter' attribute to a function with the same
        signature as time.localtime() or time.gmtime(). To change it for all
        formatters, for example if you want all logging times to be shown in GMT,
        set the 'converter' attribute in the Formatter class.
        """
        ct = self.converter(record.created)
        if datefmt:
            s = time.strftime(datefmt, ct)
        else:
            s = time.strftime(self.default_time_format, ct)
            if self.default_msec_format:
                s = self.default_msec_format % (s, record.msecs)
        return s

usesTime

def usesTime(
    self
)

Check if the format uses the creation time of the record.

View Source
    def usesTime(self):
        """
        Check if the format uses the creation time of the record.
        """
        return self._style.usesTime()