深入理解Logger日志——日志等級動態調整
不用多說在之前的文章也提及過,項目中日志的重要性,但有時候日志又會產生另一種傷害或者排除問題信息不全,如:
- 某些業務突然暴漲導致日志爆滿壓爆服務內存,會直接造成系統性能下降,極端情況下,甚至導致系統宕機。
- 在一些線上問題的排查中,因為缺少很多日志信息,debug日志又無法打開,以至於只能不斷的各種方式排查或停下服務添加日志,讓人很着急。
在這種背景下,為了兼顧性能和快速響應線上問題,這時日志級別動態調整的需求是非常需要的,可以在需要解決線上問題時,實時調整線上日志輸出級別,獲取全面的Debug日志,幫助工程師提高定位問題的效率,這個真的很香。
目前需要主要功能有:
- 項目的整體日志等級調整,面對整體大業務形式。
- 項目中某個單一類的日志等級調整,對於小問題,單一業務的處理非常好,不影響其他業務日志。
使用場景
有了這個需求靈感,上網一查,有了,美團技術團隊做了一個組件值得參考,日志級別動態調整——小工具解決大問題
Copy他們的使用場景描述一下:
場景一
業務依賴復雜。某一時刻,依賴的下游服務故障,導致請求大量超時,尤其是像外賣這種集中性特別明顯的業務,平均每秒QPS在8000以上,1分鍾的故障就會集中產生大量的錯誤日志,導致磁盤IO急劇提高,耗費大量CPU,進而導致整個服務癱瘓。如果該業務不能立即降級,怎么辦?
從代碼級別解決問題到發版上線,暫且不說流程長、操作麻煩,同時還存在引入其它故障的高風險。如果系統恰好使用Log4j版本,在極短時間內打印出了海量錯誤日志,會快速耗盡Buffer區內存,從而拖慢主線程,造成服務性能整體下降,甚至還沒有來得及修復問題,海量日志已經拖垮服務,造成服務宕機,損失慘重。
場景二
大量的訂單、結算等客訴問題反饋過來,一線工程師大量精力埋沒於排查問題中,而排查定位問題的最終手段仍然是依賴線上日志。由於鏈路較長,任一日志的缺失,都給問題的排查帶來極大的障礙,面對運營的催促,怎么辦?
工程師為了以后排查問題的方便,在任一可能出現異常的地方,都會打印出關鍵日志,然后發版上線。但好不容易解決了本次問題,還沒來得及收獲喜悅,就又面臨着一個新問題,那就是場景三。
場景三
由於線上業務系統默認日志打印級別是INFO級別,為了排查問題方便,調試型日志都以該級別打印出來。這樣的話給系統帶來了額外的負擔,在高峰期大量調試日志時會拖慢系統性能,增大出故障的風險,怎么辦?
一方面要快速響應業務,另一方面要兼顧系統性能,能不能兩方面兼顧?我們的動態調整日志級別工具正是為了解決這種痛點。
能解決哪些問題
- 日志降級。 兼容Log4j、Log4j2和Logback主流日志框架,如果遇到場景一,可以通過我們的日志工具,快速調整日志輸出級別,降低系統日志的輸出,從而達到日志降級的效果,同時能夠給RD爭取充裕的排查問題時間。
- 規范日志級別濫用,幫助工程師快速定位解決線上問題。 使用日志級別動態調整組件,可以實時動態調整線上服務的日志打印級別,調試型日志可以使用低級別打印出,減輕線上服務的負載壓力。遇到排查問題時,可以臨時將日志級別調低,快速得到精准化的日志信息,排查解決問題。
日志等級動態調整四種方法
經過多次的調查,發現對日志等級的動態調整有很多種方式每一種都有其獨特的好處,值得研究。以下日志等級調整以Logback框架為例子,其他的可以參考進行相應的改造互通。
第一種方式:配置文件的自動檢測更新
利用Logback中的配置文件,開啟logback.xml的自動掃描 scan = true 來更新日志的配置。
實踐感受:個人感覺手動改配置文件有點恐怖不太安全,只能說可以做急救的一種方式,有可能不好使,不太好設置。
第二種方式:Spring Actuator 監控
項目中若是SpringBoot為框架的可以引入 spring-boot-starter-actuator 監控依賴,配合好Web,內部有非常多的功能,其中包括日志等級的查看、修改。
參考文章對Actuator進行相應的介紹:
針對Loggers做一些介紹:
Actuator:獲取各類監控配置的地址,如下獲取Loggers的數據
Loggers
endpoint:可以通過GET訪問 http://localhost:8080/actuator/loggers 獲取所有的Loggers日志對象,配置的loggers的列表和相關的日志等級。
指定獲取某個Logger對象信息GET:http://localhost:8080/actuator/loggers/{name}
指定修改某個日志的日志等級POST:http://localhost:8080/actuator/loggers/{name}
實踐感受:這個方式非常的不錯,內容很豐富,就差個頁面了,不過這個還是存在一些安全性的問題,需要結合Spring-Security,來配置獲取權限,增加安全校驗。
推薦看手把手帶你入門 Spring Security!根據項目情況相應配置
第三種方式:Spring Boot Admin 監控管理
集成Spring Cloud 的Spring Boot Admin 來動態調整日志等級,若是項目為SpringCloud的非常香,其實這個主要是spring-boot-starter-actuator的升級版而已,在外部出現來UI界面,內部還是調用其 actuator/接口進行相應操作。
推薦參考文章:
主要界面:
在Spring Boot Admin 中的Logger動態調整,實時反饋到了日志中
此方法的測試中主要需要注意的是,在Client中Actuator是否與Spring Security配合進行鑒權了,進行相應調整。
實踐感受:第一感覺是Spring家族太強大了,不過這個也是需要配合這SpringCloud一起使用,看看項目是否適合,這也是趨勢所在。
第四種方式:自定義Logger API
這種方式主要是獲取日志實現框架的Logger類,去調整(setLevel)日志等級,因為Slf4j的API中的Logger沒有提供相關的日志等級調整,需要去具體的實現類中操作。
每一種日志實現框架中都有自己的方式獲取Loggers的日志集合,若是需要適應不同項目不同的日志類型,需要做好組件的兼容性,個人建議整體項目系統保持統一日志架構。
推薦一下美團技術團隊所做的Github地址:https://github.com/sekift/change-log-level (這個自己造輪子,不會的用上面的Spring Actuator 就很好)
他們有兩種整體和module形式,可根據所需參考所適配。
我個人參考對美團的日志調整項目做了相應的調整,適應自己的當前情況,在下一個文章做具體的介紹。
項目結構圖:
具體使用方式
引入jar包,這個包是個人的,可以根據個人喜愛,隨意操作,放在maven私有倉庫中
<dependency> <groupId>com.xxxxx.apr</groupId> <artifactId>logger</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
測試中調用:
敬請期待...
Github:https://github.com/LiZhouYan/logger-util