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)
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With