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

如何让Python项目中所有未捕获异常附带时间戳输出到标准输出

给未捕获异常添加时间戳输出的解决方案

我懂你的需求——不用纠结这个websocket连接关闭的异常原因,就是想让所有没被捕获的异常在打印的时候都带上时间戳对吧?下面给你两种实用的实现方式,覆盖主线程和子线程的场景:

1. 处理主线程的未捕获异常:重写sys.excepthook

Python的sys.excepthook是全局处理未捕获异常的钩子,我们可以重写它,在输出异常栈前加上时间戳:

import sys
import traceback
from datetime import datetime

def timestamp_excepthook(type, value, tb):
    # 获取当前时间并格式化
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    # 先打印时间戳
    print(f"[{timestamp}] Uncaught exception:")
    # 再打印原本的异常栈信息
    traceback.print_exception(type, value, tb)

# 替换默认的excepthook
sys.excepthook = timestamp_excepthook

把这段代码放在你项目的入口文件最开始的位置(比如client.py的开头),主线程里的未捕获异常就会自动带上时间戳了。

2. 处理子线程的未捕获异常:自定义线程类

你遇到的异常是在Thread-1里的,而默认的sys.excepthook不会处理子线程的未捕获异常。我们需要自定义线程类,重写run方法来捕获线程内的异常并添加时间戳:

import threading
import traceback
from datetime import datetime

class TimestampThread(threading.Thread):
    def run(self):
        try:
            # 执行原本的线程逻辑
            super().run()
        except Exception as e:
            timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            print(f"[{timestamp}] Exception in thread {self.name}:")
            traceback.print_exc()

然后在你的代码里,创建线程的时候用这个自定义类代替原来的threading.Thread。比如你代码里的Timer(Timer是Thread的子类),可以这样修改:

# 原来的代码:
# self.keepAliveTimer = Timer(15, lambda: self.sendKeepAlive())

# 修改后:
from threading import Timer

class TimestampTimer(TimestampThread, Timer):
    pass

self.keepAliveTimer = TimestampTimer(15, lambda: self.sendKeepAlive())

这样子线程里的未捕获异常也会带上时间戳输出了。

验证效果

修改后,再触发异常的话,输出会变成类似这样:

[2024-05-20 14:35:22] Exception in thread Thread-1:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
...(后面是原本的异常栈)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 09:42:34