今天我來分享一個關于日志的問題和解法,

問題
沒有界面的后端程式在實際運行中發生了什么事,通常是通過日志來探查,所以日志非常重要,資料庫記錄了程式運行的結果,日志記錄了程式運行的程序,但是日志經常出現一個問題,日志量太多,以至于把重要的日志淹沒在里面,未能及時地發現問題,或者當有問題出現的時候,在日志中找原因真的是很痛苦,
對于這個問題,第1招就是把日志進行分級,差不多是每一種日志工具都提供了這個功能,常見的有info、warn、error這些級別,當使用級別進行過濾之后,往往發現日志還是太多,就需要進一步分析原因了,
在實際專案中發現有這么幾種情況:
1. 有大量的日志,內容基本相同,只是有一兩個值不同,如“發現無法轉成long型別的字串:xxx”
2. 還有一類日志是內容完全相同,如“意外發現xxx屬性的值是null”
至于為什么會有大量的這種日志,大概率是它在回圈內部,甚至是多重回圈的內部,
解法
解法一:少寫日志
怕日志多而在寫日志代碼時猶豫,甚至就不寫了,當出問題后找不到日志,無法為定位問題提供幫助,此法不可取,
解法二:硬編碼控制日志數量
設定一些標志或計數器來使回圈內的同一類日志只列印一潭訓少數幾條,那么日志的邏輯跟業務的邏輯會混在一起,程式的整體邏輯變得復雜,此法是下策,
如何讓程式員大膽寫日志,而又不會出現日志太多,同時日志的邏輯也很少摻雜到業務邏輯中呢?
解法三:日志工具類
我寫了一個日志的實用類來解決這個問題,
1. 拼接
它是將多條日志拼接為一條來輸出,采用“前綴+主體+后綴”的形式,在初始化時設定好前綴和后綴,在接收日志條目時拼接條目,最后的輸出形式是“前綴+條目1, 條目2, …+后綴”,如果條目數為0,則前后綴都不會輸出,所以,“發現無法轉成long型別的字串:aaa”,“發現無法轉成long型別的字串:bbb”“發現無法轉成long型別的字串:ccc”,會拼接這樣一條:“發現無法轉成long型別的字串:aaa,bbb,ccc”,合成后的內容長度就大大減少,
2. 條目數限制
假如類似的情況發生1000次,拼接后的日志還是很長,作為人來講,只需要看到前面的若干條目,就了解了這個問題,通常是沒必要看到全部的值,所以這個日志工具提供了條目數的限制,對于超過限制的條目,則不會輸出,比如條目數的限制是2,那輸出的結果就是“發現無法轉成long型別的字串:aaa,bbb”
3. 同值合并
對于內容完全相同的日志,就會直接進行合并,并記錄一個次數,不相鄰的除外,原本是好幾螢屏的“意外發現xxx的值是null”,合并成一條:“[1000*]意外發現xxx的值是null”,(此法是向瀏覽器的控制臺學習)
4. 長度限制
除此之外,還提供了總長度的限制,即是對“前綴+條目1, 條目2, …+后綴”的總長度的限制,如果某個條目加進去之后整體長度超過這個限制了,那么這個條目就會被丟棄,前綴后綴是不會被丟棄的,但如果“前綴+后綴”已經超出限制了,根據“如果條目數為0,則前后綴都不會輸出”最終沒有輸出,
5. 例外
此日志類實作特定的介面(Closable),做到了即使在業務代碼發生例外的情況下,也不會漏了輸出優化后日志,用法:
try (LogUtil log = LogUtil.builder().logger(LOGGER).build()) {
// ...A
log.write(“any message”);
// ...B
}
如果A處發生例外,自然沒有任何輸出,如果B處發生例外,則不影響前面的“any message”的輸出,
以上的條目數限制、同值合并、總長度限制等功能可單獨使用,也可組合使用,所以可能會看到這樣的結果:
“發現無法轉成long型別的字串:aaa,bbb,[99*]aaa,[56*]ccc”
這個日志實用工具是對現有日志組件的封裝,而現有的日志組件是log4j,不管使用哪個日志組件,都可以加上這種封裝,我并沒有修改日志組件,只是給他套了一層“殼”,
實際投入使用后,在我們的專案中發現,有一種相同的日志產生了947條,在過去是刷了好多屏,而且還不知道他多少條,現在合成之后就是一條,并且打上了“[947*]”,不僅沒有刷屏,還很清晰的看到了條數,
干凈,舒服,
博主簡介:佘煥敏(shé),洋名 Billy Sir,
關注編程基礎技術,并致力于研究軟體的自動化生成, 對編程規范化、面向物件的極致使用也有著濃厚的興趣, 同時非常希望能夠寫程式到65歲,
只有工匠精神,才能把常人覺得單調乏味的代碼,當作作品雕刻成藝術品,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/548899.html
標籤:其他
下一篇:Java面向物件--介面和多型
