Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient way of setting Logging across a Package Module

I have a package that has several components in it that would benefit greatly from using logging and outputting useful information.

What I do not want to do is to 'setup' proper logging for every single file with somewhere along these lines:

import logging
logging.basicConfig(level=DEBUG)
my_function = logging.getLogger("my_function")
my_class = logging.getLogger("my_class")

I have tried a couple of approaches, one of them being adding the boilerplate code into a class within a utility module and try and do something like this:

from util import setlogging
set_logging()

But even the above solution doesn't look clean to me and would cause issues because setLogger doesn't have a __call__ method. What I did liked was that my "set_logging" class would read form a config file and have some default values so it wouldn't matter what level or what type of logging format I wanted it would set it up correctly.

Is there a way to initialize proper logging across the board in my package? Maybe in the __init__.py file?

And just to be as verbose as possible, this is what setlogging (now a function, not a class) looks like:

def setlogging(config=None):
    if config == None:
        config = config_options() # sets default values
    levels = {
        'debug': DEBUG,
       'info': INFO
        }

    level = levels.get(config['log_level'])
    log_format = config['log_format']
    datefmt = config['log_datefmt']

    basicConfig(
        level   = level,
        format  = log_format,
        datefmt = datefmt)
like image 973
alfredodeza Avatar asked Jul 28 '10 00:07

alfredodeza


2 Answers

If you want all the code in the various modules of your package to use the same logger object, you just need to (make that logger available -- see later -- and) call

mylogger.warning("Attenzione!")

or the like, rather than logging.warning &c. So, the problem reduces to making one mylogger object for the whole package and making it available throughout the modules in the package. (Alternatively, you could used named loggers with names starting with the package's name followed by a dot, but while that's very much a part of the logging package functionality, I've personally never found it a natural way to operate).

So, your util.setlogging function could simply be followed by, say,

mylogger = logging.getLogger(package_name)

and every module that imports util can simply use

util.mylogger.warning('Watch out!')

and the like. This seems to me to be the simplest approach, as long as the concept that all the code in the package should be logging in the same way applies.

like image 114
Alex Martelli Avatar answered Sep 28 '22 16:09

Alex Martelli


The proper way for a module to use logging is

import logging
logger = logging.getLogger('my_module_name')

and

logger.debug('help!')

becomes a no-op until someone calls logging.basicConfig() (or a variant).

like image 42
msw Avatar answered Sep 28 '22 16:09

msw