用于python警告的日志堆栈跟踪

use*_*844 5 python logging warnings stack-trace

我正在我的python程序中使用的包正在发出警告,我想了解其确切原因.我已经设置logging.captureWarning(True)并在捕获日志中捕获警告,但仍然不知道它来自何处.我如何记录堆栈跟踪,以便我可以看到警告来自哪里?我用traceback吗?

小智 6

这有点hackish,但你可以将warnings.warn方法monkeypatch 到这个:

import traceback
import warnings

def g():
    warnings.warn("foo", Warning)

def f():
    g()
    warnings.warn("bar", Warning)

_old_warn = warnings.warn
def warn(*args, **kwargs):
    tb = traceback.extract_stack()
    _old_warn(*args, **kwargs)
    print("".join(traceback.format_list(tb)[:-1]))
warnings.warn = warn

f()
print("DONE")
Run Code Online (Sandbox Code Playgroud)

这是输出:

/tmp/test.py:14: Warning: foo
  _old_warn(*args, **kwargs)
  File "/tmp/test.py", line 17, in <module>
    f()
  File "/tmp/test.py", line 8, in f
    g()
  File "/tmp/test.py", line 5, in g
    warnings.warn("foo", Warning)

/tmp/test.py:14: Warning: bar
  _old_warn(*args, **kwargs)
  File "/tmp/test.py", line 17, in <module>
    f()
  File "/tmp/test.py", line 9, in f
    warnings.warn("bar", Warning)

DONE
Run Code Online (Sandbox Code Playgroud)

看到调用原始warnings.warn函数不会报告您想要的行,但堆栈跟踪确实是正确的(您可以自己打印警告消息).


use*_*844 5

我结束了下面的内容:

import warnings
import traceback

_formatwarning = warnings.formatwarning

def formatwarning_tb(*args, **kwargs):
    s = _formatwarning(*args, **kwargs)
    tb = traceback.format_stack()
    s += ''.join(tb[:-1])
    return s

warnings.formatwarning = formatwarning_tb
logging.captureWarnings(True)
Run Code Online (Sandbox Code Playgroud)