網站上線或是還在開發、測試階段時對於難以捉摸的錯誤總是讓開發人員頭痛不已,如果是在開發環境裡,還容易抓到錯誤,一旦上了測試機或是正式機之後,錯誤的發生就無法立即掌握,尤其是當客戶在測試的時候往往遇到錯誤就只會通知開發人員說「你的程式有 BUG!」,但是要問客戶說這些錯誤是怎麼發生的時候,客戶通常是說不清楚,甚至有的客戶明明操作錯誤或是輸入錯誤的資料而引發錯誤,但也不會老實跟開發人員說出實情,而如果可以任何時候都監控網站並且當錯誤發生的時候將當下的資訊給記錄下來的話,對於開發人員甚至是對於系統的功能完整、安全防護、減少 BUG 數等等都是一件好事。
網路上有很多種監控以及記錄的工具,然而眾多的工具、套件中最容易上手的應該就是 ELMAH 了,而且最重要的是,ELMAH 有提供 DashBoard 可以查看記錄的訊息,另外也可以透過遠端的方式去查看記錄,如此一來就可以更加容易掌握網站的一舉一動了(安全機制還是要先做好),就讓我們來看看如何在你的 ASP.NET MVC 3 網站中使用ELMAH 來監控並記錄錯誤訊息。
ELMAH
Error Logging Modules and Handlers
http://code.google.com/p/elmah/
ELMAH (Error Logging Modules and Handlers) is an application-wide error logging facility that is completely pluggable. It can be dynamically added to a running ASP.NET web application, or even all ASP.NET web applications on a machine, without any need for re-compilation or re-deployment.
Once ELMAH has been dropped into a running web application and configured appropriately, you get the following facilities without changing a single line of your code:
Logging of nearly all unhandled exceptions. A web page to remotely view the entire log of recoded exceptions. A web page to remotely view the full details of any one logged exception, including colored stack traces. In many cases, you can review the original yellow screen of death that ASP.NET generated for a given exception, even with customErrors mode turned off. An e-mail notification of each error at the time it occurs. An RSS feed of the last 15 errors from the log.
而官網的Wiki中則有一篇文件,說明如何在ASP.NET MVC網站中安裝並使用ELMAH,
http://code.google.com/p/elmah/wiki/MVC
其實整個安裝的步驟並不是很繁瑣,但這裡我則介紹如何在VS2010中使用NuGet安裝ELMAH。
Step.1
開啟你的ASP.NET MVC網站,並且開啟NuGet Packages Manager
於NuGet Packages Manager中去輸入ELMAH查詢相關套件
在這裡要安裝的有:
- ELMAH
- ELMAH Core Library(no config)
- ELMAH.MVC
- ELMAH on XML Log
ELMAH可以將訊息給記錄到很多的裝置上,不過在這裡我則是要把訊息記錄到XML文字檔中,記錄在XML文字檔中的好處是可以避免資料庫的連線錯誤問題,無法連線時也是可以記錄錯誤,缺點是錯誤記錄無法篩選,而記錄在資料庫的話則是可以使用資料庫來查詢特定的錯誤記錄。
安裝完成後,看看方案總管,增加了「~/App_Data/Elmah.Errors」「~/Areas/Admin/」
Step.2
利用NuGet安裝ELMAH的好處是,它會自動去增修Web.Config的Section,我們就不必手動去增加那些Section,
我們可以直接輸入「http://your-web-Url/Admin/ELMAH」就可以按到ELMAH的DashBoard
Step.3
接下來就是測試,輸入不存在的網頁或是執行有錯誤的Action等,看看是不是會把錯誤給記錄下來,
輸入一個不存在的網址
沒有輸入Parameter
執行一個會有Exception的Action
來看看ELMAH DashBoard
上圖看來,剛剛那些的錯誤黃頁都有把資訊給記錄下來,而我們挑一個Error來看看它的Details,
ELMAH都詳細了記錄錯誤發生的訊息以及當下執行的Server端與Client端的環境訊息,
Step.4
而使用了ELMAH後,我們可以記錄錯誤訊息,但是我們並不希望把錯誤黃頁就這樣直接顯示給使用者看到,除了說可以修改Web.Confg的customError的方式,將錯誤給導到特定頁面中,這邊我用別的方式,在Global.asax裡去增加Application_Error()方法,於發生錯誤時導到特定的網頁,
/// <summary>
/// Handles the Error event of the Application control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected void Application_Error(object sender, EventArgs e){var app = (MvcApplication)sender;var context = app.Context;var ex = app.Server.GetLastError();context.Response.Clear();context.ClearError();var httpException = ex as HttpException;
var routeData = new RouteData();
routeData.Values["controller"] = "Error";routeData.Values["exception"] = ex;
routeData.Values["action"] = "Index";if (httpException != null){switch (httpException.GetHttpCode())
{case 403:
routeData.Values["action"] = "Forbidden";break;
case 404:
routeData.Values["action"] = "PageNotFound";break;
case 500:
routeData.Values["action"] = "InternalError";break;
default:
routeData.Values["action"] = "GenericError";break;
}}// Pass exception details to the target error View.
routeData.Values.Add("Error", ex.Message);
// Avoid IIS7 getting in the middle
context.Response.TrySkipIisCustomErrors = true;
IController controller = new ErrorController();
controller.Execute(new RequestContext(new HttpContextWrapper(context), routeData));}
我這邊只有針對403, 404, 500的三個錯誤去導到特定的錯誤顯示頁面,而其他的錯誤則導到統一的頁面中,接下來就是建立ErrorController以及相對應的Action、ViewPage,
public class ErrorController : Controller{/// <summary>
/// Indexes the specified error.
/// </summary>
/// <param name="error">The error.</param>
/// <returns></returns>
public ActionResult Index(string error){ViewData["Title"] = "抱歉, 處理你的請求發生錯誤";ViewData["Description"] = error;
return View();
}/// <summary>
/// Generics the error.
/// </summary>
/// <param name="error">The error.</param>
/// <returns></returns>
public ActionResult GenericError(string error){ViewData["Title"] = "抱歉, 處理你的請求發生錯誤";ViewData["Description"] = error;
return View();
}/// <summary>
/// Forbiddens the specified error.
/// </summary>
/// <param name="error">The error.</param>
/// <returns></returns>
public ActionResult Forbidden(string error){return RedirectToAction("Index", "Home");}/// <summary>
/// Pages the not found.
/// </summary>
/// <param name="error">The error.</param>
/// <returns></returns>
public ActionResult PageNotFound(string error){ViewData["Title"] = "抱歉, 處理你的請求發生404錯誤";ViewData["Description"] = error;
Response.StatusCode = 404;return View();
}/// <summary>
/// Internals the error.
/// </summary>
/// <param name="error">The error.</param>
/// <returns></returns>
public ActionResult InternalError(string error){ViewData["Title"] = "抱歉, 處理你的請求發生500錯誤";ViewData["Description"] = error;
Response.StatusCode = 500;return View();
}}
這樣一來這些錯誤就會導到特定的頁面中,而ELMAH依然持續記錄錯誤訊息,
補充說明:
在 ErrorController 的 InternalError, GenericError, Index 這幾個 Action 裡會將錯誤訊息給放到 ViewData 中,然後在前端頁面上顯示,這樣的作法只適合在練習的時候使用,而一般實際的專案並不會直接將這些錯誤訊息給直接揭露於前端使用者可以看到的頁面上,因為這麼做的話是有可能會把系統的內部細節給暴露在外,所以千萬不要將錯誤訊息直接的顯示在頁面上讓使用者看到喔!
而我們來看看錯誤訊息是記錄的目錄「~/App_Data/Elmah.Errors」下的狀況,
ELMAH把每個錯誤記錄存成一個個的XML檔案。
好的,我們完成了在ASP.NET MVC中使用NuGet來安裝ELMAH的步驟了,但是還是有一些地方還沒有完成,應該有些人會發覺到,為什麼直接輸入「http://your – WebSite – URL/Admin/ELMAH」就可以看到錯誤的紀錄呢?要是就這樣放到網路上還得了,而透過Nuget安裝ELMAH.MVC後,會預設建立在Areas下的Admin,萬一我不想放在Areas的Admin下呢?
下一回再說…
參考連結:
elmah:Error Logging Modules and Handlers for ASP.NET
ELMAH: Error Logging Modules and Handlers for ASP.NET (and MVC too!)
ELMAH - Error Loggin Module and Handler For unhandled errors in asp.net
以上
HI 版主你好,這個好的擴充,
回覆刪除使用在 ASP.NET 也可以嗎?
Hello, Elmah當然也可以應用在ASP.NET WebForm上囉
刪除Elmah一開始就是提供給ASP.NET WebForm使用,早在2004年就已經發佈,
後來又增加「Elmah.MVC」組件給ASP.NET MVC來使用
http://code.google.com/p/elmah/
http://aspnet2share.blogspot.com/2011/11/nuget-nuget-msdn-nuget-visual-studio.html
http://msdn.microsoft.com/en-us/library/aa479332.aspx
請問我用visual studio 2012 Nuget 產生Elmah為何沒有自動產生~/Areas/Admin/資料夾呢?
回覆刪除單純安裝 Elmah 是不會另外建立~/Areas/Admin 目錄。
刪除上面的文章裡還包含要安裝「ELMAH.MVC」
舊版的 ELMAH.MVC 經由 NuGet 安裝後會建立 ~/Areas/Admin 目錄,
而新版的 ELMAH.MVC 已經改了方式,不會再建立 ~/Areas/Admin 目錄。
想請教一下,我設定至此出現很有趣的現象
回覆刪除只有404的時候頁面下面的畫面,整個error page的HTML被包在雙引號裡面呈現出來
(其他錯誤都正常導至該去的頁面)
http://imgur.com/a/Ccz1f
連結為HTML的截圖請安心服用
刪除在擷圖裡有看到 browserLink 的內容,你要不要先把 BrowserLink 功能關閉呢
刪除或者你先將程式發佈到測試環境或預備環境裡看看