日志記錄最佳實踐


譯自Optimal Logging

by Anthony Vallone

Google Testing Blog

要找到一個系統問題的根本原因,你需要多長時間?5分鍾?還是5天?如果你的答案接近5分鍾,很大可能是因為你的生產環境和測試環境使用了非常好的日志記錄。更常見的情況是,諸如日志、異常處理、甚至測試這類非核心的工作,被當作一種出現問題后的補救方式。同異常處理和測試一樣,日志記錄真的也需要策略,無論是生產環境還是測試環境。永遠不要低估日志的作用。有了使用得當的日志,你甚至可以說debug不是必需的。下面是多年來對我非常有用的日志記錄指導原則。

保持適度

切勿記錄過多。大量的磁盤空間被日志占用說明你沒有想過應該記錄什么。如果記錄了太多,你就還需要設計出復雜的方法來減少磁盤訪問、保留歷史記錄、歸檔大量數據、以及在這些數據中查詢。最關鍵的是,你將發現在這么多垃圾中找到有用信息是多么的困難。

唯一一個比記錄過多日志還差的事是,記錄的過少。日志通常有兩個主要目的:定位問題和事件確認。如果你的日志不能明確一個bug的原因,或者某個事務是否執行,你就記錄的過少了。

適合記錄的:

  • 重要啟動配置
  • 錯誤
  • 警告
  • 持久性數據的更改
  • 主要系統組件間的請求和響應
  • 重要的狀態變化
  • 用戶交互
  • 有已知失敗風險的調用
  • 較長時間的等待
  • 長期運行任務的周期性進度
  • 重要的邏輯分支和導向分支的條件
  • 從高層方法來匯總處理流程的步驟和事件——避免在底層方法中記錄復雜流程的每一步驟

不適合記錄的:

  • 方法入口——不要記錄方法入口,除非它非常重要或者是日志處於調試級別。
  • 循環中的數據——避免在循環的多次迭代中記錄日志。如果是小循環,或者是間歇性的記錄,倒也無妨。
  • 大消息或者文件的內容——截斷或者使用一些有利於調試的方式進行匯總。
  • 良性錯誤——那些不是真正錯誤的錯誤會令日志的讀者感到困惑。當異常處理是執行成功的一部分時,有時會遇到這種情況。
  • 重復的錯誤——不要重復的記錄相同或者相似的錯誤。這樣可能會快速的填滿日志,並且隱藏掉真正的問題。各種類型錯誤發生的頻率最好有監視器(monitor)處理。日志只需捕獲問題的詳細信息。

多個日志級別

不要把所有信息都記錄在同一個日志級別中。絕大多數的日志庫都提供多個級別,系統啟動時可以進行指定。這樣可以很方便的控制日志詳盡程度。

典型的級別有:

  • 調試——最詳細,但是只有在開發或者調試時適用。
  • 信息——最常用的級別。
  • 警告——奇怪的或者不在預期之內的一些狀態,但是可接受。
  • 錯誤——有錯誤發生,但是流程不受影響。
  • 嚴重——流程無法繼續,系統將關閉或者重啟。

從實際使用來講,只需要兩種級別的日志配置:

  • 生產環境——除了調試級別,其他全開。如果生產環境發生了問題,日志應該能夠指明原因。
  • 開發和調試——編寫新代碼或是嘗試復現問題時,打開全部級別。

測試日志同樣重要

日志的質量對於測試代碼和產品代碼同樣重要。當一次測試運行失敗時,日志應當明確的指出這個錯誤是來自測試本身還是生產系統。如果做不到這一點,那么測試的日志是有問題的。

測試日志應該必需包括:

  • 測試執行環境
  • 初始狀態
  • 准備步驟
  • 用例步驟
  • 與系統的交互
  • 期望的結果
  • 實際的結果
  • 清理步驟

利用臨時日志隊列實現條件性的詳細信息控制

發生錯誤時,日志應當包含大量的詳細信息。但不幸的是,當遇到一個錯誤時,導致這個錯誤發生的詳細信息可能已經無法獲得了。如果你聽從了“不要記錄過多”的建議,在錯誤日志之前的那些日志可能無法提供足夠的細節。解決這個問題的一個好的方式是,在內存中創建臨時的日志隊列。在事務的處理過程中,將每一步的詳盡信息追加到隊列中。如果事務成功完成,丟棄這個隊列,只記錄一個匯總。如果發生了錯誤,就把錯誤和隊列里的全部內容記錄下來。這一方法對於系統交互的日志尤其有效。

問題是機遇

當生產環境出現問題時,你必將集中精力尋找並且修復問題,但是也不要忘記考慮一下日志。如果你費了很大力氣才找到問題的原因,這將是個非常好的機會來改善你的日志。修復問題前,先修復你的日志記錄,使其可以清楚的指明問題原因。如果這個問題又一次發生,將會很容易辨認。

如果無法復現問題,或者測試結果不確定,改進日志以便可以在問題再次發生時將其記錄下來。

在整個開發的生命周期內,都應該持續的利用問題來改進日志。寫新代碼時,試着少用debug,只使用日志。這些日志是否能夠說明發生了什么?如果不能,日志就是不充分的。

最好也記錄性能數據

記錄時間數據可以用來幫助定位性能問題。例如,要找到一個大型系統的超時原因是很困難的,除非你能夠追蹤每一個重要處理步驟的耗時情況。這是很容易做到的,只需記錄那些可能會比較耗時的調用的開始和結束時間即可:

  • 重要的系統調用
  • 網絡請求
  • CPU密集運算
  • 連接設備的交互
  • 事務

在多線程和多進程中追蹤痕跡

在涉及到多線程或多進程的處理時,要為事務創建獨一的標識。事務初始化時創建ID,將它傳入每一個為此事務工作的部分。當記錄關於此事務的日志時,每一個部分都應該記錄下這個ID。這樣,在多個事務並行執行時,追蹤一個特定的事務會容易很多。

監控和日志相互完善

一個生產服務應該既有日志也有監控。監控提供了一種實時的對於系統狀態的統計匯總。它可以提醒你,是否一定比例的某個類型請求失敗了,是否系統正在經受不正常的流量訪問,性能是否在下降,或者其他的一些異常。在某些情況下,只是這些信息就可以為找到問題原因提供線索。不過,大多數情況下,監控警報只是為了簡單的觸發你的調查。監控將問題的症狀展現給我們。日志則針對各個事務提供了詳細的信息和狀態,這樣你才能全面的理解問題的原因。


免責聲明!

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



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