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

如何格式化终止进程的异常?能否用logging模块输出JSON格式报错无需try/except?

实现方案

完全可以实现,核心思路是替换Python全局的sys.excepthook钩子捕获所有未处理异常,结合logging的自定义格式化器输出JSON结构日志,不需要修改业务代码加try/except,也不需要手动调用logging.exception。

具体实现步骤

1. 依赖安装(可选)

用第三方JSON格式化库可以简化开发,不想引入依赖也可以自己手写格式化逻辑:

pip install python-json-logger

2. 全局配置代码

只需要在程序入口位置添加如下配置即可,原有业务代码无需任何改动:

import sys
import logging
from pythonjsonlogger import jsonlogger

# 配置logging输出
log_handler = logging.StreamHandler()
# 定义JSON输出字段,可按需增减
formatter = jsonlogger.JsonFormatter(
    fmt="%(levelname)s %(exc_info)s %(asctime)s %(message)s",
    rename_fields={"levelname": "level", "exc_info": "exc_info", "asctime": "timestamp"}
)
log_handler.setFormatter(formatter)

root_logger = logging.getLogger()
root_logger.addHandler(log_handler)
root_logger.setLevel(logging.ERROR)

# 自定义全局异常钩子
def global_excepthook(exc_type, exc_val, exc_tb):
    # 跳过键盘中断这类正常退出的异常,不需要可以删除这段
    if issubclass(exc_type, KeyboardInterrupt):
        sys.__excepthook__(exc_type, exc_val, exc_tb)
        return
    # 传入异常信息输出日志
    root_logger.error("uncaught exception", exc_info=(exc_type, exc_val, exc_tb))

sys.excepthook = global_excepthook

3. 效果验证

把你原有的业务代码放在配置后面:

# 原有业务代码无需修改
foo = 1
bar = foo + 2
raise ValueError("FIXME")

执行python foo.py后输出的日志格式如下:

{"level": "ERROR", "exc_info": "Traceback (most recent call last):\n  File \"/opt/app/foo.py\", line 32, in <module>\n    raise ValueError(\"FIXME\")\nValueError: FIXME", "timestamp": "2024-05-20 14:22:31,123", "message": "uncaught exception"}

注意事项

  • 如果不想引入第三方依赖,可以自己继承logging.Formatter实现自定义格式化逻辑,在format方法中手动把日志字段拼接成JSON字符串即可
  • Python 3.8+版本如果用到多线程,需要额外配置threading.excepthook捕获子线程未处理异常
  • 多进程场景下需要在每个子进程启动时重新注册一遍sys.excepthook才会生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 08:36:03