You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何消除Python异常处理中的重复日志条目?

日志重复问题解决

需求说明

当函数触发外层异常时,尝试读取文件123:

  • 若文件读取失败,记录内层异常,且不重复输出外层异常的回溯信息
  • 若文件读取成功,仅记录外层异常日志

原代码

import logging

logging.basicConfig(filename='test.log', filemode='a', level=logging.DEBUG)
logger = logging.getLogger("my_logger")


def my_div(a, b):
    try:
        return a/b
    except Exception as e:  # outer exception
        try:
            with open('123', 'rb') as fi: 
                pass
        except Exception as e1: # inner exception
            logger.exception(f"inner error\n{storage}")
        logger.exception(f"outer error\n{storage}")


storage = {}
for i in [1,0]:
    storage[i] = my_div(2, i)

问题现象

运行后日志中出现外层异常回溯重复:

ERROR:my_logger:inner error
{1: 2.0}
Traceback (most recent call last):
  File "D:/workspace/acne/src/scratch/logger_related/minimal_logger.py", line 9, in my_div
    return a/b
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "D:/workspace/acne/src/scratch/logger_related/minimal_logger.py", line 12, in my_div
    with open('123', 'rb') as fi:
FileNotFoundError: [Errno 2] No such file or directory: '123'
ERROR:my_logger:outer error
{1: 2.0}
Traceback (most recent call last):    # 需移除该重复条目
  File "D:/workspace/acne/src/scratch/logger_related/minimal_logger.py", line 9, in my_div
    return a/b
ZeroDivisionError: division by zero

问题原因

logger.exception()会自动捕获当前上下文的异常栈,当内层except块执行完后,外层的except块依然持有原始的ZeroDivisionError异常上下文,此时再次调用logger.exception()就会重复输出该异常的回溯信息。

解决方案

根据需求调整日志记录逻辑:

  • 当内层异常触发时,仅记录内层异常,不再重复记录外层异常
  • 当内层无异常(文件读取成功),再记录外层异常

修改后的代码如下:

import logging

logging.basicConfig(filename='test.log', filemode='a', level=logging.DEBUG)
logger = logging.getLogger("my_logger")


def my_div(a, b):
    try:
        return a/b
    except Exception as e:  # outer exception
        file_read_success = False
        try:
            with open('123', 'rb') as fi: 
                pass
            file_read_success = True
        except Exception as e1: # inner exception
            # 记录内层异常,自动包含外层异常的上下文
            logger.exception(f"inner error\n{storage}")
        if file_read_success:
            # 文件读取成功时,仅记录外层异常
            logger.error(f"outer error\n{storage}", exc_info=e)


storage = {}
for i in [1,0]:
    storage[i] = my_div(2, i)

说明

  1. 用file_read_success标记文件是否读取成功
  2. 内层异常触发时,logger.exception()会自动附带外层异常的上下文(即During handling of the above exception...部分),无需额外记录外层异常
  3. 文件读取成功时,使用logger.error()并通过exc_info=e指定要记录的外层异常,避免重复捕获上下文

内容的提问来源于stack exchange,提问作者sixtytrees

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 23:52:33