This is the formatting string that I am using for logging:
\'%(asctime)s - %(levelname)-10s - %(funcName)s - %(message)s\'
But to show the logg
Someone has given the right answer. I will make a summary.
logging.Logger.findCaller(), it filter stack frames by logging._srcfile in original logging
package.
So we do the same thing, filter our own logger wrapper my_log_module._srcfile
. We replace the method logging.Logger.findCaller() of your logger instance dynamically.
BTW, please don't create a subclass of logging.Logger
, logging
package has no design for OOP when findCaller, pitty...yes?
# file: my_log_module.py, Python-2.7, define your logging wrapper here
import sys
import os
import logging
my_logger = logging.getLogger('my_log')
if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3)
# done filching
#
# _srcfile is used when walking the stack to check when we've got the first
# caller stack frame.
#
_srcfile = os.path.normcase(currentframe.__code__.co_filename)
def findCallerPatch(self):
"""
Find the stack frame of the caller so that we can note the source
file name, line number and function name.
"""
f = currentframe()
#On some versions of IronPython, currentframe() returns None if
#IronPython isn't run with -X:Frames.
if f is not None:
f = f.f_back
rv = "(unknown file)", 0, "(unknown function)"
while hasattr(f, "f_code"):
co = f.f_code
filename = os.path.normcase(co.co_filename)
if filename == _srcfile:
f = f.f_back
continue
rv = (co.co_filename, f.f_lineno, co.co_name)
break
return rv
# DO patch
my_logger.findCaller = findCallerPatch
Ok, all ready. You can use your logger in other modules now, add your logging message format: lineno, path, method name, blablabla
# file: app.py
from my_log_module import my_logger
my_logger.debug('I can check right caller now')
Or you can use a elegant way, but don't use global logging.setLoggerClass
# file: my_log_modue.py
import logging
my_logger = logging.getLogger('my_log')
class MyLogger(logging.Logger):
...
my_logger.__class__ = MyLogger