Inherit python logger from parent function scope

Question:

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

Asked By: Pepacz

||

Answers:

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')
Answered By: chepner
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.

Answered By: blues
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.