I have various module files and want to share a common object (in this case a logger) to each of them. What is the best way to do this? I have a solution but it does not feel just right.
In pseudo code:
module_1.py
global logger
# module_1
def pass_logger_module1(plogger):
global logger
logger = plogger
module_2.py
global logger
# module_2
def pass_logger_module2(plogger):
global logger
logger = plogger
main_module.py
from module_1 import pass_logger_module1
from module_2 import pass_logger_module2
logger = set_logger(logfile, logformat, 'DEBUG')
pass_logger_module1(logger)
pass_logger_module2(logger)
-
4That isn't how you should be using loggers. The logging module has the specific ability to define a parent logger with the settings you want and for child loggers to inherit them. You should read the documentation.Daniel Roseman– Daniel Roseman2018年07月19日 13:39:58 +00:00Commented Jul 19, 2018 at 13:39
-
Thanks I will do. However in more general terms what is the best way to share a common object?Bruno Vermeulen– Bruno Vermeulen2018年07月19日 13:44:19 +00:00Commented Jul 19, 2018 at 13:44
-
The best way is to pass it explicitly to each function that needs it and/or save it in objects that use it.David Maze– David Maze2018年07月21日 23:04:49 +00:00Commented Jul 21, 2018 at 23:04
3 Answers 3
As pointed out in the comments this isn't the way use the logging module.
however a more general answer for "common object to different module files" is to do it the other way around from your example, meaning:
main_module.py
# this is in global
logger = set_logger(logfile, logformat, 'DEBUG')
module_1.py
from main_module import logger
module_2.py
from main_module import logger
EDIT:
to avoid making a circular import perhaps store the logger in a different module:
settings.py
# this is in global
logger = set_logger(logfile, logformat, 'DEBUG')
main_module.py
from settings import logger
3 Comments
One way to do this is to expose your shared object through a third module, like so:
my_logger.py
logger = set_logger(logfile, logformat, 'DEBUG')
module_1.py
from my_logger import logger
...
module_2.py
from my_logger import logger
...
Your main module can then import both module_1 and module_2 without knowing about the logger and avoiding a circular import situation.
Comments
First, define your custom logger in custom_logger.py
import logging
import sys
class CustomFormatter(logging.Formatter):
err_fmt = "[*] ERROR: %(msg)s"
dbg_fmt = "[-] DEBUG: %(module)s: %(lineno)d: %(msg)s"
info_fmt = "[+] %(msg)s"
def __init__(self):
super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%')
def format(self, record):
# Save the original format configured by the user
# when the logger formatter was instantiated
format_orig = self._style._fmt
# Replace the original format with one customized by logging level
if record.levelno == logging.DEBUG:
self._style._fmt = CustomFormatter.dbg_fmt
elif record.levelno == logging.INFO:
self._style._fmt = CustomFormatter.info_fmt
elif record.levelno == logging.ERROR:
self._style._fmt = CustomFormatter.err_fmt
# Call the original formatter class to do the grunt work
result = logging.Formatter.format(self, record)
# Restore the original format configured by the user
self._style._fmt = format_orig
return result
class CustomLogger(logging.Logger):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
formatter = CustomFormatter()
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(formatter)
self.addHandler(handler)
self.setLevel(logging.INFO)
Then, in your other modules, import CustomLogger.
from custom_logger import CustomLogger
logger = CustomLogger(__name__)
logger.debug("Hello, world!")