日志規范總結篇


什么是日志

日志用來記錄用戶操作、系統運行狀態等,是一個系統的重要組成部分。然而,由於日志通常不屬於系統的核心功能,所以常常不被團隊成員所重視。對於一些簡單的小程序,可能並不需要在如何記錄日志的問題上花費太多精力。但是對於作為基礎平台為很多產品提供服務的后端程序,就必須要考慮如何依靠良好的日志來保證系統可靠的運行了。

好的日志可以幫助系統的開發和運維人員:
1. 了解線上系統的運行狀態
2. 快速准確定位線上問題
3. 發現系統瓶頸
4. 預警系統潛在風險
5. 挖掘產品最大價值

日志分類

診斷日志

  • 請求入口和出口
  • 外部服務調用和返回
  • 資源消耗操作:打開文件,IO等
  • 容錯行為
  • 程序異常,Exception
  • 后台操作:多線程等
  • 關鍵程序的啟動、關閉、配置加載

統計日志

  • 用戶訪問統計
  • 下單、支付日志

審計日志

  • 管理操作

日志中記錄什么?

日志應該不多不少,能夠從日志中得到所有需要的信息。在實踐中經常發生日志不夠的情況,例如:1)請求出錯時不能通過日志直接來定位問題,而需要開發人員再臨時增加日志並要求請求的發送者重新發送同樣的請求才能定位問題;2)無法確定服務中的后台任務是否按照期望執行;3)無法確定服務的內存數據結構的狀態;4)無法確定服務的異常處理邏輯(如重試)是否正確執行;5)無法確定服務啟動時配置是否正確加載;
示例:
[INFO] RequestID:b1946ac92492d2347c6235b4d2611184, ErrorCode:1426, Message: callback request (to http://example.com/callback) failed due to socket timeout

容易遺漏的日志:

  1. 系統的配置參數:系統在啟動過程中通常會首先讀啟動參數,可以在系統啟動后將這些參數輸出到日志中,方便確認系統是按照期望的參數啟動的;
  2. 后台定期執行的任務:如定期更新緩存的任務,可以記錄任務開始時間,任務結束時間,更新了多少條緩存配置等等,這樣可以掌握定期執行的任務的狀態;
  3. 異常處理邏輯:如對於分布式存儲系統來說,當系統在一個存儲節點上讀數據失敗時,需要去另一個數據節點上進行重試,可以將讀數據失敗這件事情記錄下來,之后可以通過對日志的分析確認是否某些節點的磁盤可能存在故障。再比如,如果系統需要請求一個外部資源,可以將請求這個外部資源偶爾失敗又重試成功這件事情記錄下來,具體來說:
 
 
 
 
 
[INFO] RequestID:b1946ac92492d2347c6235b4d2611184, auth request (to http://auth1.example.com/v2) timeout ... 1 try    
[INFO] RequestID:b1946ac92492d2347c6235b4d2611184, auth request (to http://auth1.example.com/v2) timeout ... 2 try  
[INFO] RequestID:b1946ac92492d2347c6235b4d2611184, auth request (to http://auth1.example.com/v2) success
要好於:[INFO] RequestID:b1946ac92492d2347c6235b4d2611184, auth request (to http://auth1.example.com/v2) success
 
 

因為前者可以讓我們預判被依賴的服務器服務質量有風險,也許需要進行擴容;日志中需要記錄關鍵參數,出錯時的關鍵原因等。


 
 
 
 
[INFO] RequestID:b1946ac92492d2347c6235b4d2611184, auth failed
[INFO] RequestID:b1946ac92492d2347c6235b4d2611185, content digest does not match
[INFO] RequestID:b1946ac92492d2347c6235b4d2611186, request ip not in whitelist
就不如:
[INFO] RequestID:b1946ac92492d2347c6235b4d2611184, auth failed due to token expiration
[INFO] RequestID:b1946ac92492d2347c6235b4d2611185, content digest does not match, expect 7b3f050bfa060b86ba781151c563c953, actual f60645e7107917250a6408f2f302d048
[INFO] RequestID:b1946ac92492d2347c6235b4d2611186, request ip(=202.17.34.1) 
 
 

日志級別

  • FATAL — 表示需要立即被處理的系統級錯誤。當該錯誤發生時,表示服務已經出現了某種程度的不可用,系統管理員需要立即介入。這屬於最嚴重的日志級別,因此該日志級別必須慎用,如果這種級別的日志經常出現,則該日志也失去了意義。通常情況下,一個進程的生命周期中應該只記錄一次FATAL級別的日志,即該進程遇到無法恢復的錯誤而退出時。當然,如果某個系統的子系統遇到了不可恢復的錯誤,那該子系統的調用方也可以記入FATAL級別日志,以便通過日志報警提醒系統管理員修復;
  • ERROR — 該級別的錯誤也需要馬上被處理,但是緊急程度要低於FATAL級別。當ERROR錯誤發生時,已經影響了用戶的正常訪問。從該意義上來說,實際上ERROR錯誤和FATAL錯誤對用戶的影響是相當的。FATAL相當於服務已經掛了,而ERROR相當於好死不如賴活着,然而活着卻無法提供正常的服務,只能不斷地打印ERROR日志。特別需要注意的是,ERROR和FATAL都屬於服務器自己的異常,是需要馬上得到人工介入並處理的。而對於用戶自己操作不當,如請求參數錯誤等等,是絕對不應該記為ERROR日志的;
  • WARN — 該日志表示系統可能出現問題,也可能沒有,這種情況如網絡的波動等。對於那些目前還不是錯誤,然而不及時處理也會變為錯誤的情況,也可以記為WARN日志,例如一個存儲系統的磁盤使用量超過閥值,或者系統中某個用戶的存儲配額快用完等等。對於WARN級別的日志,雖然不需要系統管理員馬上處理,也是需要及時查看並處理的。因此此種級別的日志也不應太多,能不打WARN級別的日志,就盡量不要打;
  • INFO — 該種日志記錄系統的正常運行狀態,例如某個子系統的初始化,某個請求的成功執行等等。通過查看INFO級別的日志,可以很快地對系統中出現的 WARN,ERROR,FATAL錯誤進行定位。INFO日志不宜過多,通常情況下,INFO級別的日志應該不大於TRACE日志的10%;
  • DEBUG or TRACE — 這兩種日志具體的規范應該由項目組自己定義,該級別日志的主要作用是對系統每一步的運行狀態進行精確的記錄。通過該種日志,可以查看某一個操作每一步的執 行過程,可以准確定位是何種操作,何種參數,何種順序導致了某種錯誤的發生。可以保證在不重現錯誤的情況下,也可以通過DEBUG(或TRACE)級別的日志對問題進行診斷。需要注意的是,DEBUG日志也需要規范日志格式,應該保證除了記錄日志的開發人員自己外,其他的如運維,測試人員等也可以通過 DEBUG(或TRACE)日志來定位問題;

關於RequestId

一個系統通常通過RequestID來對請求進行唯一的標記,目的是可以通過RequestID將一個請求在系統中的執行過程串聯起來。該RequestID通常會隨着響應返回給調用者,如果調用出現問題,調用者也可以通過提供RequestID幫助服務提供者定位問題

RequestId的生成:

  • 簡單系統,簡單隨機數即可
    RequestID = md5(time.Now() + random.Int())
  • 分布式環境需要建立全局唯一ID,參照twitter

慢操作日志

  • 服務在接收到一個請求的時候,記錄請求的接收時間(T1),在請求處理完成待發送的時候,會記錄請求發送時間(T2),通常一個請求的日志都記為INFO級別,然而當出現請求處理時間(T2-T1)超過一定時間(如10s)時,可以將該日志提升為WARN級別。通過該方法,可以預先發現系統可能存在的一些問題。
  • 同樣的慢操作日志還可以用來記錄系統一些外部依賴的處理時間,如一個服務可能依賴外部認證服務器來進行認證授權。通過記錄每次認證請求的時間並將超出預期時間的請求日志采用WARN級別輸出,可以盡早發現認證服務器是不是需要擴容等問題。
  • 慢日志的時間閾值應該是可以動態調整的,這樣在進行系統優化時,可以將該報警時間閾值逐漸調小,不斷地對系統進行優化


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM