關於日誌,在你們的印象中都是比較簡單的,只須引入了相關依賴包,剩下的事情就是在項目中「盡情」的打印咱們須要的信息了。可是每每越簡單的東西越容易讓咱們忽視,從而致使一些不應有的bug發生,做爲一名嚴謹的程序員,怎麼能讓這種事情發生呢?因此下面咱們就來了解一下關於日誌的那些正確使用姿式。java
首先是日誌文件的命名,儘可能要作到見名知意,團隊裏面也必須使用統一的命名規範,否則「髒亂差」的日誌文件會影響你們排查問題的效率。這裏推薦以「projectName_logName_logType.log」來命名,這樣經過名字就能夠清晰的知道該日誌文件是屬於哪一個項目,什麼類型,有什麼做用。例如在咱們MessageServer項目中監控Rabbitmq 消費者相關的日誌文件名能夠定義成「messageserver_rabbitmqconsumer_monitor.log」。程序員
關於日誌保存的時間,普通的日誌文件建議保留15天,若比較重要的可根據實際狀況延長,具體請參考各自服務器磁盤空間以及日誌文件大小做出最優選擇。安全
常見的日誌級別有如下:bash
建議在項目中使用這四種級別, ERROR、WARN、INFO 、DEBUG。服務器
一、提早判斷日誌級別markdown
//條件判斷 if(logger.isDebugEnabled){ logger.debug("server info , id : " + id + ", user : " + user); } //使用佔位符 logger.debug("server info , id : {}, user : {}",id,user); 複製代碼
對於DEBUG,INFO級別的日誌,在咱們的程序中是比較高頻的存在,當咱們的項目大了,日誌變多了,這時候爲了程序運行的效率,咱們必須以條件判斷或者佔位符的方式來打印日誌。爲何呢?假如咱們項目中配置的日誌級別爲WARN,那麼對於咱們下面的日誌輸出語句‘ logger.debug("server info , id : " + id + ", user : " + user);’,雖然該日誌不會被打印,可是卻會執行字符串拼接的操做,這裏咱們的user是一個實例對象,因此還會執行toString方法,這樣就白白浪費了很多系統的資源。異步
二、避免多餘日誌輸出socket
在咱們的生產環境中,通常禁止DEBUG日誌的輸出,其打印的頻率是很是高的,容易對正常運行的程序形成嚴重的影響,在咱們最近的項目中就有遇到過相似的狀況。elasticsearch
那麼這時候該學會使用additivity屬性post
<logger name="xx" additivity="true"> 複製代碼
在這邊配置成true的話,也就是默認的狀況,這時候當前Logger會繼承父Logger的Appender,說白了就是當前日誌的輸出除了輸出在當前日誌文件之外,還會輸出至父文件裏。因此通常狀況下,咱們爲了不重複打印,會將這個參數設置成false,以減小沒必要要的輸出。
三、保證日誌記錄信息完整
在咱們的代碼中,日誌記錄的內容要包含異常的堆棧,請勿隨意輸出「XX出錯」等簡單的日誌,這對於錯誤的調試毫無幫助。因此咱們在記錄異常的時候必定要帶上堆棧信息,例如
logger.error("rabbitmq consumer error,cause : "+e.getMessage(),e); 複製代碼
切記在輸出對象實例的時候,須確保對象重寫了toString方法,不然只會輸出其hashCode值。
四、定義logger變量爲static
private static final Logger logger = LoggerFactory.getLogger(XX.class);
複製代碼
確保一個對象只使用一個Logger對象,避免每次都從新建立,不然可能會致使OOM。
五、正確使用日誌級別
try{ //.. }catch(xx){ logger.info(..); } 複製代碼
這樣一來,原本是ERROR的信息,全都打印在INFO日誌文件裏了,不知情的同事還會在死盯着錯誤日誌,並且還找不出問題,多影響工做效率是吧?
六、推薦使用slf4j+logback組合
logback庫裏自身就已經實現了slf4j的接口,就無需引入多餘的適配器了,並且logback也具備更多的優勢,建議新項目可使用這個組合。 還有一點須要注意,當引入slf4j後,要注意其實際使用的日誌庫是不是由咱們引入的,也有可能會使用了咱們第三方依賴包所帶入的日誌庫,這樣就可能會致使咱們的日誌失效。
七、日誌的聚合分析
日誌的聚合能夠把位於不一樣服務器之間的日誌統一塊兒來分析處理,現在ELK技術棧亦或者的EFG(fluentd+elasticsearch+grafana)等都是一些比較成熟的開源解決方案。
拿ELK來講,能夠在咱們的服務器上直接經過logstash來讀取應用打印的日誌文件,或者也能夠在咱們項目中的日誌配置文件裏配置好相關的socket信息,打印的時候直接把日誌信息輸出至logstash。再交由elasticsearch存儲,kibana展現。
好了,關於日誌先聊這麼多~ 你們有須要補充或者交流的能夠在下方留言哦。
《使用ConcurrentHashMap必定線程安全?》
《大白話搞懂什麼是同步/異步/阻塞/非阻塞》
《論JVM爆炸的幾種姿式及自救方法》
《解放程序員雙手之Supervisor》
關注「深夜裏的程序猿」,分享最乾的乾貨