Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable logging per method/function?

Tags:

python

logging

I'm new to Python logging and I can easily see how it is preferrable to the home-brew solution I have come up with.

One question I can't seem to find an answer to: how do I squelch logging messages on a per-method/function basis?

My hypothetical module contains a single function. As I develop, the log calls are a great help:

logging.basicConfig(level=logging.DEBUG,
                format=('%(levelname)s: %(funcName)s(): %(message)s'))
log = logging.getLogger()

my_func1():
    stuff...
    log.debug("Here's an interesting value: %r" % some_value)
    log.info("Going great here!")
    more stuff...

As I wrap up my work on 'my_func1' and start work on a second function, 'my_func2', the logging messages from 'my_func1' start going from "helpful" to "clutter".

Is there single-line magic statement, such as 'logging.disabled_in_this_func()' that I can add to the top of 'my_func1' to disable all the logging calls within 'my_func1', but still leave logging calls in all other functions/methods unchanged?

Thanks

linux, Python 2.7.1

like image 784
JS. Avatar asked Sep 07 '11 22:09

JS.


2 Answers

The trick is to create multiple loggers.

There are several aspects to this.

First. Don't use logging.basicConfig() at the beginning of a module. Use it only inside the main-import switch

 if __name__ == "__main__":
     logging.basicConfig(...)
     main()
     logging.shutdown()

Second. Never get the "root" logger, except to set global preferences.

Third. Get individual named loggers for things which might be enabled or disabled.

log = logging.getLogger(__name__)

func1_log = logging.getLogger( "{0}.{1}".format( __name__, "my_func1" )

Now you can set logging levels on each named logger.

log.setLevel( logging.INFO )
func1_log.setLevel( logging.ERROR )
like image 109
S.Lott Avatar answered Sep 30 '22 13:09

S.Lott


You could create a decorator that would temporarily suspend logging, ala:

from functools import wraps

def suspendlogging(func):
    @wraps(func)
    def inner(*args, **kwargs):
        previousloglevel = log.getEffectiveLevel()
        try:
            return func(*args, **kwargs)
        finally:
            log.setLevel(previousloglevel)
    return inner

@suspendlogging
def my_func1(): ...

Caveat: that would also suspend logging for any function called from my_func1 so be careful how you use it.

like image 29
Kirk Strauser Avatar answered Sep 30 '22 14:09

Kirk Strauser