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:
sysloglibrary - Apple: ASL (Apple System Log)
- Windows:
ReportEventAPI - Java:
java.util.loggingpackage, Apache Log4j - Python:
loggingmodule - Node.js: Bunyan, Winston
- Unix Shell:
loggercommand - Unix Kernel:
printkfunction - 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 設定記錄的主題和詳細程度