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();
    }
}

 


參考網址:

 

以上

沒有留言:

張貼留言

提醒

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

最近的留言