Ignore specific logging line temporarily

I have a method called import_customers() which loads csv-like data.

This methods logs to log-level INFO.

In one case I want to avoid this logging.

I see several ways:

Variant 1: a new kwarg like do_logging=True which I can switch to false.

Variant 2: Use some magic context which ignores this line.

with IgnoreLoggingContext() as context:
    import_customers()

How could I implement IgnoreLoggingContext()?

If you think V1 is better, then please leave a comment.


Solution 1:

It depends on your need. If you want to disable the whole logging, it would be the simplest:

from contextlib import contextmanager
import logging


@contextmanager
def IgnoreLoggingContext():
    root = logging.getLogger()
    origin_level = root.getEffectiveLevel()
    root.setLevel(logging.WARNING) # Or whatever you want
    yield
    root.setLevel(origin_level)

with IgnoreLoggingContext():
    do_something()

Or you can pass a variable to the manager to specify which logger to disable:

@contextmanager
def IgnoreLoggingContext(name):
    logger = logging.getLogger(name)
    origin_level = logger.getEffectiveLevel()
    logger.setLevel(logging.WARNING) # Or whatever you want
    yield
    logger.setLevel(origin_level)

Solution 2:

Loggers can be completely disabled via the disabled attribute. Another thing is that loggers do not necessarily propagate to the root logger and can define own record handling, so the complete disabling could look like this:

@contextlib.contextmanager
def off():
    loggers = [logging.getLogger(name) for name in logging.root.manager.loggerDict]
    # turn loggers off
    for logger in loggers:
        logger.disabled = True
    logging.root.disabled = True
    yield
    # turn loggers back on
    for logger in loggers:
        logger.disabled = False
    logging.root.disabled = False

Usage example:

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    logging.info('foo')
    with off():
        logging.info('bar')

will print

INFO:root:foo

Solution 3:

Just change the logging level from INFO to ERROR and when you're done change it back.

# Beginning of file
rootLogger.setLevel(logging.INFO)

# Change logging level to only log to error, just prior to calling your method
rootLogger.setLevel(logging.ERROR)

# Change it back when you're done
rootLogger.setLevel(logging.INFO)