7

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.

Sagar Gupta
  • 1,352
  • 1
  • 12
  • 26
guettli
  • 25,042
  • 81
  • 346
  • 663
  • Don't understand what are you still looking for...? There are at least two valid answers. Or if you have more requirements you should specify them in your question. – Sraw Aug 28 '19 at 00:28
  • @Sraw I am curious. Yes, there are two valid answers. Maybe someone knows a third solution. – guettli Aug 28 '19 at 10:35
  • Immediate thought is you can set a custom logging level for this, see or similar https://stackoverflow.com/questions/2183233/how-to-add-a-custom-loglevel-to-pythons-logging-facility – stacksonstacks Aug 29 '19 at 21:39
  • @stacksonstacks I don't understand why a custom logging level does help. – guettli Aug 30 '19 at 07:40

3 Answers3

8

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)
Flimm
  • 136,138
  • 45
  • 251
  • 267
Sraw
  • 18,892
  • 11
  • 54
  • 87
3

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
hoefling
  • 59,418
  • 12
  • 147
  • 194
1

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)
Calculus
  • 781
  • 7
  • 20
  • 2
    This overwrites the log level if it was DEBUG at the beginning. And it does not set the old level again if an exception was raised. But basically I think you are right: first read the current log level. Then try-except-finally and set the old level again in the finally block. – guettli Aug 30 '19 at 07:36