Log Level

Posted by Adam on August 24, 2022
### Log 使用的時機 1. 確認部署程式是否存在本次開發的內容(e.g. 寫在 Controller 中) 1. 拋出「可預期的錯誤」之前,詳述如何修正此錯誤 1. 處理所有「IO 項目」時,盡可能列出相關資訊 1. 任何你覺得「可能」會發生問題的段落 --- 1. TRACE: 最低層級的log,通常用於非常詳細的追蹤資訊,例如追蹤某個方法的執行細節,通常用於開發和測試階段。 2. DEBUG: 用於除錯目的的詳細log,一般開發者會在開發階段使用以追蹤程式的執行狀態。 3. INFO: 用於較重要的資訊,例如程式啟動和結束時的訊息,或者重要事件的發生。在產品環境中,通常會記錄到INFO級別的日誌。 4. WARN: 用於警告訊息,可能會導致潛在問題的情況,但不會影響系統運行。程式在運行過程中可能會產生警告。 5. ERROR: 用於錯誤訊息,程式執行過程中發生錯誤,可能導致系統崩潰或功能失效。通常會在這個層級下記錄程式運行時的異常情況。 --- # 📘 Spring Boot 專案 Logging 使用規範 適用於 Java / Spring Boot 專案,用於規範團隊使用 log 的層級與內容,協助除錯與維運。 --- ## 🔧 Log 等級定義與用途 | 等級 | 用途說明 | 實務情境 | | ------- | ----------------------------- | ---------------- | | `ERROR` | 無法繼續處理、需立即修正的錯誤 | 資料庫無法連線、空指標例外等 | | `WARN` | 可繼續執行但值得注意的狀況 | 不合法參數、自動修正的資料格式 | | `INFO` | 正常流程中重要業務資訊(推薦保留於 production) | 使用者登入成功、排程任務執行 | | `DEBUG` | 詳細除錯訊息(開發測試用,production 預設關閉) | 請求參數、回應格式、處理流程追蹤 | | `TRACE` | 最細節執行流程,通常不建議使用 | 方法進出記錄、極細除錯場景 | --- ## ✅ 使用範例與建議 ### `INFO` 範例:流程節點 ```java logger.info("User [{}] login success", username); logger.info("Order [{}] created by user [{}]", orderId, userId); logger.info("Sync job started at {}", LocalDateTime.now()); ``` * 適用:登入、下單、排程、資料匯入等「使用者可感知事件」 * 建議格式:**動詞 + 對象 + 關鍵欄位** --- ### `DEBUG` 範例:內部執行細節 ```java logger.debug("Received payload: {}", requestBody); logger.debug("Retry attempt [{}] failed for task [{}]", attempt, taskId); logger.debug("Calculated amount: {} for user: {}", amount, userId); ``` * 適用:參數檢查、流程邏輯追蹤、迴圈處理、API 呼叫細節 * 記得避免輸出密碼、Token、身分證等機敏資料 --- ### `ERROR` 與 `WARN` 範例 ```java try { userRepository.save(user); } catch (DataAccessException e) { logger.error("無法儲存使用者:{},原因:{}", user.getId(), e.getMessage(), e); throw new UserSaveException("使用者儲存失敗", e); } if (!isValidEmail(email)) { logger.warn("收到不合法 Email:{}", email); } ``` --- ## 📂 實務環境建議設定 | 環境 | 預設 Log 等級 | 原因 | | --------- | --------- | ----------------- | | `dev` | `DEBUG` | 可查看所有除錯細節 | | `test` | `DEBUG` | 單元測試與整合測試環境 | | `staging` | `INFO` | 模擬正式環境,追蹤主要業務流程 | | `prod` | `INFO` | 最小限度留存必要資訊,避免過度輸出 | 可在 `application.yml` 中設定: ```yaml logging: level: root: info com.example.service: debug ``` --- ## 🎛 動態調整 log 等級(需啟用 Actuator) 啟用 actuator: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> ``` ```yaml management: endpoints: web.exposure.include: loggers ``` 使用 POST 調整等級: ```http POST /actuator/loggers/com.example.service { "configuredLevel": "DEBUG" } ``` --- ## 🧼 風格建議與禁忌 * ✅ 使用參數化寫法(避免字串拼接):`logger.info("User: {}", userId);` * ✅ 捕捉特定例外,不使用 `catch (Exception e)`,除非極特殊狀況 * ✅ 註解可加上 `JIRA` 單號,方便追蹤 * ❌ 不要 log 密碼 / token / 身分證等個資 * ❌ 不要在正式環境開啟 `debug` 或 `trace` * ❌ 過度 log 每筆資料會造成硬碟爆量,應限制輸出 --- 如需整合 Logback、外部集中 log 系統(如 ELK / Loki),可另訂 log 結構化與格式化規範。