python中如何用sys.excepthook來對全局異常進行捕獲、顯示及輸出到error日誌中

使用sys.excepthook函數進行全局異常的獲取。bootstrap

1. 使用MessageDialog實現異常顯示;app

2. 使用logger把捕獲的異常信息輸出到日誌中;函數

步驟:定義異常處理函數, 並使用該函來替換掉系統的內置處理函數;ui

對於threading.py的異常捕獲,須要對該文件進行一些改變:spa

以下:debug

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輸出文件:code

相關文章
相關標籤/搜索