Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logging module name/line of one stack level higher in Python

Tags:

python

logging

I wrote a wrapper logger class which keeps the return value of self.logger=getLogger(...) in an attribute and calls logging requests accordingly (self.logger.info(...)). In the handler formats I use the tags %(module)s and %(lineno)d to print module name and line number. Unfortunately I only get the wrappers module name in line number since that is where the final call to the logging system happens.

Do you know how to report the function with its module name and line number which calls the wrapper instead?

like image 558
Gerenuk Avatar asked Oct 22 '25 03:10

Gerenuk


1 Answers

While I agree that having a wrapper as described is a bit silly, I just solved this problem myself for when using a lambda to wrap calls that have similar, long, and annoying parameters in "extras". Having not found a good answer elsewhere I thought I'd share.

(This is a Python 3.2.3 solution. And again, it's specific to a lambda wrapper rather than a class wrapper.)

Step one: look up the Python source code, find ..Lib\logging\__init__.py,
Step b: find the "Logger.findCaller" method, copy it into a utility file somewhere, renamed to, say, "find_caller_no_lambda".
Next step: remove "self" from the method signature, prefix any module level attributes, and make the following change, modified to taste:

#       if filename == _srcfile: # Original line
        if filename == logging._srcfile or f.f_code.co_name == "<lambda>": # New line
            f = f.f_back # Original line for context.
            continue # Original line for context.

Step the last: wherever your logger is declared, insert the following line:

my_logger.findCaller = util.find_caller_no_lambda

Voilà.

(And of course you can just subclass Logger for that one little change if you feel like it.)

Addendum:

Conversely, you can rewrite Logger.makeRecord to remove the check against key conflicts in extras, and add the line numbers, function name, etc, to the log call itself/detect such things in your wrapper.

like image 192
Redsplinter Avatar answered Oct 23 '25 17:10

Redsplinter