I have the following application structure:
./utils.py
def do_something(logger=None):
if not logger:
logger = logging.getLogger(__name__)
print('hello')
logger.debug('test')
./one.py
from utils import do_something
logger = logging.getLogger(__name__)
do_something(logger=logger)
./two.py
from utils import do_something
logger = logging.getLogger(__name__)
do_something(logger=logger)
Now, then this runs, the logging output will show the names of the respective modules that are using the functions (one
and two
) rather than utils
. I then use this information (the logger's name) to filter the messages.
Is there a way to do this without having to pass the logger though as an argument? Would I have to basically introspect the caller function and initialize a logger based on that? What's the common solution for this type of recipe, when one function is used all over the code base but the loggers should be of those calling the function?
Passing the
logger
as an argument looks fine to me. But if you have many calls todo_something
then passing the same logger in each call is not only too verbose but prone to errors --you might pass the wrong logger by mistake. Also, while you do need to makedo_something
aware of the logger, doing it at the point where you are calling it probably does not make sense --you want to do something, not mess with loggers. OOP to the rescue: makedo_something
a method of a class and pass the logger when instantiating the class, then you do not need to pass it to the method.Now in the client module you create an instance of
UsefulObject
and you can call.do_something
on it without passing the logger every time.Variable
logger
being a global, can be accessed from insidedo_something()
function like this:After reading this carefully:
In simple english would be:
I conclude that there is no other way!
You have to pass logger as an argument for this particular case.
If you don't like the existing solutions, here's a magic way to do it:
The calling function must then have a global variable called
log
.