使用處理異常的過濾器 HandleErrorAttribute
1.新建一個類繼承自 HandleErrorAttribute,然後重寫OnException這個方法
將錯誤信息寫入隊列中
public class MyExceptionAttribute : HandleErrorAttribute { public static Queue<Exception> ExecptionQueue = new Queue<Exception>(); /// <summary> /// 可以捕獲異常數據 /// </summary> /// <param name="filterContext"></param> public override void OnException(ExceptionContext filterContext) { base.OnException(filterContext); Exception ex = filterContext.Exception; //寫到隊列 ExecptionQueue.Enqueue(ex); //跳轉到錯誤頁面. filterContext.HttpContext.Response.Redirect("/Error.html"); } }
只要程序出錯就會執行這個方法。
2.註冊定義好的異常過慮器
打開App_Start文件夾中FilterConfig.cs修改
public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { // filters.Add(new HandleErrorAttribute()); filters.Add(new MyExceptionAttribute()); } }
驗證一下:在1中定義的過慮器的ex行打一個斷點,然後在控制器的action中增加一段出錯的代碼
public ActionResult Index() { int a = Convert.ToInt16("aaa"); return Content(a.ToString()); // return View(); }
運行可以看到效果:
3.開啓一個新的線程不斷的讀取隊列,通過Log4把消息寫入日誌文件
讀取消息應該在程序開始的時候就開始執行,在Global.asax.cs中添加代碼
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); //開啓一個線程,掃描異常信息隊列。 string filePath = Server.MapPath("/Log/"); ThreadPool.QueueUserWorkItem((a) => { while (true) { //判斷一下隊列中是否有數據 if (MyExceptionAttribute.ExecptionQueue.Count() > 0) { Exception ex=MyExceptionAttribute.ExecptionQueue.Dequeue(); if (ex != null) { //將異常信息寫到日誌文件中。 //string fileName = DateTime.Now.ToString("yyyy-MM-dd"); //File.AppendAllText(filePath+fileName+".txt",ex.ToString(),System.Text.Encoding.UTF8); ILog logger = LogManager.GetLogger("errorMsg"); logger.Error(ex.ToString()); } else { //如果隊列中沒有數據,休息 Thread.Sleep(3000); } } else { //如果隊列中沒有數據,休息 Thread.Sleep(3000); } } },filePath); }
4.配置Log4
1 <configuration> 2 <configSections> 3 <!--Log4Net配置--> 4 <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> 5 </configSections> 6 <log4net> 7 <!-- OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL --> 8 <!-- Set root logger level to ERROR and its appenders --> 9 <root> 10 <level value="ALL" /> 11 <appender-ref ref="SysAppender" /> 12 </root> 13 <!-- Print only messages of level DEBUG or above in the packages --> 14 <logger name="WebLogger"> 15 <level value="DEBUG" /> 16 </logger> 17 <appender name="SysAppender" type="log4net.Appender.RollingFileAppender,log4net"> 18 <!--文件路徑--> 19 <param name="File" value="App_Data/" /> 20 <!--文件追加--> 21 <param name="AppendToFile" value="true" /> 22 <!--備份類型--> 23 <param name="RollingStyle" value="Date" /> 24 <!--文件名稱--> 25 <param name="DatePattern" value=""Logs_"yyyyMMdd".txt"" /> 26 <!--是否固定名稱--> 27 <param name="StaticLogFileName" value="false" /> 28 <layout type="log4net.Layout.PatternLayout,log4net"> 29 <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" /> 30 <param name="Header" value=" ----------------------header-------------------------- " /> 31 <param name="Footer" value=" ----------------------footer-------------------------- " /> 32 </layout> 33 </appender> 34 <appender name="consoleApp" type="log4net.Appender.ConsoleAppender,log4net"> 35 <layout type="log4net.Layout.PatternLayout,log4net"> 36 <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" /> 37 </layout> 38 </appender> 39 </log4net> 40 <!--Log4Net配置結束--> 41 </configuration>