1. 程式人生 > 其它 >Slf4j列印異常堆疊資訊並推送到ELK

Slf4j列印異常堆疊資訊並推送到ELK

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都是一樣的用法。