Reputation: 1967
I have python project with multiple modules with logging. I perform initialization (reading log configuration file and creating root logger and enable/disable logging) in every module before start of logging the messages. Is it possible to perform this initialization only once in one place (like in one class may be called as Log) such that the same settings are reused by logging all over the project?
I am looking for a proper solution to have only once to read the configuration file and to only once get and configure a logger, in a class constructor, or perhaps in the initializer (__init__.py
). I don't want to do this at client side (in __main__
). I want to do this configuration only once in separate class and call this class in other modules when logging is required.
Upvotes: 4
Views: 12227
Reputation: 4738
You can initialize and configure logging in your main entry point. See Logging from multiple modules in this official Python 3 HOWTO.
Upvotes: 2
Reputation: 106
I personally prefer doing my initialization in the __init__.py
at a relatively high level in the package hierarchy. This configures the parent logger for all child loggers created with the __name__
parameter within the package hierarchy.
See the top answer in this post here for a detailed recommendation on how to best use the logger hierarchy: Where to configure logging? It's long but worth the read.
Upvotes: 2
Reputation: 282
From the documentation,
Note that Loggers should NEVER be instantiated directly, but always through the module-level function logging.getLogger(name). Multiple calls to getLogger() with the same name will always return a reference to the same Logger object.
Upvotes: 3
Reputation: 4654
I had the same problem and I don't have any classes or anything, so I solved it with just using global variable
utils.py:
existing_loggers = {}
def get_logger(name='my_logger', level=logging.INFO):
if name in existing_loggers:
return existing_loggers[name]
# Do the rest of initialization, handlers, formatters etc...
Upvotes: 0
Reputation: 1967
setup using @singleton pattern
#log.py
import logging.config
import yaml
from singleton_decorator import singleton
@singleton
class Log:
def __init__(self):
configFile = 'path_to_my_lof_config_file'/logging.yaml
with open(configFile) as f:
config_dict = yaml.load(f)
logging.config.dictConfig(config_dict)
self.logger = logging.getLogger('root')
def info(self, message):
self.logger.info(message)
#module1.py
from Log import Log
myLog = Log()
myLog.info('Message logged successfully)
#module2.py
from Log import Log
myLog = Log() #config read only once and only one object is created
myLog.info('Message logged successfully)
Upvotes: -1