文章目錄
讓 log4net 收到指定錯誤 Level 發送 mail
平常我自己本身慣用的 log 套件是 nlog,主要原因是因為設定相對較簡潔,加上多年前看過的效能比較 - Benchmarking 5 popular .NET logging libraries 結果是 nlog 效能較好,不過前陣子看到另一篇文章 - .Netcore之日誌組件Log4net、Nlog性能比較 重新比較 nlog 與 log4net 的效能則得出 log4net 效能較好的結論,所以針對兩者效能問題我想自己動手比較看看,再下結論
在取得效能比較結論前之前,因緣際會下需要調整其他同事的專案,剛好是使用 log4net,所以透過這個機會紀錄一下使用方式
BTW:原本想要大致紀錄一下 log4net 的相關設定及用法,但文件愈看愈多卻也愈搞不清楚設定細節,決定改天有需要時再另外紀錄,今天就只紀錄如何讓 log4net 發出 mail 囉
基本設定
以下範例會將 log4net 設定與 application config (app.config 或是 web.config) 放在一起
加入 log4net 的 configSection
讓程式可以利用指定的 log4net handler 來處理 log4net config 區塊
<configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> </configSections>
加入 log4net 相關設定
log4net 區段的組成內容
appender
允許零個或多個,用來設定 log 輸出的實際對象:file、mail、console…etc,實際輸出訊息的格式也設定於此
logger
允許零個或多個,預設會繼承 root 的參數設定,程式指定 logger name,再經由 logger 設定分派給 appender 處理
renderer
允許零個或多個,透過實作 log4net.ObjectRenderer.IObjectRenerer 來客製化 log 輸出
root
允許零個或一個,logger 最上層的參數,會被所有 logger 繼承
param
允許零個或多個,用來指定 log4net 全域用參數
<log4net> <appender name="SmtpAppender" type="log4net.Appender.SmtpAppender"> <to value="[email protected]" /> <from value="[email protected]" /> <subject value="test logging message" /> <smtpHost value="127.0.0.1" /> <bufferSize value="512" /> <lossy value="false" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" /> </layout> </appender> <logger name="UserQuery"> <level value="DEBUG" /> <appender-ref ref="SmtpAppender" /> </logger> </log4net>
實際使用
//建立 logger var log = LogManager.GetLogger(this.GetType()); //讀取 log4net 相關設定 XmlConfigurator.Configure(); // 開始寫 log log.Debug("Test Debug"); log.Info("Test Info"); log.Warn("Test Warn"); log.Error("Test Error"); log.Fatal("Test Fatal");
log 設定說明
logger
name
屬性需與程式中所指定的 logger 相同
手動指定 logger 名稱
var log = LogManager.GetLogger("UserQuery");
使用當前 class 的名稱
method 1 :
var log = LogManager.GetLogger(this.GetType());
method 2:
var log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
level
元素指定最低 log 等級 ,會覆寫
root
設定appender-ref
元素指定使用的 appender
SmtpAppender
to
,from
,subject
與smtpHost
是必要條件to
mail 對象
from
送出的 mail
subject
mail 主旨
smtpHost
mail server 位址
bufferSize
緩衝區大小
lossy
用來設定是否可以允許資料遺失,只在繼承自
BufferingAppenderSkeleton
的 appender 出現,SmtpAppender 是其一,預設是false
(避免資料不見); 如設為true
需搭配evaluator
設定,緩衝區滿時會將最舊的 log 刪除使用預設值 –> 要特別注意,這樣的設定不會立即發送,需待 bufferSize 滿了才統一發送,可以將 bufferSize 設為
1
即會立即發送<log4net> <appender name="SmtpAppender" type="log4net.Appender.SmtpAppender"> <to value="[email protected]" /> <from value="[email protected]" /> <subject value="fail message" /> <smtpHost value="127.0.0.1" /> <bufferSize value="512" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" /> </layout> </appender> <logger name="UserQuery"> <level value="DEBUG" /> <appender-ref ref="SmtpAppender" /> </logger> </log4net>
結果
evaluator
threshold
在
threshold
指定觸發發送 mail 的 level (含以上 level)
低於
threshold
指定 level 的 log 都會先存在緩衝區,直到指定 level 事件出現在一併將緩衝區的 log 輸出實例設定
<log4net> <appender name="SmtpAppender" type="log4net.Appender.SmtpAppender"> <to value="[email protected]" /> <from value="[email protected]" /> <subject value="fail message" /> <smtpHost value="127.0.0.1" /> <bufferSize value="512" /> <lossy value="true" /> <evaluator type="log4net.Core.LevelEvaluator"> <threshold value="ERROR" /> </evaluator> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" /> </layout> </appender> <logger name="UserQuery"> <level value="DEBUG" /> <appender-ref ref="SmtpAppender" /> </logger> </log4net>
結果
如何限定只處理特定 level
方法一: 透過
filter
將levelMin
與levelMax
都指定為ERROR
<log4net> <appender name="SmtpAppender" type="log4net.Appender.SmtpAppender"> <to value="[email protected]" /> <from value="[email protected]" /> <subject value="fail message" /> <smtpHost value="127.0.0.1" /> <bufferSize value="512" /> <lossy value="true" /> <evaluator type="log4net.Core.LevelEvaluator"> <threshold value="ERROR" /> </evaluator> <filter type="log4net.Filter.LevelRangeFilter"> <levelMin value="ERROR" /> <levelMax value="ERROR" /> </filter> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" /> </layout> </appender> <logger name="UserQuery"> <level value="DEBUG" /> <appender-ref ref="SmtpAppender" /> </logger> </log4net>
方法二:透過
filter
將levelToMatch
指定為ERROR
並加上DenyAllFilter
<log4net> <appender name="SmtpAppender" type="log4net.Appender.SmtpAppender"> <to value="[email protected]" /> <from value="[email protected]" /> <subject value="fail message" /> <smtpHost value="127.0.0.1" /> <bufferSize value="512" /> <lossy value="true" /> <evaluator type="log4net.Core.LevelEvaluator"> <threshold value="ERROR" /> </evaluator> <filter type="log4net.Filter.LevelMatchFilter,log4net"> <levelToMatch value="ERROR" /> </filter> <filter type="log4net.Filter.DenyAllFilter" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" /> </layout> </appender> <logger name="UserQuery"> <level value="DEBUG" /> <appender-ref ref="SmtpAppender" /> </logger> </log4net>
心得
不得不說 log4net 還真不是我的菜呀,功能也許很強大很彈性,但是文件實在令人不敢恭維,想要達到特定功能貌似許多做法,但卻好像遶了一大圈:我只想在 ERROR 時寄送 mail ,level 包含 FATAL 都不經由 mail,我反覆測試了好多種組合才真正解決問題,或許是我資質駑鈍,雖然經過這次經驗後我日後應該可以快速想到做法,但如果這樣簡單的需求都要讓入門者花那麼多時間嘗試,我想這樣的使用者體驗並不合格
參考資訊
文章作者 Yowko Tsai
上次更新 2021-11-02
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。