在本文中,我想介紹一個簡單的解決方案,我們已經使用基于Stats4j和SMTPAppender的自定義Log4J Appender實現了(這比您預期的配置和故障排除更加困難)。
挑戰
我們在日志方面面臨以下挑戰:
- 不幸的是,有一定數量的例外情況是正常的(客戶選擇沒有結果的搜索條件,外部服務的暫時性,不重要的中斷等),因此我們當然不希望被發送垃圾郵件。 因此,解決方案必須具有可配置的閾值,并且僅在超出閾值時發送警報。
- 故障率應該在可配置的時間內進行計算(足夠長的時間不會因幾分鐘的中斷而觸發警報,而足夠短的時間可以在發生嚴重事件時盡快通知團隊)。
- 發送警報后,一段時間內(最好在解決原始問題之前)不應再發送其他警報,我們不希望因為我們已經知道的問題而被發送垃圾郵件。
解決方案
我們基于Lara D'Abreo的Stat4J解決方案,該解決方案提供了一個自定義Log4J附加程序,該附加程序使用日志來計算可配置的度量,并在超出警告或嚴重閾值時觸發警報。 它有幾年歷史了,具有alpha質量(關于通用性和靈活性)的開源庫,幸運的是,它足夠簡單,可以輕松地根據需要進行修改。
因此,我們對Stat4J進行了調整,以在警報數量超過閾值時生成警報,此后保持安靜,然后將其與Log4J SMTPAppender結合使用, 后者偵聽警報并將其通過電子郵件發送給團隊。
Stat4J調整
Stat4J的關鍵組件包括用于Log4J的Stat4jAppender,用于匯總單個日志的計算器(度量)(例如,通過對它們進行計數或從中提取一些數字),用于定義要通過正則表達式考慮的日志以及如何通過以下方式處理的統計信息:引用計算器,最后在統計信息的值超出其限制時發出警告,并記錄警告。 您可以在介紹Stat4J的文章中了解更多信息 。
我們已經實現了一個自定義的度量計算器, RunningRate (以計算最近N分鐘內的失敗數),并修改了Stat4J,如下所示:
- 我們增強了Alert來支持新屬性quietperiod,以便一旦觸發,隨后的警報將在該持續時間內被忽略(除非以前的警報只是警告,而新警報是關鍵警報)
- 我們修改了附加器, 將日志的Throwable與日志消息一起包含,然后將其傳遞給各個統計計算器,以便我們可以更精確地過濾要計數的內容
- 最后,我們修改了Alert,將警報記錄為錯誤而不是警告,以使SMTPAppender不會忽略它們
從GitHub (我們的源代碼或編譯的jar )中獲取我們修改后的Stat4j 。 免責聲明:這是一天的工作,我對代碼并不感到驕傲。
Stat4J配置
以stat4j.properties為例 ,并將其放在類路徑中。 它已經配置了正確的計算器,統計信息和警報。 看到這部分:
### JAKUB HOLY - MY CONFIG
calculator.minuteRate.classname=net.sourceforge.stat4j.calculators.RunningRate
# Period is in [ms] 1000 * 60 * 10 = 10 min:
calculator.minuteRate.period=600000statistic.RunningErrorRate.description=Errors per 10 minutes
statistic.RunningErrorRate.calculator=minuteRate
# Regular expression to match "<throwable.toString> <- <original log message>"
statistic.RunningErrorRate.first.match=.*Exception.*# Error Rate
alert.TooManyErrorsRecently.description=Too many errors in the log
alert.TooManyErrorsRecently.statistic=RunningErrorRate
alert.TooManyErrorsRecently.warn= >=3
alert.TooManyErrorsRecently.critical= >=10
alert.TooManyErrorsRecently.category=alerts
# Ignore following warnings (or criticals, after the first critical) for the given amount of time:
# 1000 * 60 * 100 = 100 min
alert.TooManyErrorsRecently.quietperiod=6000000
重要的配置參數是
- Calculator.minuteRate.period (以毫秒為單位)–在此期間計算錯誤,在其結束時重置計數; 合理的值可能是10分鐘
- alert.TooManyErrorsRecently.warn和alert.TooManyErrorsRecently.critical –在此期間遇到如此多的錯誤時觸發警報。 合理的值取決于您應用程序的正常錯誤率
- alert.TooManyErrorsRecently.quietperiod (以毫秒為單位)–在此期間,在持續失敗的情況下,不要發送進一步的警報以防止垃圾郵件; 合理的值取決于您通常解決問題的速度,對我來說1個小時似乎還可以
Log4J配置
現在,我們需要告訴Log4J使用Stat4j附加程序來計算錯誤發生次數并通過電子郵件發送警報:
log4j.rootCategory=DEBUG, Console, FileAppender, Stat4jAppender
...
### Stat4jAppender & EmailAlertsAppender ###
# Collects statistics about logs and sends alerts when there
# were too many failures in cooperation with the EmailAlertsAppender## Stat4jAppender
log4j.appender.Stat4jAppender=net.sourceforge.stat4j.log4j.Stat4jAppender
log4j.appender.Stat4jAppender.Threshold=ERROR
# For configuration see stat4j.properties## EmailAlertsAppender
# BEWARE: SMTPAppender ignores its Thresholds and only evers sends ERROR or higher messages
log4j.category.alerts=ERROR, EmailAlertsAppender
log4j.appender.EmailAlertsAppender=org.apache.log4j.net.SMTPAppender
log4j.appender.EmailAlertsAppender.To=dummy@example.com
# BEWARE: The address below must have a valid domain or some receivers will reject it (e.g. GMail)
log4j.appender.EmailAlertsAppender.From=noreply-stat4j@google.no
log4j.appender.EmailAlertsAppender.SMTPHost=172.20.20.70
log4j.appender.EmailAlertsAppender.BufferSize=1
log4j.appender.EmailAlertsAppender.Subject=[Stat4j] Too many exceptions in log
log4j.appender.EmailAlertsAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.EmailAlertsAppender.layout.ConversionPattern=%d{ISO8601} %-5p %X{clientIdentifier} %c %x - %m%n
注釋
- #8指定Stat4J附加程序
- #9僅向Stat4J發送錯誤,我們對不太嚴重的異常不感興趣
- #14“警報”是Stat4jAppender用于記錄警報的日志類別(與您通過Logger.getLogger(“ alerts”)創建的類別)相同; 如前所述,SMTPAppender將不考慮配置而僅處理錯誤和更高級別
SMTPAppender的問題
使SMTPAppender工作非常棘手。 一些陷阱:
- SMTPAppender忽略所有非ERROR或更高級別的日志,而不考慮您如何設置閾值
- 如果您指定了“不存在的發件人”域,則某些收件人的郵件服務器可以將其作為垃圾郵件刪除(例如,GMail)
- 要發送電子郵件,您當然需要mail.jar(對于舊版JVM也需要activation.jar),這是Tomcat的說明。
一個$ 100的提示:要對其進行調試,請在調試模式下運行您的應用程序,并在javax.mail.Transport#send上設置方法斷點(不需要源代碼),然后在其中設置this.session.debug為如果為true,則會在服務器日志中獲得以下SMTP通信的非常詳細的日志。
邊注
本文基于Log4J的事實并不意味著我會親自選擇它,它只是隨項目一起提供的。 我至少會考慮使用更新的和閃亮的Logback代替:-)。
結論
Stat4j + SMTPAppender是基于日志和電子郵件的相當靈活的自行完成警報系統的良好基礎。 您可以使用Hyperic HQ plus開箱即用地實現相同的功能。
參考: 當錯誤日志太多時,聚集錯誤日志以發送警告電子郵件–來自The Holy Java Blog的 JCG合作伙伴 JakubHoly的 Log4j,Stat4j,SMTPAppender 。
- 首先記錄異常的根本原因
- Java日志混亂
- 正確記錄應用程序的10個技巧
- 使用Java發送電子郵件
- Spring,Quartz和JavaMail集成教程
- 使用Spring使用Java發送電子郵件– GMail SMTP服務器示例
- Java教程和Android教程列表
翻譯自: https://www.javacodegeeks.com/2011/10/log4j-stat4j-smtpappender-integration.html