python中如何用sys.excepthook来对全局异常进行捕获、显示及输出到error日志中
使用sys.excepthook函数进行全局异常的获取。
1. 使用MessageDialog实现异常显示;
2. 使用logger把捕获的异常信息输出到日志中;
步骤:定义异常处理函数, 并使用该函来替换掉系统的内置处理函数;
对于threading.py的异常捕获,需要对该文件进行一些改变:
如下:
try: self.run() except SystemExit: if __debug__: self._note("%s.__bootstrap(): raised SystemExit", self) except: if __debug__: self._note("%s.__bootstrap(): unhandled exception", self) # If sys.stderr is no more (most likely from interpreter # shutdown) use self.__stderr. Otherwise still use sys (as in # _sys) in case sys.stderr was redefined since the creation of # self. if _sys: if id(_sys.excepthook) != id(_sys.__excepthook__): exc_type, exc_value, exc_tb = self.__exc_info() _sys.excepthook(exc_type, exc_value, exc_tb) _sys.stderr.write("Exception in thread %s:\n%s\n" % (self.name, _format_exc()))
#-*- coding: UTF-8 -*- #------------------------------------------------------------------------------- # Name: 模块except hook handler # Purpose: 全局捕获异常 # # Author: ankier # # Created: 17-08-2013 # Copyright: (c) ankier 2013 # Licence: <your licence> #------------------------------------------------------------------------------- import logging import sys import traceback import datetime import wx ## @detail 创建记录异常的信息 class ExceptHookHandler(object): ## @detail 构造函数 # @param logFile: log的输入地址 # @param mainFrame: 是否需要在主窗口中弹出提醒 def __init__(self, logFile, mainFrame = None): self.__LogFile = logFile self.__MainFrame = mainFrame self.__Logger = self.__BuildLogger() #重定向异常捕获 sys.excepthook = self.__HandleException ## @detail 创建logger类 def __BuildLogger(self): logger = logging.getLogger() logger.setLevel(logging.DEBUG) logger.addHandler(logging.FileHandler(self.__LogFile)) return logger ## @detail 捕获及输出异常类 # @param excType: 异常类型 # @param excValue: 异常对象 # @param tb: 异常的trace back def __HandleException(self, excType, excValue, tb): # first logger try: currentTime = datetime.datetime.now() self.__Logger.info('Timestamp: %s'%(currentTime.strftime("%Y-%m-%d %H:%M:%S"))) self.__Logger.error("Uncaught exception:", exc_info=(excType, excValue, tb)) self.__Logger.info('\n') except: pass # then call the default handler sys.__excepthook__(excType, excValue, tb) err_msg = ''.join(traceback.format_exception(excType, excValue, tb)) err_msg += '\n Your App happen an exception, please contact administration.' # Here collecting traceback and some log files to be sent for debugging. # But also possible to handle the error and continue working. dlg = wx.MessageDialog(None, err_msg, 'Administration', wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy()
输出效果:
log输出文件: