2011年10月10日 星期一

ASP.NET MVC + ELMAH 監控並記錄你的網站錯誤資訊 3

前兩篇有關於ELMAH的文章中介紹了了如何安裝以及如何做權限設定的修改,這一篇就來說明一下如何讓ELMAH在記錄錯誤也同時發出Email通知特定的人員,畢竟有錯誤發生時,如果可以即時的將訊息通知給特定人員(WebMaster or PM or Developer),對於錯誤狀況的掌握會更加迅速(對於開發人員來說,比客戶早一點知道總是比較好吧)。


ELMAH的信件通知設定

透過NuGet安裝ELMAH後,會自動在Web.Config加入ErrorMail的設定:

configSections區段:

  <configSections>
    <sectionGroup name="elmah">
      <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
      <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
      <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
      <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
    </sectionGroup>
  </configSections>

System.Web區段的httpModules:

    <httpModules>
      <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
      <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
      <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
    </httpModules>
    <httpHandlers>
      <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
    </httpHandlers>
  </system.web>
system.webServer區段:
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true">
      <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
      <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" />
      <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler" />
    </modules>
    <handlers>
      <add name="Elmah" path="/elmah.axd" verb="POST,GET,HEAD" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" />
    </handlers>
  </system.webServer>

 

而為了可以讓ELMAH發出EMAIL通知,接下來就要修改一下Web.Config中elmah區段的設定,

這是原本的設定部分:

  <elmah>
    <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data/Elmah.Errors" />
    <security allowRemoteAccess="yes" />
  </elmah>

而我們就要在這個區段去增加errorMail的設定:

  <elmah>
    <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data/Elmah.Errors" />
  <security allowRemoteAccess="yes" />
  <errorMail
    from="寄出的Email"
    to="收信的Email"
    subject="通知信件的主旨"
    async="true"
    smtpPort="0"
    useSsl="true"/>
  </elmah>

errorMail的to屬性,也可以設定多組的收信Email,使用「;」分號或是「,」逗號相隔就可以了,而errorMail的屬性設定可以瀏覽ELMAH的Wiki的說明:

Elmah Wiki – Configuring error notifictions

 

而除了elamh區段的errorMail設定外,也需要另外去在Web.Config中增加system.net的mailSettings資料,下面的設定中,我是設定要透過Gmail來做發出信件,

  <system.net>
    <mailSettings>
      <smtp deliveryMethod="Network">
        <network 
          host="smtp.gmail.com"
          port="587"
          userName="你的帳號@gmail.com"
          password="你的Gmail的密碼" />
      </smtp>
    </mailSettings>
  </system.net>

這樣一來,只要ELMAH有記錄到錯誤就會同時發出信件通知,下圖就是我在outlook中收到的錯誤訊息通知,

image

看看信件內容,

image

image

image

 

favicon.ico錯誤排除

然而有些錯誤是我們不希望讓Elamh給記錄起來甚至是發出Email通知,最經常看到的就是找不到favicon.ico的錯誤,因為現在的瀏覽器都會預設去載入favicon.ico,要是找不到的話就會被記錄為404錯誤,

image

image

這真的是……有點莫名其妙,所以以下的方式可以將這個不算是錯誤的錯誤給過濾掉,

首先去修改Web.Config,就是在elmah區段去增加errorFilter的設定,

    <errorFilter>
      <test>
        <!-- do not log favicon.ico 404's -->
        <and>
          <equal binding="HttpStatusCode" value="404" type="Int32" />
          <regex binding="Context.Request.ServerVariables['URL']" pattern="/favicon\.ico(\z|\?)" />
        </and>
      </test>
    </errorFilter>

另外也可以在Global.asax的RegisterRoutes()方法中再去增加一組routes.IgnoreRoute()

    public static void RegisterRoutes(RouteCollection routes)
    {
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
      routes.IgnoreRoute("ErrorAdmin/elmah.axd");
      routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

這樣一來就不會去記錄有關favicon.ico的404錯誤,而不會記錄這個錯誤就不會發出信件通知了。

 

不寄發404錯誤的信件通知

另外還有就是,或許有人不會喜歡一天到晚都收到404錯誤信件,畢竟打錯網址是常常會有的事情,這一種錯誤是需要記錄,但就不必發出信件通知了,所以我們可以在Global.asax中增加ErrorMail_Filtering()方法,

public void ErrorMail_Filtering(object sender, ExceptionFilterEventArgs e)
{
    var httpException = e.Exception as HttpException;
    if (httpException != null && httpException.GetHttpCode() == 404)
    {
        e.Dismiss();
    }
}

 


參考網址:

 

以上

3 則留言:

  1. hi!
    首先感謝你的分享!
    想請教一個問題,我照你的步驟在專案中加入 ELMAH,可以正確的攔截 exception,也可以寫入 MSSQL
    佰唯獨mail 無法寄出,也得不到任何錯誤訊息,唯獨在 vs2015 訊息清單有下列訊息
    嚴重性 程式碼 說明 專案 檔案 行 隱藏項目狀態
    訊息 找不到元素 'elmah' 的結構描述資訊。 PowerTester_RESTful D:\google_ncu\Dev\PowerTester_Restful\PowerTester_RESTful\Web.config 128

    嚴重性 程式碼 說明 專案 檔案 行 隱藏項目狀態
    訊息 找不到元素 'errorMail' 的結構描述資訊。 PowerTester_RESTful D:\google_ncu\Dev\PowerTester_Restful\PowerTester_RESTful\Web.config 135

    嚴重性 程式碼 說明 專案 檔案 行 隱藏項目狀態
    訊息 找不到屬性 'from' 的結構描述資訊。 PowerTester_RESTful D:\google_ncu\Dev\PowerTester_Restful\PowerTester_RESTful\Web.config 135
    ....
    不知是否有關係?

    回覆刪除
    回覆
    1. 說實在的,你只有將你的錯誤訊息給我,我怎麼會知道你的 web.config 是哪邊出問題呢?
      我又不是有天眼通
      錯誤訊息裡有提到「errorMail」,你再仔細看看你的 web.config 裡有沒有 errorMail 的內容,就是這篇文章所寫的,在 web.config 裡一定要有那些設定資料呀

      刪除
  2. 您好:
    感謝您的教學文章,真的是受益良多
    在這邊有個問題請教您
    在Web.Config中增加system.net的mailSettings之後,執行發生錯誤 (HTTP Error 500.19)
    錯誤訊息是:
    無法讀取設定區段 'mailSettings',因為它缺少區段宣告

    不知道您之不知報原因是甚麼
    我所使用的版本為 .NET Framework 4
    謝謝!

    回覆刪除

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。