首页 文章

在Python中记录一个堆栈级别的模块名称/行

提问于
浏览
2

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

你知道如何报告函数及其模块名称和行号,而不是调用包装器吗?

2 回答

  • 2

    虽然我同意如上所述使用包装器有点傻,但我自己解决了这个问题,因为当使用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以删除对额外内容中的键冲突的检查,并将行号,函数名称等添加到日志调用本身/检测包装器中的此类内容 .

  • 0

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

相关问题