如何在 ASP.NET Web API 套用 ELMAH 錯誤紀錄模組 (2021 年版) | The Will Will Web

The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

如何在 ASP.NET Web API 套用 ELMAH 錯誤紀錄模組 (2021 年版)

之前寫過好幾篇跟 ELMAH 相關的文章,其中 如何在 ASP.NET MVC 4 套用 ELMAH 錯誤紀錄模組 這篇還沒有過時,但剛在看 如何在 ASP.NET Web API 套用 ELMAH 錯誤紀錄模組 這篇文章時發現,現在有更簡單的設定方法,所以特別撰文分享心得。

  1. 安裝 elmah 套件

    這個步驟將會安裝 ELMAH 核心的 elmah.corelibrary 套件,以及套用 ELMAH 必要的 Web.config 設定!

    Install-Package elmah
    

    預設套用的設定還不少,其中包含:

    三個 <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>
    

    一個 <system.webServer> 下的 validation 設定:

    <validation validateIntegratedModeConfiguration="false" />
    

    三個 <system.webServer> 下的 modules 設定:

    <modules>
      <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>
    

    一個 <elmah> 自訂組態設定,預設會使用記憶體來儲存錯誤記錄以及關閉遠端存取權限

    <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>
    
    <elmah>
      <!--
          See http://code.google.com/p/elmah/wiki/SecuringErrorLogPages for
          more information on remote access and securing ELMAH.
      -->
      <security allowRemoteAccess="false" />
    </elmah>
    

    一個 <location> 自訂路徑,設定 ELMAH 使用 /elmah.axd 路徑來查看錯誤記錄 (Web UI):

    <location path="elmah.axd" inheritInChildApplications="false">
      <system.web>
        <httpHandlers>
          <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
        </httpHandlers>
        <!--
          See http://code.google.com/p/elmah/wiki/SecuringErrorLogPages for
          more information on using ASP.NET authorization securing ELMAH.
    
        <authorization>
          <allow roles="admin" />
          <deny users="*" />
        </authorization>
        -->
      </system.web>
      <system.webServer>
        <handlers>
          <add name="ELMAH" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" />
        </handlers>
      </system.webServer>
    </location>
    
  2. 安裝 Elmah.Contrib.WebApi 套件

    這個套件主要提供你兩個類別:Elmah.Contrib.WebApi.ElmahHandleErrorApiAttributeElmah.Contrib.WebApi.ElmahExceptionLogger

    Install-Package Elmah.Contrib.WebApi
    

    其中 Elmah.Contrib.WebApi.ElmahHandleErrorApiAttribute 是一個 Action Filter (動作過濾器),幫助你記錄 Action 執行過程中的例外,如果 Action 回應 HTTP 狀態碼為 5xx 的話,也會一併記錄到 ELMAH 之中。這個類別的用法,是在 App_Start\WebApiConfig.csRegister() 方法中加入以下這行(你必須手動加入):

    config.Filters.Add(new ElmahHandleErrorApiAttribute());
    

    另一個 Elmah.Contrib.WebApi.ElmahExceptionLogger 則是用來替 ASP.NET Web API 註冊全域的 ExceptionLogger,用以紀錄整個站台所有與 ASP.NET Web API 相關的例外狀況。這個類別的用法,是在 App_Start\WebApiConfig.csRegister() 方法中加入以下這行(你必須手動加入):

    config.Services.Add(typeof(IExceptionLogger), new ElmahExceptionLogger());
    

    請記得引用兩個命名空間:

    using System.Web.Http.ExceptionHandling;
    using Elmah.Contrib.WebApi;
    

    這兩個不同的類別,通常不會一起使用,但還是要看狀況判斷。因為 ElmahHandleErrorApiAttribute 主要針對 API Action 做紀錄,而 ElmahExceptionLogger 則是實作了 ASP.NET Web API 的全域錯誤處理機制,詳見 Global Error Handling in ASP.NET Web API 2 官網文件說明。兩個都啟用的話,可能會重複記錄到相同的例外狀況。

  3. 如果你想把例外狀況都儲存成 XML 檔案的話,可以安裝 elmah.xml 套件即可

    Install-Package elmah.xml
    

    安裝這個套件的過程,會自動幫你建立一個 App_Data\Elmah.Errors 資料夾,並且幫你在 Web.config 加入一段 <elmah> 區段下的宣告:

    <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data/Elmah.Errors" />
    

    嚴正提醒:如果不打算看 ELMAH 的 Log,就把 Log 關閉,不要將 Log 一直累積在伺服器上,否則資料量過大可能會影響主機效能。參見: Windows 下的 TEMP 目錄中檔案過多會導致系統效能驟降

範例程式

本文範例程式與 Git 變更記錄都放在這裡: https://github.com/doggy8088/AspNetWebApiELMAH/commits/master

另外,由於 ELMAH 還有很多內建的功能,完整的範例可以從 sample web.config 取得。這裡我覺得最強大的功能,應該非 <errorFilter> 莫屬,關於錯誤過濾器的設定方式,我再找時間跟大家分享!

相關連結

  • ELMAH—Home

    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.