如何用Python记录当前行和堆栈信息?

26 投票
8 回答
24295 浏览
提问于 2025-04-16 12:23

我有一个记录日志的功能,代码如下。

logging.basicConfig(
    filename = fileName,
    format = "%(levelname) -10s %(asctime)s %(message)s",
    level = logging.DEBUG
)

def printinfo(string):
    if DEBUG:
        logging.info(string)

def printerror(string):
    if DEBUG:
        logging.error(string)
    print string

我需要记录行号和堆栈信息。例如:

1: def hello():
2:    goodbye()
3:
4: def goodbye():
5:    printinfo()

---> Line 5: goodbye()/hello()

我该如何用Python实现这个功能呢?

解决方案

def printinfo(string):
    if DEBUG:
        frame = inspect.currentframe()
        stack_trace = traceback.format_stack(frame)
        logging.debug(stack_trace[:-1])
    if LOG:
        logging.info(string)

这个方法给了我我需要的信息,正好符合我的要求。

DEBUG      2011-02-23 10:09:13,500 [
  '  File "/abc.py", line 553, in <module>\n    runUnitTest(COVERAGE, PROFILE)\n', 
  '  File "/abc.py", line 411, in runUnitTest\n    printinfo(string)\n']

8 个回答

18

从Python 3.2开始,你可以通过在记录日志时加上stack_info=True这个参数来简化操作。不过,如果你使用的是更早的版本,就需要参考上面提到的其他方法了。

19
import inspect
import traceback

def method():
   frame = inspect.currentframe()
   stack_trace = traceback.format_stack(frame)
   print ''.join(stack_trace)

使用 stack_trace[:-1] 可以避免在堆栈跟踪中包含 method/printinfo 的信息。

20

要获取当前的函数名、模块和行号,你只需要修改你的格式字符串,把这些信息加进去就可以了。

logging.basicConfig(
    filename = fileName,
    format = "%(levelname) -10s %(asctime)s %(module)s:%(lineno)s %(funcName)s %(message)s",
    level = logging.DEBUG
)

大多数人只在记录异常时才需要堆栈信息,而如果你调用 logging.exception(),日志模块会自动帮你处理这些。如果你在其他时候也想要堆栈信息,那就需要用到 traceback 模块来提取你需要的额外信息。

撰写回答