我写了一个包装器 Logger 类,它将 self.logger=getLogger(...) 的返回值保存在一个属性中并相应地调用记录请求( self.logger.info(...) ) . 在处理程序格式中,我使用标签 %(module)s 和 %(lineno)d 来打印模块名称和行号 . 不幸的是,我只获得行号中的包装器模块名称,因为这是对日志系统的最终调用发生的地方 .
self.logger=getLogger(...)
self.logger.info(...)
%(module)s
%(lineno)d
你知道如何报告函数及其模块名称和行号,而不是调用包装器吗?
虽然我同意如上所述使用包装器有点傻,但我自己解决了这个问题,因为当使用lambda来包装在“extras”中具有相似,冗长和烦人参数的调用时 . 在其他地方找不到好的答案,我想我会分享 .
(这是一个Python 3.2.3解决方案 . 再次,它特定于lambda包装器而不是类包装器 . )
第一步:查找Python源代码,找到..Lib \ logging \ __ init__.py,步骤b:找到"Logger.findCaller"方法,将其复制到某处的实用程序文件中,重命名为"find_caller_no_lambda" .下一步:从方法签名中删除"self",为任何模块级属性添加前缀,并进行以下更改,修改为:
# 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.
最后一步:在声明 Logger 的任何地方,插入以下行:
my_logger.findCaller = util.find_caller_no_lambda
瞧 .
(当然,如果您愿意,可以将Logger子类化为一个小改动 . )
附录:
相反,您可以重写Logger.makeRecord以删除对额外内容中的键冲突的检查,并将行号,函数名称等添加到日志调用本身/检测包装器中的此类内容 .
它在Python Frame对象中 . http://docs.python.org/library/inspect.html
2 回答
虽然我同意如上所述使用包装器有点傻,但我自己解决了这个问题,因为当使用lambda来包装在“extras”中具有相似,冗长和烦人参数的调用时 . 在其他地方找不到好的答案,我想我会分享 .
(这是一个Python 3.2.3解决方案 . 再次,它特定于lambda包装器而不是类包装器 . )
第一步:查找Python源代码,找到..Lib \ logging \ __ init__.py,
步骤b:找到"Logger.findCaller"方法,将其复制到某处的实用程序文件中,重命名为"find_caller_no_lambda" .
下一步:从方法签名中删除"self",为任何模块级属性添加前缀,并进行以下更改,修改为:
最后一步:在声明 Logger 的任何地方,插入以下行:
瞧 .
(当然,如果您愿意,可以将Logger子类化为一个小改动 . )
附录:
相反,您可以重写Logger.makeRecord以删除对额外内容中的键冲突的检查,并将行号,函数名称等添加到日志调用本身/检测包装器中的此类内容 .
它在Python Frame对象中 . http://docs.python.org/library/inspect.html