I need to set up logging for a fairly specific setup. In short, I want to handle logging from a common piece of library code in two different "parent" modules.
app_one \
app_one_main.py
app_two \
app_two_main.py
lib_package \
lib_module.py
Both app_one_main and app_two_main import lib_module (code below).
These modules obviously do not share the same package structure, so logging messages from lib_module won't propagate up to app_one or app_two by default, if I'm using getLogger(__name__)
Restrictions
- Both app_one and app_two will be running in the same Python session, so I can't globally manipulate the hierarchy of the logger in lib_module.
- I can't manipulate the global root logger because of the way my code is integrated into a larger system.
- app_one and app_two have different handlers. For instance, they write their logs to different files.
Some Ideas
- This answer suggests passing a parent logger into functions of the library code. This would work, I guess, but it would break almost all of my existing code and I'm not thrilled about passing around loggers this way.
- I could subclass
logging.Loggerand overrideLogger.parentsuch that it finds any loggers in its enclosing scopes. I've implemented something similar in the past, but it seems a bit over-engineered and it would break a lot of features of the default logging system.
Code
(this code does not even pretend to work. It's just a rough starting place.)
# app_one_main.py
import logging
from lib_package import lib_module
logger = logging.getLogger(__name__)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(logging.Formatter("APP ONE: %(message)s"))
logger.addHandler(stream_handler)
def log_app_one():
logger.warning("hello from app_one_main")
lib_module.do_the_thing()
# app_two_main.py
import logging
from lib_package import lib_module
logger = logging.getLogger(__name__)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(logging.Formatter("APP TWO: %(message)s"))
logger.addHandler(stream_handler)
def log_app_two():
logger.warning("hello from app_two_main")
lib_module.do_the_thing()
# lib_module.py
import logging
logger = logging.getLogger(__name__)
def do_the_thing():
logger.warning("hello from library code")
Desired Result
app_one and app_two will ultimately run on another platform like Maya, which provides a single python session. Both modules will be imported into that same session.
So, if I ran app_one_main.log_app_one(), I would want:
APP ONE: hello from app_one_main
APP ONE: hello from library code
And app_two_main.log_app_two():
APP TWO: hello from app_two_main
APP TWO: hello from library code