Item 41: Add Logging Statements#

Logging 語句讓你能夠追蹤和理解程式的執行過程。它們將訊息發送到輸出裝置(standard error、console、printer)或儲存在可以稍後瀏覽和分析的地方(檔案或資料庫)。

Logging 相對於 Debugger 的優勢#

有些人認為 logging 只是不會用 debugger 的人才用的方法,但 logging 其實有多項獨特優勢:

  • 精確定位:可以輕鬆放置在策略性位置,精確輸出你需要的資料
  • 持久性:debugger session 的設定是短暫的,而 logging 語句是永久的,可以投入更多心力格式化輸出
  • 可過濾與可查詢:使用正式 logging framework(而非隨意的 println)的輸出天然具有可過濾和可查詢的特性

該記錄什麼#

  • 關鍵函式的進入和離開
  • 關鍵資料結構的內容
  • 狀態變更
  • 對使用者互動的回應

Logging 層級與設定#

為避免大量 logging 對效能的影響,大多數 logging 介面允許設定訊息的重要性層級,可以在 source(程式端)或 destination(日誌設施端)進行調整。實作 debug mode(見 Item 40)可以讓你在需要時提高 logging 的詳細程度。

各平台 Logging 設施#

  • Unix: syslog library
  • Apple: ASL (Apple System Log)
  • Windows: ReportEvent API
  • Java: java.util.logging package, Apache Log4j
  • Python: logging module
  • Node.js: Bunyan, Winston
  • Unix Shell: logger command
  • Unix Kernel: printk function
  • C++: Boost.Log v2

其他 Logging 方式#

  • GUI 應用程式:彈出 popup 訊息
  • JavaScript:寫入 browser 的 console window
  • Web 應用程式:在 HTML 中塞入 logging 輸出(HTML 註解或可見文字)
  • 無法修改原始碼時:讓程式開啟一個以 log 訊息為名稱的檔案,用 strace 追蹤

當你用完 print-type logging 語句後,不要刪除它。如果刪除,你會失去建立它的工作;如果註解掉,它會隨著程式碼變更而過時。正確做法是用 conditional statement 包裝:

if (loggingEnabled)
    printf("Entering function foo\n");

Remote Logging#

對於缺少可寫檔案系統的嵌入式裝置(如高階電視或低階路由器),可以使用 remote logging,將 log 條目發送到遠端 server 儲存。

重點回顧#

  • 加入 logging 語句來建立永久、可維護的除錯基礎設施
  • 使用 logging framework 而非自行發明
  • 透過 logging framework 設定記錄的主題和詳細程度