如何提取并保存異常堆棧信息到日志?1. 使用traceback模塊獲取完整的異常堆棧;2. 配置Logging模塊將錯誤信息寫入日志文件;如何自定義異常信息?1. 在捕獲異常時拼接額外上下文(如operation_id);2. 使用raise重新拋出異常;如何處理多線程或異步環境下的異常?1. 使用sys.exc_info()獲取線程異常信息;2. 配置日志格式包含線程名稱;如何處理嵌套異常?1. 利用__cause__和__context__屬性追蹤異常鏈;2. 遞歸記錄所有層級的異常信息。
直接提取異常堆棧信息并保存到日志文件,核心在于traceback模塊的靈活運用,以及對日志模塊的配置。這不僅能幫助我們快速定位問題,還能為后續的錯誤分析提供詳實的數據。
import traceback import logging # 配置日志 logging.basicConfig(filename='error.log', level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s') def some_function(a, b): return a / b try: result = some_function(10, 0) print(result) except Exception as e: # 獲取完整的異常堆棧信息 error_message = traceback.format_exc() # 記錄到日志文件 logging.error(error_message) print("發生錯誤,詳情請查看error.log")
如何自定義異常信息,使其更具可讀性?
除了標準的traceback信息,我們還可以自定義異常信息,使其包含更多上下文,方便問題排查。例如,在捕獲異常時,可以添加一些額外的參數或變量信息。
import traceback import logging logging.basicConfig(filename='error.log', level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s') def some_function(a, b, operation_id): try: return a / b except Exception as e: # 添加operation_id到異常信息中 error_message = f"Operation ID: {operation_id}n{traceback.format_exc()}" logging.error(error_message) raise # 重新拋出異常,可以選擇不拋出 try: some_function(10, 0, "user_login_123") except Exception as e: print("發生錯誤,詳情請查看error.log")
如何處理多線程或異步環境下的異常堆棧信息?
在多線程或異步環境中,異常的產生和捕獲可能不在同一個線程或協程中,需要特殊處理才能正確記錄堆棧信息。一種常見的方法是使用sys.exc_info()獲取當前線程的異常信息,并傳遞給日志記錄函數。
import traceback import logging import threading import time logging.basicConfig(filename='error.log', level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(threadName)s - %(message)s') def worker(): try: 1 / 0 except Exception as e: # 獲取當前線程的異常信息 exc_info = sys.exc_info() # 記錄到日志文件 logging.error("Exception in thread", exc_info=exc_info) threads = [] for i in range(2): t = threading.Thread(target=worker, name=f"Thread-{i}") threads.append(t) t.start() for t in threads: t.join() print("Done.")
如何優雅地處理嵌套異常的堆棧信息?
有時候,一個異常可能會導致另一個異常,形成嵌套異常。要完整地記錄這些嵌套異常的堆棧信息,需要遞歸地處理異常鏈。python 3 提供 __cause__ 和 __context__ 屬性來追蹤異常鏈。
import traceback import logging logging.basicConfig(filename='error.log', level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s') def inner_function(): try: raise ValueError("Inner exception") except ValueError as e: raise RuntimeError("Outer exception") from e def outer_function(): try: inner_function() except RuntimeError as e: log_exception_chain(e) def log_exception_chain(e): error_message = traceback.format_exception(type(e), e, e.__traceback__) logging.error("".join(error_message)) if e.__cause__: logging.error("Caused by:") log_exception_chain(e.__cause__) elif e.__context__: logging.error("Context:") log_exception_chain(e.__context__) try: outer_function() except Exception as e: print("發生錯誤,詳情請查看error.log")
import sys
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END