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

posted on 2013-08-17 09:04  |残阳|露  阅读(11641)  评论(0编辑  收藏  举报

导航