線上排障技巧 | 動態修改 LOGGER 級別
前言
大多數情況下,我們會在列印日誌時定義日誌的LOGGER級別,用來控制輸出的資訊範圍。
一方面,過多的輸出會影響檢視日誌的效率,另一方面,過少的日誌讓問題定位變得困難。
但當線上出現問題時,線上容器通常定義在info級別,發生一些疑難問題時,光靠info級別的日誌很難定位問題。
一個典型的場景:在一些需要列印MySQL語句的場景,如果你正在使用MyBatis框架,由於MyBaits中SQL語句是DEBUG級別的資訊,通常在線上容器就沒法看到。
一個醜陋的解決辦法就是在沙箱/預發環境,將log4j.xml中的info改為debug:
<Root level="info">然後重新打包部署,再發起請求來除錯程式碼。
甚至在一些無法模擬請求的場景下,還需要將修改灰度至線上環境,大量的debug資訊會對線上服務造成實質性的影響。
「本文簡要介紹如何使用阿里巴巴開源Java除錯工具Arthas,實時修改線上服務的LOGGER級別,從而免去打包再部署的繁雜手續,更快的定位線上問題。」
「效果演示:」
本地測試:實時修改LOGGER級別
安裝arthas
網路安裝
在接通外網的環境下,可以使用快速網路安裝,會從阿里的源拉去全量包。
curl -O https://arthas.aliyun.com/arthas-boot.jar java -jar arthas-boot.jar全量安裝
如果本地外網環境不通,比如某些容器內是不允許外網訪問的,那麼可以使用預先下載好的全量安裝包,然後解壓後執行包內的jar,使用命令:
java -jar arthas-boot.jar啟動arthas
我在本地啟動arthas,效果如下圖:
全域性Logger資訊
使用命令:
可以看到所有logger的資訊,包括其中每個appenders。
使用如下命令,修改名稱為ROOT的logger的日誌級別至debug級別:
logger --name ROOT --level debug可以看到多出了debug級別的輸出。
指定類名的logger資訊
在有多個logger的情況下,可以查詢指定名稱的logger
logger -n ROOT指定classloader的logger資訊
如果需要改變指定類的輸出級別,先要定位到該類的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使用 ongl 命令
此外,Arthas還支援使用ognl來修改日誌級別。但是這種方法對log4j不友好,修改會報錯。並且就算支援的logback/slf4j,也需要複雜的形如ognl -c @org.slf4j.LoggerFactory@getLogger(“root”).setLevel()的命令才能修改,並不是一個很好的辦法。
線上實戰:實時列印MyBatis SQL語句
容器內啟動arthas
我的線上容器,是沒有外網訪問許可權的(這種情況蠻常見的),我將全量包解壓在容器內執行:
列印DEBUG級別的SQL日誌
下圖是沒有DEBUG資訊的一條請求日誌,可以看到只有入參出參的攔截器資訊(INFO級別):
使用logger --name ROOT --level debug
,將SQL語句輸出出來:
畢竟,很多時候線上的bug是不小心拼錯SQL導致。
總結
文章簡單總結了使用Arthas來動態調整日誌級別的使用方法。在線上環境,能夠有效的提升排查問題的效率。當然Arthas能做的還遠不止於此,更多有趣並且「實用」的功能等待大家的發掘。
看完三件事❤️
如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:
-
點贊,轉發,有你們的 『點贊和評論』,才是我創造的動力。
-
關注公眾號 『java爛豬皮』,不定期分享原創知識。
-
同時可以期待後續文章ing