ASP.NET 排程模組 - Hangfire 有個蠻酷的功能,能偵測專案是否已啟用 Serilog、NLog、Log4Net、EntLib Logging、Loupe 或 Elmah 等 Log 程式庫,一旦發現會自動寫入 Log。但大多時候 Hangfire 穩定執行,這堆用不到的 Log 便顯得喧賓奪主:

幾乎所有 Log 機制都有所謂的 LogLevel,區分為 Trace、Debug、Information、Warn、Error、Critical... 等不同等級。借用微軟的定義說明各等級的適用場合:

  • None/Off
    不記錄
  • Trace
    包含最詳細訊息的記錄,訊息可能包含敏感性應用程式資料。預設停用,且永遠不應在生產環境中啟用。
  • Debug
    開發期間用於互動式調查用,主要包含用於偵錯的資訊,不具備任何長期價值。
  • Information/Info
    追蹤應用程式一般流程的記錄,應具備長期價值。
  • Warning
    醒目提示應用程式異常或未預期事件,但這些異常或未預期事件不會造成應用程式執行停止。
  • Error
    在目前執行流程因失敗而停止時進行醒目提示的記錄,記錄應著重目前活動的失敗資訊細節,而非整個應用程式的失敗。
  • Critical/Fatal
    描述無法復原的應用程式或系統損毀,或需要立即注意重大失敗的記錄。

NLog 或 Serilog 都支援針對個別來源設定不同詳細等級,以 NLog 為例,可利用 Logger Name Filter 在 NLog.config 指定 Hangfire.* 項目不記錄 Warn 等級(含)以下 Log (僅記錄 Error 跟 Fatal 等級)。而其他程式用的 Log 則維持 Trace,留存最多訊息以利偵錯。

其做法是在原本的 logger name="*" 上方多加一條 <logger name="Hangfire.*" maxlevel="Warn" final="true" />, name="Hangfire.*" 指明這條規則適用 Logger 名稱以 Hangfire 起始的記錄,maxlevel="Warn" 限定等級在 Warn 以下,因這條規則未指定 writeTo,故記錄將會被導向黑洞直接丟棄,final="true" 代表符合本規則就不再執行後續規則。若非 Hangfire 的 Log,或 Hangfire.* Level 為 Error/Fatal,則不適用第一條規則,依原本 name="*" 規則,輸出到 f Target:

  <rules>
    <logger name="Hangfire.*" maxlevel="Warn" final="true" />
    <logger name="*" minlevel="Trace" writeTo="f" />
  </rules>

很簡單的小技巧,剛好拿 Hangfire 當案例來練習,好用!

Exmaple of how to use NLog logger name filter to set different log level for specific logs.


Comments

# by ChrisTorng

漏列 Warn?

# by Jeffrey

to ChrisTorng,感謝提醒,已補上。

Post a comment