博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

ASP.NET 项目收集详细错误信息的一种方法

Posted on 2010-09-14 23:19  moss_tan_jun  阅读(554)  评论(0编辑  收藏  举报

 

 

在项目运维过程中,常常出现客户描述某个错误,无法说得很清楚,通常这种情况下,建议客户截图发给我们看,然后“看图说话”来答复错误,但是这么做,常常有个问题,是无法知道当时到底哪个地址,从那个IP,操作的具体哪个URL,都传递了什么参数,具体的错误是什么引起的。如果能记录下详细的错误环境相关的一些信息,以备运维和开发人员去查询问题,那就太方便了。于是我就想起来在我的应用中做这么一个小模块。实现随时可以查询到位所有的错误的详细信息(包括发生错误的时间、IP地址、错误记录、URL地址、详细错误信息)如下图所示:甚至我通过我的一个WebBrowser框架浏览此业务系统,自动截取当时系统的截图,这样能在业务部门及时没有发现错误的时候,也做到心里有数。

 

下面介绍一下实现方法:

1.在Global.asax代码文件中,添加如下函数

代码
 1  protected void Application_Error(object sender, EventArgs e)
 2         {
 3             try
 4             {
 5                 Exception objErr = Server.GetLastError().GetBaseException();
 6                 string err = "Error Caught in Application_Error event" +
 7                              "\nError in:" + Request.Url +
 8                              "\nError Message:" + objErr.Message +
 9                              "\nStack Trace:" + objErr.StackTrace +
10                              "\nSource Ip:" + Request.UserHostAddress;
11                 const string eventSource = "XXXX应用服务器";
12                 if (!EventLog.SourceExists(eventSource))
13                     EventLog.CreateEventSource(eventSource,eventSource);
14                 EventLog.WriteEntry(eventSource, err, EventLogEntryType.Error);
15                 //Server.ClearError();
16             }
17             catch (Exception exception)
18             {
19                 sysConfig.PLog("Sys""", exception.Message, "");
20             }
21             //在出现未处理的错误时运行的代码
22             Server.Transfer("~/Error.aspx");
23         }

 

 2.写一个Error.aspx作为标准页面,展示给用户看,另外在后台Error.aspx.cs处理错误的记录中主要处理错误代码如下:

错误处理代码
 1  #region 标准错误处理
 2             Exception objExp = HttpContext.Current.Server.GetLastError();
 3             objExp.Source = HttpContext.Current.Request.Url.ToString();
 4             //忽略采网际快车或其他网络工具下载带有书签的HTTP请求导致的异常]
 5             if (HttpContext.Current.Request.Url.ToString().IndexOf("#"!= -1)
 6             {
 7                 //清除当前HTTP请求的所有错误
 8                 ToShowError(objExp, "您的请求是非法的,将被系统忽略");
 9                 HttpContext.Current.ClearError();
10                 return;
11             }
12 
13             //循环处理异常事件
14             for (Exception TempException = objExp; TempException != null; TempException = TempException.InnerException)
15             {
16                 #region 如果系统检测到非法字符,则提示并返回
17                 if (TempException.GetType().ToString() == "System.Web.HttpRequestValidationException")
18                 {
19                     //清除当前HTTP请求的所有错误
20                     ToShowError(TempException, "系统检测到您输入了非法字符");
21                     HttpContext.Current.ClearError();
22                     //返回
23                     return;
24                 }
25                 #endregion
26 
27                 #region 异常为内存溢出
28                 if (TempException.GetType().ToString() == "System.OutOfMemoryException")
29                 {
30                     //清除当前HTTP请求的所有错误
31                     ToShowError(TempException, "服务器资源耗尽,请稍候重试!");
32                     HttpContext.Current.ClearError();
33                     //返回
34                     break;
35                 }
36                 #endregion
37 
38                 #region 由SQLServer返回的警告或或错误引发的异常
39                 if (TempException.GetType().ToString() == "System.Data.SqlClient.SqlException")
40                 {
41                     byte ErrLevel = ((System.Data.SqlClient.SqlException)TempException).Class;
42                     int Number = ((System.Data.SqlClient.SqlException)TempException).Number;
43 
44                     //严重程度处理    [数据库服务器已经关闭] 
45                     //Number == 17  [SQL Server 不存在或访问被拒绝]
46                     //Number == 11  [常规网络错误。请检查您的网络文档]
47                     if (ErrLevel == 20 && (Number == 17 || Number == 11))
48                     {
49                         ToShowError(TempException, "数据库服务器已经关闭,请稍候重试!");
50                         //清除当前HTTP请求的所有错误
51                         HttpContext.Current.ClearError();
52                         //返回
53                         return;
54                     }
55 
56                     //严重程度处理 [数据库服务器正在关闭]
57                     //Number == 6002 [SHUTDOWN 正在进行。请注销]
58                     if (ErrLevel == 16 && Number == 6002)
59                     {
60                         ToShowError(TempException, "数据库服务器正在关闭,请稍候重试!");
61                         //清除当前HTTP请求的所有错误
62                         HttpContext.Current.ClearError();
63                         //返回
64                         return;
65                     }
66 
67                     //严重程度处理 [系统正在登陆数据库服务器]
68 
69 
70                     //输出
71                     ToShowError(TempException, "系统正在登陆数据库服务器,请稍候重试!");
72 
73                     //返回
74                     return;
75                 }
76                 #endregion
77 
78                 #region 框架异常
79                 if (TempException.GetType().ToString() == "System.Web.HttpUnhandledException")
80                 {
81                     if (TempException.InnerException != null)
82                     {
83                         ToShowError(TempException.InnerException, "框架异常!");
84                     }
85                     else
86                     {
87                         ToShowError(TempException, "框架异常");
88                     }
89                     HttpContext.Current.ClearError();
90                     return;
91                 }
92                 #endregion
93 
94                 //其他异常处理
95                 ToShowError(TempException, "");
96             }
97             #endregion

 

 基本工作就完成了。事实证明,收集错误,对于快速定位问题,分析问题,能极大的提高效率。另外,通过收集错误,才发现,以前认为不会出现问题的页面,其实在偶尔会因为url参数等问题,是会出错的,之前还经常欺负业务部门,说决定不可能出现这样的问题,但是如果自己有错误机制,就会在武断的说这个话之前,先去看下服务器里面记录的错误,会更客观。而不是说,现在无法定位问题,等你下次出现这个问题的时候,来告诉我,别管页面,我给你看。