接觸過一定數(shù)量的業(yè)務系統(tǒng),大部分系統(tǒng)線上維護都是要你命3000获三,越老越要命旁蔼。本文僅從軟件工程角度給出一個合理的建議。
常見的讓大家詬病的三個問題:
1. 日志文件太過簡單疙教,error一個日志棺聊,info一個日志,打開文件會發(fā)現(xiàn)一堆與業(yè)務無關的中間件日志贞谓,和組件心跳日志
2. 異常信息打印不規(guī)范限佩,一個異常被多次拋出,多次打印同一條信息的異常棧裸弦,有效信息被大量的冗余日志沖散祟同,不利于線上問題排查,這不屬于本文章要討論的問題理疙,這是代碼規(guī)范晕城,要嚴格控制異常棧的打印。
3. logger 是有繼承關系的=严汀W┣辍!你生的孩子要管你爸叫爺爺赃梧,但是他可以選擇不認祖宗滤蝠。有些開發(fā)者搞不清楚logger繼承關系,導致同一日志在不同文件下多次輸出槽奕,維護系統(tǒng)的人看著累几睛,日志也累啊,它見誰都要認祖歸宗粤攒,其實搞清楚繼承關系可以讓我們日志輸出孑然一身輕所森。
注:一些聰明但是神經大條的人確實不會對這些問題敏感囱持,反正再亂的線團他們都能找到線頭,這正促使了一堆牛人留下了一堆足以讓接盤的新人頭大的維護工作焕济。但是顯然業(yè)務系統(tǒng)中遺留這樣完全不必要的問題纷妆,不利于業(yè)務系統(tǒng)的工作流水線標準化,造成新人工作交接上崗到熟練的周期不必要延長晴弃。
最近工作中再一次涉及到了日志整理的問題掩幢,雖然簡單,但很少有人總結并留下思路上鞠,特錄此文际邻,希望大家對自己的接班人都溫柔一些,干活的時候一時興起芍阎,亂七八糟的操作不要太猛世曾。
log4j 和 logback 區(qū)別是有的,本文僅以log4j 為示例谴咸,logback的配置不如log4j 靈活
log4j 日志配置的兩個關鍵要素:
1. logger轮听。如果把每一個類比作自然人,每一個自定義名稱的logger比作法人岭佳,logger就可以是泛指的人血巍,即logger 既可以以一個完整類名作為標識,也可以以開發(fā)者自定義的名稱作為標識珊随。要做精確控制的時候只要按照完整類名定義logger即可述寡。
2. appender 。日志輸出到不同的文件玫恳。建議的做法:
系統(tǒng)所有的error日志輸出到error.log , 對輸出到這個文件的日志嚴格控制
系統(tǒng)其他級別的日志統(tǒng)一按照業(yè)務模塊辨赐,組件角色其中一個維度(注意是其中一個,按照自己的需求京办,不要多維度組合)將非error日志區(qū)分文件輸出掀序。
log4j的輸出日志級別的四個關鍵屬性:
<logger name="*****" additivity="false">
? ? <level value="INFO"/>
</logger>
1. level標簽里值是設定本logger的最低級別,即該類日志可以輸出的最低級別的日志記錄
2. additivity:表示Logger不會在父Logger的appender里輸出惭婿,默認為true不恭。配置additivity="false", 就能確保該日志記錄只會在一個文件中輸出财饥,當然根據(jù)開發(fā)者對業(yè)務系統(tǒng)的掌握程度换吧,這個字段應該靈活設置,讓日志更簡潔钥星,分類更清晰沾瓦。
<appender name="console" class="*******">
? ? <param name="file" value="${log4j_dir}/***/monitor-error.log" />
? ? ....
? ? <param name="threshold" value="info" />
? ? <filter class="org.apache.log4j.varia.LevelRangeFilter">
? ? ? ? <param name="LevelMax" value="error"/>
? ? ? ? <param name="LevelMin" value="info"/>
? </filter>
</appender>
3. threshold 屬性, 在appender指定日志輸出的最低級別,默認為DEBUG贯莺。
4. filter 子域风喇, 這就是一個可以展開的內容,具體參見https://www.cnblogs.com/yulinlewis/p/10152875.html
只要明確上面的這些概念缕探,就可以讓那個我們的系統(tǒng)日志變得更加清晰明了魂莫,采用本文推薦的日志設計一定會減輕日常的系統(tǒng)維護工作。從而減輕不必要的腦力負擔爹耗,也讓應用維護能夠有一個相對標準的流程耙考。