Slf4j列印異常堆疊資訊並推送到ELK
阿新 • • 發佈:2022-05-24
1.問題描述
在日常開發中,對於異常資訊,通過會進行log列印,有時會接入到ELK,但需要注意細節問題。
用的最多的可能就是在類上加入@Slf4j註解,在可能異常的地方使用log.error("異常資訊為:"+e)或log.error("異常資訊為:{}", e.getMessage())列印錯誤資訊,但在實際場景中想要去分析異常的原因,檢視完整異常堆疊資訊,定位其異常具體發生在哪一行代時,顯得有些力不從心。
2.場景還原
這裡使用了最常用的日誌佔位符方式進行說明,對於字元拼接方式也是一樣的道理。
測試程式碼:進行了兩種日誌的列印,分別是異常資訊和異常類
@RequestMapping(value = "/test") public Integer test() { try { int i = 10 / 0; return i; } catch (Exception e) { String q = "測試介面"; log.error("{}發生異常1:{}", q, e.getMessage()); log.error("{}發生異常2:{}", q, e); } return null; }
控制檯列印結果:
kibana查詢結果:
從kibana的結果可以看出,第二種日誌列印方式列印了異常類及異常原因,在kibana中明顯優於第一種方式,可一幕瞭然看到異常資訊。但展開檢視兩個日誌的詳細資訊,兩種日誌列印都看不到具體的錯誤所在的行
3.解決方案
其實若只在控制檯列印異常的完整資訊,則採用第二種方式即可,去掉多餘的佔位符:
log.error("{}發生異常3:", q, e);
列印結果如下:
若需要推送到ELK,則在列印錯誤資訊時,把堆疊資訊也打印出來。這裡在第二種方式的基礎上列印,再最後再加上異常類指定堆疊即可,將日誌列印修改如下:
log.error("{}發生異常3:{}", q, e, e);
列印結果如下,可以看出已達到想要的結果。在異常堆疊中,可以看到異常發生的類以及所在行(line)
上述無論是Slf4j還是log4j2都是一樣的用法。