大多數狀況下,咱們會在打印日誌時定義日誌的LOGGER級別,用來控制輸出的信息範圍。html
一方面,過多的輸出會影響查看日誌的效率,另外一方面,過少的日誌讓問題定位變得困難。java
但當線上出現問題時,線上容器一般定義在info級別,發生一些疑難問題時,光靠info級別的日誌很難定位問題。git
一個典型的場景:在一些須要打印MySQL語句的場景,若是你正在使用MyBatis框架,因爲MyBaits中SQL語句是DEBUG級別的信息,一般在線上容器就無法看到。github
一個醜陋的解決辦法就是在沙箱/預發環境,將log4j.xml中的info改成debug:web
<Root level="info"> <AppenderRef ref="detail"/> <AppenderRef level="error" ref="error"/> </Root>
而後從新打包部署,再發起請求來調試代碼。面試
甚至在一些沒法模擬請求的場景下,還須要將修改灰度至線上環境,大量的debug信息會對線上服務形成實質性的影響。算法
本文簡要介紹如何使用阿里巴巴開源Java調試工具Arthas,實時修改線上服務的LOGGER級別,從而免去打包再部署的繁雜手續,更快的定位線上問題。sql
效果演示:後端
本文內容重點:設計模式
本文閱讀大概須要:2分鐘
碼字不易,歡迎關注個人我的原創技術公衆號:後端技術漫談(二維碼見文章底部)
Arthas是阿里開源的Java診斷工具,它的功能能夠大體參考下圖:
它運行的原理是經過字節碼生成工具(ASM字節碼加強),將代理邏輯編織到原來的類裏,實現對應的監控調試等功能。
關於Arthas這個工具,以前我寫了一篇完整的總結文章,包括全部功能的使用和原理初探,能夠去原文章查看:https://juejin.im/post/6844903998730797070
在接通外網的環境下,可使用快速網絡安裝,會從阿里的源拉去全量包。
curl -O https://arthas.aliyun.com/arthas-boot.jar java -jar arthas-boot.jar
若是本地外網環境不通,好比某些容器內是不容許外網訪問的,那麼可使用預先下載好的全量安裝包,而後解壓後運行包內的jar,使用命令:
java -jar arthas-boot.jar
我在本地啓動arthas,效果以下圖:
使用命令:
logger
能夠看到全部logger的信息,包括其中每一個appenders。
使用以下命令,修更名稱爲ROOT的logger的日誌級別至debug級別:
logger --name ROOT --level debug
能夠看到多出了debug級別的輸出。
在有多個logger的狀況下,能夠查找指定名稱的logger
logger -n ROOT
若是須要改變指定類的輸出級別,先要定位到該類的classLoader,而後修改該clasLoader的logger。
使用sc命令查看你須要改變的類信息:
sc -d cn.monitor4all.miaoshaweb.DynamicLoggerTest | grep classLoaderHash
隨後能夠經過classLoader找到其對應的logger:
logger -c 18b4aac2
而後就能夠調整對應的logger日誌級別:
logger -c 18b4aac2 --name ROOT --level debug
此外,Arthas還支持使用ognl來修改日誌級別。可是這種方法對log4j不友好,修改會報錯。而且就算支持的logback/slf4j,也須要複雜的形如ognl -c @org.slf4j.LoggerFactory@getLogger("root").setLevel()
的命令才能修改,並非一個很好的辦法。
個人線上容器,是沒有外網訪問權限的(這種狀況蠻常見的),我將全量包解壓在容器內運行:
下圖是沒有DEBUG信息的一條請求日誌,能夠看到只有入參出參的攔截器信息(INFO級別):
使用logger --name ROOT --level debug
,將SQL語句輸出出來:
畢竟,不少時候線上的bug是不當心拼錯SQL致使。
文章簡單總結了使用Arthas來動態調整日誌級別的使用方法。在線上環境,可以有效的提高排查問題的效率。固然Arthas能作的還遠不止於此,更多有趣而且實用的功能等待你們的發掘。
我是一名奮鬥在一線的互聯網後端開發工程師。
主要關注後端開發,數據安全,邊緣計算等方向,歡迎交流。
若是文章對你有幫助,不妨點贊,收藏起來~