【问题标题】:Logging module name/line of one stack level higher in Python在 Python 中记录更高堆栈级别的模块名称/行
【发布时间】:2012-04-05 10:57:24
【问题描述】:

我编写了一个包装记录器类,它将self.logger=getLogger(...) 的返回值保存在一个属性中,并相应地调用记录请求(self.logger.info(...))。在处理程序格式中,我使用标签%(module)s%(lineno)d 打印模块名称和行号。不幸的是,我只在行号中获取包装模块名称,因为这是对日志系统的最终调用。

你知道如何用它的模块名称和行号来报告调用包装器的函数吗?

【问题讨论】:

  • 由于记录器是单例,因此将它们保存在包装器实例中不会获得任何收益。我会去掉包装纸——它能给你带来什么?

标签: python logging


【解决方案1】:

虽然我同意使用所描述的包装器有点愚蠢,但我自己解决了这个问题,因为当使用 lambda 包装在“附加”中具有相似、长且烦人的参数的调用时。在其他地方没有找到好的答案,我想我会分享。

(这是一个 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.

最后一步:在声明记录器的任何位置,插入以下行:

my_logger.findCaller = util.find_caller_no_lambda

瞧。

(当然,如果您愿意的话,您可以将 Logger 子类化为那一点点变化。)

附录:

相反,您可以重写 Logger.makeRecord 以删除对 extras 中的键冲突的检查,并将行号、函数名称等添加到日志调用本身/在包装器中检测此类内容。

【讨论】:

    【解决方案2】:

    它在 Python Frame 对象中。 http://docs.python.org/library/inspect.html

    【讨论】:

    • 但是如何让日志系统使用它呢?只有处理程序知道格式化字符串并解决它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-13
    • 2015-05-29
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    相关资源
    最近更新 更多