WinForm、ASP.NET、MVC記錄全域性錯誤日誌
阿新 • • 發佈:2018-12-07
之前我轉載了一篇“C#使用Log4Net記錄日誌”,但如果是錯誤日誌,則沒必要在每個方法裡面捕獲異常再記錄日誌,這時我們寫一個全域性的錯誤日誌記錄方法就行了,但這全域性到底應該寫在哪呢?
不同的專案寫的地方是不一樣的:WinForm、ASP.NET、MVC
WinForm:在Program.cs檔案裡
/// <summary> /// 應用程式的主入口點。 /// </summary> [STAThread] static void Main() { //處理未捕獲的異常 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); //處理UI執行緒異常 Application.ThreadException += Application_ThreadException; //處理非UI執行緒異常 AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; #region 應用程式的主入口點 Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); #endregion } //處理UI執行緒異常 static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) { Exception error = e.Exception as Exception; //記錄日誌 } //處理非UI執行緒異常 static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Exception error = e.ExceptionObject as Exception; //記錄日誌 }
ASP.NET:在Global.asax.cs檔案裡
void Application_Error(object sender, EventArgs e)
{
// 在出現未處理的錯誤時執行的程式碼
Exception error = Server.GetLastError().GetBaseException();
//記錄日誌
}
MVC:需要寫一個繼承HandleErrorAttribute的類,然後在檔案FilterConfig.cs裡新增過濾器
public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); //預設註冊全域性的錯誤處理的過濾器。 filters.Add(new MyExceptionFilterAttribute()); } } /// <summary> /// 自定義錯誤處理類 /// </summary> public class MyExceptionFilterAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { base.OnException(filterContext); //處理錯誤訊息 Exception error = filterContext.Exception; //記錄日誌 } }
最後,我們就可以自己寫一個方法,用Log4Net元件記錄錯誤日誌。
由於採用全域性記錄日誌,一般我們只建立一個log4net.ILog例項,因此在記錄日誌過於頻繁的時候,應該要考慮例項被其它執行緒佔用時無法記錄的問題。解決方法如下:
1、單執行緒中用鎖。這種方法容易造成鎖等待從而造成資源浪費。
2、在每個配置檔案每個appender節點裡面新增
<!--記錄日誌寫入檔案時,不鎖定文字檔案,防止多執行緒時不能寫Log,官方說執行緒非安全-->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
3、把多執行緒轉為單執行緒:採用資料庫佇列。先把日誌記錄進資料庫佇列,再每隔一段時間把佇列的資訊記錄成檔案,記錄後清空佇列