我和 Erik 做了同样的事情,但有一些变化:
import logging
import inspect
from os import path
loggers_dict = {}
def myMakeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
if extra and 'pathname' in extra:
fn = extra.pop('pathname')
rv = logging.LogRecord(name, level, fn, lno, msg, args, exc_info, func)
if extra is not None:
rv.__dict__.update(extra)
return rv
logging.Logger.makeRecord = myMakeRecord
def getLogger():
fn, lno, func = base_logger.findCaller()
extras = {'pathname': fn, 'lineno': lno, 'funcName': func}
fnn = path.normcase(fn)
caller_name = inspect.modulesbyfile.get(fnn, inspect.getmodule(None, fn).__name__)
if caller_name not in loggers_dict:
loggers_dict[caller_name] = logging.getLogger(caller_name)
return loggers_dict[caller_name], extras
def myLogDebug(*msg):
log, extras = getLogger()
if len(msg) == 1:
log.debug(msg[0], extra=extras)
else:
log.debug(' '.join(map(str, msg)), extra=extras)
这里的主要内容是遗留问题,人们在代码上调用了 myLogDebug,如果我更改所有内容,那将是一团糟。另一个问题是 python 2.7 版本,如果我可以使用来自this thread 的参数堆栈级别会很好。
然后我修改了一些东西以获得正确的调用者堆栈帧级别,并且没有改变原始方法的任何内容。
编辑 - 1
caller_name = inspect.modulesbyfile.get(fnn, inspect.getmodule(None, fn).__name__)
这部分是一个小技巧,只是为了不要一直从检查模块运行getmodule。有一个 dict(一个内部缓存 modulesbyfile)在第一个 getmodule 之后可以直接访问模块名称。
有时调试源代码帮助的轨道,它没有记录。