Reputation: 959
I want my function do_x
to use (child) logger __main__.do_all
that is defined in the parent scope do_all
from which do_x
is called. Instead the root logger is used by default.
Is there a way do force do_x
to use the child logger __main__.do_all
? Should I pass the logger as parameter to do_x
, even though it is not recommended in numerous posts? Assume that I want to call do_x
also from other scopes using other (child) loggers.
import logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(funcName)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
def do_x():
logger.warning('doing x')
def do_all():
logger = logging.getLogger(__name__ + '.do_all')
logger.warning('Starting do_all')
do_x()
def do_all_other():
logger = logging.getLogger(__name__ + '.do_all_other')
logger.warning('Starting do_all_other')
do_x()
do_all()
do_all_other()
Produces
2022-09-27 11:34:40,562 - __main__.do_all - do_all - WARNING - Starting do_all
2022-09-27 11:34:40,562 - __main__ - do_x - WARNING - doing x
2022-09-27 11:34:40,562 - __main__.do_all_other - do_all_other - WARNING - Starting do_all_other
2022-09-27 11:34:40,562 - __main__ - do_x - WARNING - doing x
I want the second and the last line of the output to use __main__.do_all
and __main__.do_all_other
respectively
Upvotes: 1
Views: 879
Reputation: 5195
import logging
import inspect
logging.basicConfig(format='%(asctime)s - %(name)s - %(funcName)s - %(levelname)s - %(message)s')
def do_x():
logger_name = __name__ + '.' + inspect.stack()[1].function
logger = logging.getLogger(logger_name)
logger.warning('some log')
def do_all():
do_x()
def do_other():
do_x()
do_all()
do_other()
produces
2022-09-26 17:33:06,967 - __main__.do_all - do_x - WARNING - some log
2022-09-26 17:33:06,967 - __main__.do_other - do_x - WARNING - some log
Requires a recent version of python, but works with older versions too. inspect.stack()
just returns the data in a slightly different format in older versions.
Upvotes: 2
Reputation: 532538
The logger namespace is independent of function scopes. do_x
should simply make the same call to getLogger
to use the same Logger
instance.
def do_x():
logging.getLogger(__name__ + '.do_all').info('doing x')
Upvotes: 0