Shuzheng
Shuzheng

Reputation: 13840

How to make a `FileHandler` strip terminal escape sequences (colors) from a log message?

I have a single Logger with two Handlers: StreamHandler and FileHandler.

I want to log colored output to the terminal using escape sequences (see Logger usage) via the StreamHandler. However, I don't want to log such escape sequences via the FileHandler:

Log to StreamHandler: \033[39m{}\033[0m\033[91m{}\033[0m\033[39m{}\033[0m
Log to FileHandler: {}{}{}

In order words, the FileHandler should strip the terminal escape sequences.

Is there any solution besides creating two Loggers configured with a StreamHandler and FileHandler, respectively?

I really don't want to carry two separate Loggers around in the code, if it can be avoided.

Logger usage:

fmt = 'Match: {} ({}/v{}): \033[39m{}\033[0m\033[91m{}\033[0m\033[39m{}\033[0m ({}) {}'

self.logger.info(
    fmt,
    o.type.lower(),
    o.id,
    o.version,
    remove_control_chars(match.left),
    remove_control_chars(match.text),
    remove_control_chars(match.right),
    match.regex,
    suffix
)

Logger configuration:

def init(log, level, no_console):
    formatter = logging.Formatter(
        '{asctime:s} -- {levelname:<5s} -- {name:s} -- {process:d} -- {funcName:s} -- {message:s}',
        datefmt='%m/%d/%Y %I:%M:%S %p',
        style='{'
    )

    logger = logging.getLogger('watchdog')

    if getattr(logging, level.upper()) is None:
        raise common.exc.WatchdogException(f'Failed to set level for logger: {level.upper()}')

    logger.setLevel(getattr(logging, level.upper()))

    if not no_console:
        handler = logging.StreamHandler()
        handler.setFormatter(formatter)
        logger.addHandler(handler)

    try:
        handler = logging.FileHandler(log, mode='w+')
        handler.setFormatter(formatter)
        logger.addHandler(handler)
    except Exception as exc:
        raise common.exc.WatchdogException(f'Failed to initialize file handler: {log}') from exc

Upvotes: 1

Views: 285

Answers (1)

blues
blues

Reputation: 5185

It is possible to strip the extra characters in the FileHandler by adding a Filter to it but there is a much better solution. Each handler can have their own Formatter. So the ideal way would be to add a Formatter only to the StreamHandler which adds the terminal escape sequences to the log.

Upvotes: 2

Related Questions