| Tony Gong的技术Blog |
|
|||
| 技术旅途中蹒跚的行者 | ||||
|
公告
日历
统计
导航 |
一个简单的异常处理方法,是把异常信息按日期储存到xml日志文件中,方便分析。
主要实现的功能是: 1,根据日期创建xml日志文件,如2006-04-26log.xml 2,把每一个异常信息,包括一些环境信息储存到xml日志中 3,对外显示一个友好的错误信息 在一下小软件上还是有一些帮助的,尤其对于bug返回很有帮助,对方只要把xml文件反馈,我们就可以根据xml上的异常信息来修复一些bug 让我们先看看日志的效果,以下是实际产生的xml日志内容: - <root> - <ExceptionInformation> - <AdditionalInformationProperty> <ExceptionManager.Title>WindowsApplication12</ExceptionManager.Title> <ExceptionManager.MachineName>GRAPECITY-TONY</ExceptionManager.MachineName> <ExceptionManager.TimeStamp>2006-4-26 21:35:22</ExceptionManager.TimeStamp> <ExceptionManager.FullName>WindowsApplication12, Version=1.0.2307.37434, Culture=neutral, PublicKeyToken=null</ExceptionManager.FullName> <ExceptionManager.AppDomainName>WindowsApplication12.exe</ExceptionManager.AppDomainName> <ExceptionManager.ThreadIdentity /> <ExceptionManager.WindowsIdentity>GRAPECITY-TONY\Tony</ExceptionManager.WindowsIdentity> </AdditionalInformationProperty> - <Exception> <ExceptionType>System.NullReferenceException</ExceptionType> <Message>Object reference not set to an instance of an object.</Message> <TargetSite>Void Form1_Load(System.Object, System.EventArgs)</TargetSite> <StackTrace>at WindowsApplication12.Form1.Form1_Load(Object sender, EventArgs e) in C:\Documents and Settings\Tony\My Documents\Visual Studio Projects\WindowsApplication12\Form1.vb:line 48</StackTrace> <Source>WindowsApplication12</Source> </Exception> </ExceptionInformation> </root>stackTrace中根据到了出错位置。 更近一步,我们可以创建一个xsl文件来把上述的xml文件格式化的更友好一些,这个下次有空在弄吧,先把异常处理类贴上来吧: Imports System.Xml Imports System.Collections.Specialized Imports System.IO Imports System.Security Imports System.Threading Imports System.Security.Principal![]() ![]() ''' ----------------------------------------------------------------------------- ''' Project : WindowsApplication12 ''' Class : ExceptionManager ''' ''' ----------------------------------------------------------------------------- ''' <summary> ''' 异常管理类 ''' </summary> ''' <remarks> ''' 根据日期,在指定xml文件中写入异常记录 ''' </remarks> ''' <history> ''' [Tony] 2006-4-26 Created ''' </history> ''' -----------------------------------------------------------------------------![]() Public NotInheritable Class ExceptionManagerClass ExceptionManager![]() Private Shared EXCEPTIONMANAGER_NAME As String = GetType(ExceptionManager).Name Private Shared EXCEPTIONMANAGEMENT_CONFIG_SECTION As String = "exceptionManagement" Private Shared EXCEPTIONLOG_DIRECTORY As String = "Exception Log" Private Shared RES_EXCEPTIONMANAGEMENT_PERMISSION_DENIED As String = "The event source {0} does not exist and cannot be created with the current permissions." Private Shared RES_EXCEPTIONMANAGEMENT_INFOACCESS_EXCEPTION As String = "ExceptionManagerInternalException" Private Shared EXCEPTIONMANAGER_ERROR_ON_SAVE = "The error log can not saved on the disk."![]() ![]() ![]() Constructor#Region "Constructor "![]() ''' ----------------------------------------------------------------------------- ''' <summary> ''' 私有构造函数 ''' </summary> ''' <remarks> ''' 不让定义instance ''' </remarks> ''' <history> ''' [Tony] 2006-4-26 Created ''' </history> ''' -----------------------------------------------------------------------------![]() Private Sub New()Sub New() End Sub 'New![]() #End Region![]() ![]() Public Methods#Region "Public Methods "![]() ''' ----------------------------------------------------------------------------- ''' <summary> ''' 异常处理方法 ''' </summary> ''' <param name="exception">传入异常</param> ''' <remarks> ''' </remarks> ''' <history> ''' [Tony] 2006-4-26 Created ''' </history> ''' -----------------------------------------------------------------------------![]() Public Overloads Shared Sub Publish()Sub Publish(ByVal exception As Exception) Publish(exception, System.Windows.Forms.Application.ProductName) End Sub![]() ![]() ''' ----------------------------------------------------------------------------- ''' <summary> ''' overload异常处理方法 ''' </summary> ''' <param name="exception">传入异常</param> ''' <param name="caption">传入要显示的title</param> ''' <remarks> ''' </remarks> ''' <history> ''' [Tony] 2006-4-26 Created ''' </history> ''' -----------------------------------------------------------------------------![]() Public Overloads Shared Sub Publish()Sub Publish(ByVal exception As Exception, _ ByVal caption As String)![]() ![]() Try '写入log writeExceptionToLogFile(exception, caption)![]() '调试状态直接显示异样,否则显示友好的错误提示 '#If Not Debug Then MessageBox.Show("出现问题,请联系管理员!", caption, MessageBoxButtons.OK, MessageBoxIcon.Error) '#Else ' MessageBox.Show(exception.ToString) '#End If Catch![]() ![]() End Try![]() End Sub![]() #End Region![]() ![]() Private Methods#Region "Private Methods"![]() ''' ----------------------------------------------------------------------------- ''' <summary> ''' 写log方法 ''' </summary> ''' <param name="exception">传入异常</param> ''' <param name="caption">传入title</param> ''' <remarks> ''' </remarks> ''' <history> ''' [Tony] 2006-4-26 Created ''' </history> ''' -----------------------------------------------------------------------------![]() Private Shared Sub writeExceptionToLogFile()Sub writeExceptionToLogFile(ByVal exception As Exception, ByVal caption As String) '定义log文件路径 Dim logPath As String = getLogPath()![]() '定义exception XML,调用SerializeToXML方法,把本次exception的信息组织起来,然会返回给newDoc Dim newDoc As XmlDocument = SerializeToXML(exception, CreateAdditionalInfo(caption))![]() '定义要输出到xml的文本 Dim outString As String![]() '定义log里也有的历史记录 Dim oldDoc As New XmlDocument![]() '如果已有log文件,则读取内容 If File.Exists(logPath) Then oldDoc.Load(logPath)![]() '把root节点下的内容读取出来 Dim oldExceptionContent As String![]() If Not oldDoc Is Nothing AndAlso _ Not oldDoc.ChildNodes Is Nothing AndAlso _ oldDoc.ChildNodes.Count = 1 Then oldExceptionContent = oldDoc.ChildNodes(0).InnerXml End If![]() '要输出到xml的文本 outString = "<root>" & _ oldExceptionContent & _ newDoc.InnerXml & _ "</root>"![]() '写入文件 Dim fs As FileStream = File.Open(logPath, FileMode.OpenOrCreate, FileAccess.ReadWrite) Dim writer As StreamWriter = New StreamWriter(fs) writer.Write(outString) writer.Close() fs.Close() End Sub![]() ''' ----------------------------------------------------------------------------- ''' <summary> ''' 获取log文件路径 ''' </summary> ''' <returns>返回log文件具体路径</returns> ''' <remarks> ''' 返回值类似于:Exception Log\2006-02-26-log.xml ''' </remarks> ''' <history> ''' [Tony] 2006-4-26 Created ''' </history> ''' -----------------------------------------------------------------------------![]() Private Shared Function getLogPath()Function getLogPath() As String![]() '根据日期得到文件组成部分 Dim file_prfix As String = Now.ToString("yyyy-MM-dd")![]() '找存放log文件的目录,无则创建 If Not Directory.Exists(EXCEPTIONLOG_DIRECTORY) Then Directory.CreateDirectory(EXCEPTIONLOG_DIRECTORY) End If![]() '返回 Return EXCEPTIONLOG_DIRECTORY + "\" + file_prfix + "-log.xml" End Function![]() ''' ----------------------------------------------------------------------------- ''' <summary> ''' 获取附加信息 ''' </summary> ''' <param name="caption">title</param> ''' <returns>返回一些AdditionalInfo的集合</returns> ''' <remarks> ''' 该集合主要是当前电脑的一些信息,比如操作系统等 ''' </remarks> ''' <history> ''' [Tony] 2006-4-26 Created ''' </history> ''' -----------------------------------------------------------------------------![]() Private Shared Function CreateAdditionalInfo()Function CreateAdditionalInfo(ByVal caption As String) As NameValueCollection![]() Dim additionalInfo As New NameValueCollection![]() additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".Title", caption)![]() Try additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".MachineName", Environment.MachineName)![]() Catch e As SecurityException additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".MachineName", RES_EXCEPTIONMANAGEMENT_PERMISSION_DENIED) Catch additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".MachineName", RES_EXCEPTIONMANAGEMENT_INFOACCESS_EXCEPTION) End Try![]() Try additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".TimeStamp", DateTime.Now.ToString()) Catch e As SecurityException additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".TimeStamp", RES_EXCEPTIONMANAGEMENT_PERMISSION_DENIED) Catch additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".TimeStamp", RES_EXCEPTIONMANAGEMENT_INFOACCESS_EXCEPTION) End Try![]() Try additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".FullName", Reflection.Assembly.GetExecutingAssembly().FullName)![]() Catch e As SecurityException additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".FullName", RES_EXCEPTIONMANAGEMENT_PERMISSION_DENIED) Catch additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".FullName", RES_EXCEPTIONMANAGEMENT_INFOACCESS_EXCEPTION) End Try![]() Try additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".AppDomainName", AppDomain.CurrentDomain.FriendlyName) Catch e As SecurityException additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".AppDomainName", RES_EXCEPTIONMANAGEMENT_PERMISSION_DENIED) Catch additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".AppDomainName", RES_EXCEPTIONMANAGEMENT_INFOACCESS_EXCEPTION) End Try![]() Try additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".ThreadIdentity", Thread.CurrentPrincipal.Identity.Name) Catch e As SecurityException additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".ThreadIdentity", RES_EXCEPTIONMANAGEMENT_PERMISSION_DENIED) Catch additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".ThreadIdentity", RES_EXCEPTIONMANAGEMENT_INFOACCESS_EXCEPTION) End Try![]() Try additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".WindowsIdentity", WindowsIdentity.GetCurrent().Name) Catch e As SecurityException additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".WindowsIdentity", RES_EXCEPTIONMANAGEMENT_PERMISSION_DENIED) Catch additionalInfo.Add(EXCEPTIONMANAGER_NAME + ".WindowsIdentity", RES_EXCEPTIONMANAGEMENT_INFOACCESS_EXCEPTION) End Try![]() Return additionalInfo![]() End Function![]() ''' ----------------------------------------------------------------------------- ''' <summary> ''' 组织xml方法 ''' </summary> ''' <param name="exception">传入异常</param> ''' <param name="additionalInfo">传入附加信息集合</param> ''' <returns></returns> ''' <remarks> ''' </remarks> ''' <history> ''' [Tony] 2006-4-26 Created ''' </history> ''' -----------------------------------------------------------------------------![]() Private Shared Function SerializeToXML()Function SerializeToXML(ByVal exception As Exception, _ ByVal additionalInfo As NameValueCollection) As XmlDocument![]() Try '定义1个根节点,2个子节点的名称 Dim xmlNodeName_ROOT As String = "ExceptionInformation" Dim xmlNodeName_ADDITIONAL_INFORMATION As String = "AdditionalInformationProperty" Dim xmlNodeName_EXCEPTION As String = "Exception"![]() '定义一个xml文档 Dim xmlDoc As New XmlDocument![]() '写入根节点 Dim xmlRoot As XmlElement = xmlDoc.CreateElement(xmlNodeName_ROOT) xmlDoc.AppendChild(xmlRoot)![]() '写入2个子节点 Dim xmlChild1 As XmlElement = xmlDoc.CreateElement(xmlNodeName_ADDITIONAL_INFORMATION) xmlRoot.AppendChild(xmlChild1) Dim xmlChild2 = xmlDoc.CreateElement(xmlNodeName_EXCEPTION) xmlRoot.AppendChild(xmlChild2)![]() '定义节点下的元素 Dim element As XmlElement '元素值 Dim elementText As XmlText![]() '把附加信息集合的所有项目,都加入的子节点"AdditionalInformationProperty"下. If Not (additionalInfo Is Nothing) AndAlso additionalInfo.Count > 0 Then Dim i As String For Each i In additionalInfo element = xmlDoc.CreateElement(i.Replace(" ", "_"))![]() elementText = xmlDoc.CreateTextNode(additionalInfo.Get(i))![]() element.AppendChild(elementText) xmlChild1.AppendChild(element) Next i End If![]() '把异常的一些详细信息都加入到子节点"Exception"下 If Not (exception Is Nothing) Then '先加入"ExceptionType"元素 element = xmlDoc.CreateElement("ExceptionType") elementText = xmlDoc.CreateTextNode(exception.GetType().FullName) element.AppendChild(elementText) xmlChild2.AppendChild(element)![]() '加入"Message","TargetSite","Source","StackTrace"4个元素 For Each p As System.Reflection.PropertyInfo In exception.GetType().GetProperties() If p.Name = "Message" OrElse p.Name = "TargetSite" OrElse _ p.Name = "Source" OrElse p.Name = "StackTrace" Then![]() If Not (p.GetValue(exception, Nothing) Is Nothing) Then element = xmlDoc.CreateElement(p.Name) elementText = xmlDoc.CreateTextNode(p.GetValue(exception, Nothing).ToString()) element.AppendChild(elementText) xmlChild2.AppendChild(element) End If End If Next![]() End If![]() '返回 Return xmlDoc![]() Catch e As Exception![]() End Try![]() End Function #End Region![]() End Class![]() ![]() 里面注释已经写的挺清楚了,就不多加解释了。 现在看看我们怎么调用这个shared方法,我们可以在try.....catch.....代码中调用它,如下: ![]() Private Sub Form1_Load()Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Try Dim a As String = Nothing Dim b As Int16 = a.Length Catch ex As Exception ExceptionManager.Publish(ex) End Try End Sub运行该form1窗体,将提示如下错误提示窗体: 程序员问答社区,解决您的IT难题
|
![]() |
|
| Copyright © Tony.Gong | Powered by: 博客园 模板提供:沪江博客 |