在Web應用運行過程中,我們難免會遇到程序運行異常,這個時候我們就應該將異常信息記錄下來,以便開發(fā)人員和維護人員對異常原因進行還原,對異常原因進行修復。在ASP.NET平臺中進行日志記錄的組件也有很多,如Log4Net、CommonLogging等,我們這里選用Log4Net進行異常日志的記錄。
1. 捕獲異常
在ASP.NET MVC中提供了一個全局的異常處理過濾器:HandleErrorAttribute,可以通過該過濾器捕獲異常信息。
我們在Models文件夾下新建類型Log4ExceptionAttribute,繼承HandleErrorAttribute類,同時重寫OnException方法來捕獲異常數(shù)據(jù):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
using System.Web.Mvc; namespace PMS.WebApp.Models { public class Log4ExceptionAttribute:HandleErrorAttribute { /// <summary> /// 重寫OnException方法來捕獲異常數(shù)據(jù) /// </summary> /// <param name="filterContext"></param> public override void OnException(ExceptionContext filterContext) { base .OnException(filterContext); //捕獲當前異常數(shù)據(jù) var ex = filterContext.Exception; } } } |
新建過濾器后我們還需要在Global文件中調用的RegisterGlobalFilters方法中完成自己定義異常處理過濾的注冊。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
using System.Web.Mvc; using PMS.WebApp.Models; namespace PMS.WebApp { public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { //filters.Add(new HandleErrorAttribute()); filters.Add( new Log4ExceptionAttribute()); } } } |
2. 考慮到多用戶并發(fā)操作時可能產生的問題,我們需要新建一個隊列來進行異常信息的暫存,同時開辟一個線程專門對隊列中的異常信息進行處理。
在Log4ExceptionAttribute類中新建一個靜態(tài)的異常類型的隊列,在發(fā)生異常后,程序自動觸發(fā)OnException方法,方法中將當前的異常信息入隊后,跳轉到錯誤頁面。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
using System; using System.Collections.Generic; using System.Web.Mvc; namespace PMS.WebApp.Models { public class Log4ExceptionAttribute:HandleErrorAttribute { public static Queue<Exception> Exceptions= new Queue<Exception>(); /// <summary> /// 重寫OnException方法來捕獲異常數(shù)據(jù) /// </summary> /// <param name="filterContext"></param> public override void OnException(ExceptionContext filterContext) { base .OnException(filterContext); //捕獲當前異常數(shù)據(jù) var ex = filterContext.Exception; //將異常數(shù)據(jù)入隊 Exceptions.Enqueue(ex); //跳轉到錯誤頁面 filterContext.HttpContext.Response.Redirect( "/Error.html" ); } } } |
Log4Net的配置是在應用程序配置文件中進行的,我們先在配置文件中進行Log4Net的配置。Log4Net需要配置的節(jié)點位置和SpringNet完全相同,首先需要在configSessions中新增子節(jié)點,然后在configuration節(jié)點中增加log4net節(jié)點完成具體配置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
<configuration> <configSections> <section name= "entityFramework" type= "System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission= "false" /> <!-- For more information on Entity Framework configuration, visit http: //go.microsoft.com/fwlink/?LinkID=237468 --> <!--↓Log4Net配置↓--> <section name= "log4net" type= "log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> <!--↑Log4Net配置↑--> <!--↓Spring.Net配置↓--> <sectionGroup name= "spring" > <section name= "context" type= "Spring.Context.Support.MvcContextHandler, Spring.Web.Mvc4" /> </sectionGroup> <!--↑Spring.Net配置↑--> </configSections> <!--↓Spring.Net配置↓--> <spring> <context> <resource uri= "file://~/Config/controllers.xml" /> <resource uri= "file://~/Config/services.xml" /> </context> </spring> <!--↑Spring.Net配置↑--> <!--↓Log4Net配置↓--> <log4net> <!-- OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL --> <!-- Set root logger level to ERROR and its appenders --> <root> <level value= "ALL" /> <appender- ref ref = "SysAppender" /> </root> <!-- Print only messages of level DEBUG or above in the packages --> <logger name= "WebLogger" > <level value= "DEBUG" /> </logger> <appender name= "SysAppender" type= "log4net.Appender.RollingFileAppender,log4net" > <param name= "File" value= "App_Data/" /> <param name= "AppendToFile" value= "true" /> <param name= "RollingStyle" value= "Date" /> <param name= "DatePattern" value= "" Logs_ "yyyyMMdd" .txt "" /> <param name= "StaticLogFileName" value= "false" /> <layout type= "log4net.Layout.PatternLayout,log4net" > <param name= "ConversionPattern" value= "%d [%t] %-5p %c - %m%n" /> <param name= "Header" value=" ----------------------header-------------------------- " /> <param name= "Footer" value=" ----------------------footer-------------------------- " /> </layout> </appender> <appender name= "consoleApp" type= "log4net.Appender.ConsoleAppender,log4net" > <layout type= "log4net.Layout.PatternLayout,log4net" > <param name= "ConversionPattern" value= "%d [%t] %-5p %c - %m%n" /> </layout> </appender> </log4net> <!--↑Log4Net配置↑--> ... </configuration> |
在配置文件中可以對日志記錄的信息、格式、文件名等作出具體的配置,下面是配置信息的詳解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
<? xml version = "1.0" ?> < configuration > < configSections > < section name = "log4net" type = "log4net.Config.Log4NetConfigurationSectionHandler,log4net" /> </ configSections > <!--站點日志配置部分--> < log4net > < root > <!--控制級別,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF--> <!--比如定義級別為INFO,則INFO級別向下的級別,比如DEBUG日志將不會被記錄--> <!--如果沒有定義LEVEL的值,則缺省為DEBUG--> < level value = "ERROR" /> < appender-ref ref = "RollingFileAppender" /> </ root > < appender name = "RollingFileAppender" type = "log4net.Appender.RollingFileAppender" > <!--日志文件名開頭--> < file value = "c:\Log\TestLog4net.TXT" /> <!--多線程時采用最小鎖定--> < lockingModel type = "log4net.Appender.FileAppender+MinimalLock" /> <!--日期的格式,每天換一個文件記錄,如不設置則永遠只記錄一天的日志,需設置--> < datePattern value = "(yyyyMMdd)" /> <!--是否追加到文件,默認為true,通常無需設置--> < appendToFile value = "true" /> <!--變換的形式為日期,這種情況下每天只有一個日志--> <!--此時MaxSizeRollBackups和maximumFileSize的節(jié)點設置沒有意義--> <!--<rollingStyle value="Date"/>--> <!--變換的形式為日志大小--> <!--這種情況下MaxSizeRollBackups和maximumFileSize的節(jié)點設置才有意義--> < RollingStyle value = "Size" /> <!--每天記錄的日志文件個數(shù),與maximumFileSize配合使用--> < MaxSizeRollBackups value = "10" /> <!--每個日志文件的最大大小--> <!--可用的單位:KB|MB|GB--> <!--不要使用小數(shù),否則會一直寫入當前日志--> < maximumFileSize value = "2MB" /> <!--日志格式--> < layout type = "log4net.Layout.PatternLayout" > < conversionPattern value = "%date [%t]%-5p %c - %m%n" /> </ layout > </ appender > </ log4net > </ configuration > |
在Global文件中的Application_Start方法中開啟一個線程,用于將隊列中的錯誤信息寫入日志文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
using System.Linq; using System.Threading; using System.Web.Http; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; using log4net; using PMS.WebApp.Models; using Spring.Web.Mvc; namespace PMS.WebApp { // 注意: 有關啟用 IIS6 或 IIS7 經(jīng)典模式的說明, // 請訪問 http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : SpringMvcApplication //HttpApplication { protected void Application_Start() { log4net.Config.XmlConfigurator.Configure(); //讀取Log4Net配置信息 AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //開啟一個線程,掃描異常信息隊列. var filePath = Server.MapPath( "/Log/" ); ThreadPool.QueueUserWorkItem((a) => { while ( true ) { //判斷隊列中是否有數(shù)據(jù) if (Log4ExceptionAttribute.Exceptions.Any()) { //出隊一條異常信息 var ex = Log4ExceptionAttribute.Exceptions.Dequeue(); //若異常信息不為空 if (ex == null ) continue ; //將異常信息寫入到日志文件中 var logger = LogManager.GetLogger( "errorMsg" ); logger.Error(ex.ToString()); } else { //若異常信息隊列為空,則線程休息三秒 Thread.Sleep(3000); } } }, filePath); } } } |
成功完成錯誤日志的配置。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/JiaoWoWeiZai/p/5877976.html