Skip to content
Advertisement

Prevent one of the logging handlers for specific messages

I monitor my script with the logging module of the Python Standard Library and I send the loggings to both the console with StreamHandler, and to a file with FileHandler.

I would like to have the option to disable a handler for a LogRecord independantly of its severity. For example, for a specific LogRecord I would like to have the option not to send it to the file destination or to the console (with passing a parameter).

I have found that the library has the Filter class for that reason (which is described as a finer grained way to filter blocks), but haven’t figured out how to do it.

Any ideas how to do this in a cosistent way?

Advertisement

Answer

Finally, it is quite easy. I used a function as a Handler.filer as suggested in the comments.

This is a working example:

from pathlib import Path
import logging
from logging import LogRecord


def build_handler_filters(handler: str):

    def handler_filter(record: LogRecord):
        if hasattr(record, 'block'):
            if record.block == handler:
                return False
        return True

    return handler_filter


ch = logging.StreamHandler()
ch.addFilter(build_handler_filters('console'))
fh = logging.FileHandler(Path('/tmp/test.log'))
fh.addFilter(build_handler_filters('file'))

mylogger = logging.getLogger(__name__)
mylogger.setLevel(logging.DEBUG)
mylogger.addHandler(ch)
mylogger.addHandler(fh)

When the logger is called, the message is sent to both console and output, i.e.

mylogger.info('msg').

To block for example the file the logger should be called with the extra argument like this

mylogger.info('msg only to console', extra={'block': 'file'})

Disabling console is analogous.

Advertisement