logging-best-practices

logging-best-practices

熱門

專注於寬事件(標準日誌行)的日誌記錄最佳實踐,以實現強大的除錯與分析能力

104星標
10分支
更新於 2026/1/21
SKILL.md
唯讀
名稱
logging-best-practices
描述

專注於寬事件(標準日誌行)的日誌記錄最佳實踐,以實現強大的除錯與分析能力

日誌記錄最佳實踐技能

版本:1.0.0

目的

本技能提供在應用程式中實現有效日誌記錄的指南。重點在於寬事件(也稱為標準日誌行)——一種針對每個請求、每個服務發出單一、富含上下文的事件的模式,從而實現強大的除錯與分析能力。

何時應用

在以下情況應用這些指南:

  • 撰寫或審查日誌記錄程式碼時
  • 加入 console.log、logger.info 或類似指令時
  • 為新服務設計日誌記錄策略時
  • 設定日誌記錄基礎設施時

核心原則

1. 寬事件(關鍵)

針對每個請求、每個服務發出一個富含上下文的事件。與其在處理程式中散落多行日誌,不如將所有資訊整合到一個結構化事件中,並在請求完成時發出。

const wideEvent: Record<string, unknown> = {
  method: 'POST',
  path: '/checkout',
  requestId: c.get('requestId'),
  timestamp: new Date().toISOString(),
};

try {
  const user = await getUser(c.get('userId'));
  wideEvent.user = { id: user.id, subscription: user.subscription };

  const cart = await getCart(user.id);
  wideEvent.cart = { total_cents: cart.total, item_count: cart.items.length };

  wideEvent.status_code = 200;
  wideEvent.outcome = 'success';
  return c.json({ success: true });
} catch (error) {
  wideEvent.status_code = 500;
  wideEvent.outcome = 'error';
  wideEvent.error = { message: error.message, type: error.name };
  throw error;
} finally {
  wideEvent.duration_ms = Date.now() - startTime;
  logger.info(wideEvent);
}

2. 高基數與高維度(關鍵)

包含高基數欄位(使用者 ID、請求 ID——數百萬個唯一值)和高維度欄位(每個事件多個欄位)。這使得能夠按特定使用者進行查詢,並回答你尚未預料到的問題。

3. 業務上下文(關鍵)

始終包含業務上下文:使用者訂閱層級、購物車價值、功能開關、帳戶年齡。目標是了解「一位高級客戶無法完成一筆 2,499 美元的購買」,而不僅僅是「結帳失敗」。

4. 環境特徵(關鍵)

在每個事件中包含環境和部署資訊:提交雜湊、服務版本、區域、實例 ID。這使得能夠將問題與部署關聯起來,並識別特定區域的問題。

5. 單一日誌記錄器(高)

使用一個在啟動時配置的日誌記錄器實例,並在各處匯入。這確保了統一的格式和自動的環境上下文。

6. 中介軟體模式(高)

使用中介軟體處理寬事件基礎設施(計時、狀態、環境、發送)。處理程式應僅添加業務上下文。

7. 結構與一致性(高)

  • 一致地使用 JSON 格式
  • 跨服務保持統一的欄位名稱
  • 簡化為兩個日誌級別:infoerror
  • 絕不記錄非結構化字串

應避免的反模式

  1. 散落的日誌:每個請求多個 console.log() 呼叫
  2. 多個日誌記錄器:不同檔案中使用不同的日誌記錄器實例
  3. 缺少環境上下文:沒有提交雜湊或部署資訊
  4. 缺少業務上下文:記錄技術細節但沒有使用者/業務資料
  5. 非結構化字串:使用 console.log('something happened') 而非結構化資料
  6. 不一致的結構:跨服務使用不同的欄位名稱

指南

寬事件(rules/wide-events.md

  • 每個服務跳躍發出一個寬事件
  • 包含所有相關上下文
  • 使用請求 ID 連接事件
  • 在 finally 區塊中於請求完成時發出

上下文(rules/context.md

  • 支援高基數欄位(user_id、request_id)
  • 包含高維度(多個欄位)
  • 始終包含業務上下文
  • 始終包含環境特徵(commit_hash、version、region)

結構(rules/structure.md

  • 在整個程式碼庫中使用單一日誌記錄器
  • 使用中介軟體實現一致的寬事件
  • 使用 JSON 格式
  • 保持一致的結構
  • 簡化為 info 和 error 級別
  • 絕不記錄非結構化字串

常見陷阱(rules/pitfalls.md

  • 避免每個請求多行日誌
  • 為未知的未知設計
  • 始終跨服務傳播請求 ID

參考資料: