有关日志打印的几点经验
前段時間,完善智能導航發送告警短信中短信太長接收不到的bug,牽涉出了日志打印的問題;日志打印這件事說小事小,說大也大,寫好日志能方便自己調試代碼和發現解決問題,以下就是有關日志打印自己總結的幾點經驗教訓:
日志打印應該分層、分角度,一個好的日志不應該只打印與業務有關的日志。
日志打印應該從以下幾個方面去打印:
模塊運行日志:模塊運行日志包括消息隊列的監控、線程的運行狀態。該日志應該以INFO級別打印,并且采用間隔打印,或叫做定時打印。以減少日志打印總量。從該角度可以反應出該模塊是否有消息隊列積壓,是否所有線程都運行正常。消息隊列的打印可以采用日下格式:
使用統一的關鍵字Monitor來標示模塊運行日志。隊列監控日志使用|隊列名|消息放入速度|消息取出速度|消息放入個數|消息取出個數|當前隊列消息個數|。線程監控日志使用|線程名|線程狀態碼|,線程狀態碼可以自己擴展。0表示正常1表示運行結束2表示線程阻塞。
09:16:59.347 INFO |Monitor|ReceiveTimerQueue|0/s|0/s|0|0|0| 09:16:59.347 INFO |Monitor|SendRegistQueue|0/s|0/s|0|0|0| 09:16:59.347 INFO |Monitor|boss->omc|0/s|0/s|0|0|0| 09:16:59.347 INFO |Monitor|SendQueue|0/s|0/s|0|0|0| 09:16:59.347 INFO |Monitor|boss->pss|0/s|0/s|7037|7037|0| 09:16:59.347 INFO |Monitor|ReceiveAuthQueue|0/s|0/s|0|0|0| 09:16:59.347 INFO |Monitor|ReceiveQueue|0/s|0/s|0|0|0| 09:16:59.348 INFO |Monitor|receiveHandler5|0|SendHandler1|0|receiveAuthMsgHandleThread1|0| receiveTimerMsgHandler1|0|SendRegHandler|0|SendHandler3|0|SendHandler2|0|receiveHandler4|0|receiveHandler8|0|receiveHandler7|0|receiveHandler2|0|receiveHandler3|0|receiveHandler6|0|receiveHandler1|0|業務日志:業務日志打印用戶請求流程,能夠清楚的使用某幾個關鍵字可以提取一個用戶的業務流程就可以。業務日志要分詳細日志,如上BossAgent打印的日志,非常詳細,應該都打印DEBUG級別的日志,而另外就需要打印總結性日志,總結性日志以INFO級別打印,包括|請求開始時間|請求結束時間|請求主體|請求類型|請求結果|請求外部資源返回結果|。其中請求主體可以繼續擴展,如BossAgent的請求主體可以擴展為|手機號碼|省份編碼|MM2消息SEQUENCE|,DSS的請求主體可能屬性更多一些,|手機號碼|手機密碼|手機UA|手機MOD|手機MAN|計費類型|套餐類型|白名單|。
模塊性能日志:模塊的性能日志應該能夠通過該日志清晰的反應該模塊目前性能,包括外部請求的壓力,內部請求處理速度。
模塊外部資源日志:模塊的外部資源日志需要詳細記錄,現今單獨的模塊很少見了,很多大型復雜的系統往往是由多個模塊構成,模塊間采用或標準或私有協議進行通信。這種場景下爆發的問題往往比較復雜,并且與多個模塊都有關系或是責任。所以在模塊級別上將該模塊所依賴的外部資源都打印出來非常重要,通過這些日志應該能夠完成快速定位問題與哪些模塊相關聯或是哪些模塊需要負根本責任。通常模塊的外部資源包括數據庫,系統間內部模塊、第三方系統。如BossAgent的外部資源包括數據庫,系統間內部模塊為PSS、第三方系統應該是一級Boss。數據庫資源的打印應該包括所有的SQL語句,這個非常重要,無論是問題的定位還是后續的SQL優化,還是數據庫架構的調整,都需要這些信息能夠快讀的整理出該模塊所有的SQL語句,提供給專業的DBA進行分析。SQL語句的打印還應該包括參數的打印。
第三方系統的打印主要包括,請求壓力的統計、截流告警、請求處理的延遲、以及超時。
1、對異常的打印
異常日志的打印對于問題的分析和定義有極大的幫助,異常日志的打印應該注意以下幾點,雜異常分支必須打印日志。如switch case語句塊中的default,if else中的 else分支。Try catch語句塊中catch分支。對于catch分支的打印,應該盡量使用標準的異常打印,不應該打印的控制臺上,對于異常的處理不在本開發指南的討論范圍,所以簡單說明。異常應該打印堆棧信息,并且打印日志發生的場景。
2、日志級別
日志級別對于定位問題的重要性,在現網運營的過程中,往往都會打印低級別的日志,一些過于詳細得日志記錄程DEBUG,而一些總結性的日志記錄為INFO級別,對于外部資源日志,如果日志過于龐大,請將日志打印為DEBUG日志,在此基礎上在抽取總結性日志,打印為INFO日志。
3、考慮日志對性能的影響
日志的頻繁打印會對模塊的性能產生極大的影響。如BPP的在每次接受到消息后都會打印消息結構體,將該日志注掉,性能在原有的基礎上上升了600條/秒。
4、日志打印內容
4.1 不打印無用的日志
如現網的BossAgent將與PSS之間通信的心跳消息結構體打印出來,該日志不僅打印頻繁,而且沒有任何意義。
4.1 不打印不完全的日志
不打印不完全的日志,如BossAgent的消息隊列積壓的告警日志,只打印了消息隊列滿,但是沒有打印是誰滿了,也就是缺少主語,對于后續的定位產生了極大的阻礙。
4.3不打印重復的日志
如上BossAgent日志,將MM2消息結構體打印了多次,沒有任何意義。
4.4不在循環里打印日志
如果代碼的邏輯是一個無限循環或是循環的次數較多,這里的日志不應當打印太過頻繁,使用盡量縮減日志量,并且將有用的信息打印出來。在循環打印日志或占用大量CPU時間,這里需要進行特殊的打印。就是采取間隔打印或是定時打印。
5、日志格式
日志格式統一使用主語+謂語+賓語+狀語的格式,日志打印應該遵從人類的自然語言,任何沒有開發經驗或是外行人都能從你的日志中捕獲到有用的信息,相信你的日志就打印的很成功了。
加入分隔符,使用分隔符使每個域都能夠清晰識別,分隔符可以提高日志可分析性,也可以過濾空格。
如下日志:13722223310 register 200,沒有采用域分隔符,這樣都手機號碼中出現異常數據如13722223310+空格,無法快速定位。加入域分隔符以后13722223310 |register|200|,可以清晰的看清楚手機號碼后有多余的空格。
還有更多的有關日志打印的內容參照以下文章。
http://ju.outofmemory.cn/entry/72841
http://blog.csdn.net/mgoann/article/details/5681759
總結
以上是生活随笔為你收集整理的有关日志打印的几点经验的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (十)HTML5本地存储——SQLLit
- 下一篇: 在一台服务器上配置多个Tomcat的方法