ログ記録と監視 は何をしますか?
ルール
- 構造化ログ:
timestamp、level、message、requestId、userId フィールドを含むJSON形式
- ログレベル:
error(重大な障害)、warn(機能低下)、info(ビジネスイベント)、debug(開発時のみ)
- Node.jsのログ記録にはPinoを使用 — 高速、構造化、デフォルトでJSON形式
- エラー追跡にはSentry: 早期に初期化し、未処理の例外をキャプチャし、ユーザーコンテキストとブレッドクラムを追加
- ログをリクエストIDで関連付ける — リクエストごとにUUIDを生成し、すべてのサービスコールに渡す
- シークレット、パスワード、トークン、完全なクレジットカード番号をログに記録しない — 機密フィールドを編集する
- 個々のエラーではなく、エラーレートのスパイクに対してアラートを発行する — しきい値を使用(例: 5分間でエラーレートが5%を超えた場合)
- Axiom/Datadog: OTLPまたはネイティブSDKを介してログを送信し、ビジネスKPIのカスタムメトリクスを追加
- ヘルスチェックエンドポイント:
GET /health が { status: "ok" } とDB接続確認を返す
- p50、p95、p99のレスポンスタイムを監視 — p95の悪化にアラート
パターン
import pino from "pino";
const logger = pino({ level: process.env.LOG_LEVEL || "info" });
logger.info({ userId, action: "checkout", orderId }, "注文完了");
logger.error({ err, requestId }, "支払い処理に失敗");
import * as Sentry from "@sentry/nextjs";
Sentry.init({ dsn: process.env.SENTRY_DSN, tracesSampleRate: 0.1 });
避けるべきこと
- 本番環境での
console.log — 代わりに構造化ロガーを使用する
- すべてのリクエスト本文をログに記録する — ペイロードではなく要約を記録する
- 未処理のPromise拒否を無視する — 常にキャプチャする
- ノイズの多いアラートによるアラート疲れ — しきい値を調整し、類似のエラーをグループ化する