LESSON 30分

ストーリー

高橋アーキテクト
ログ基盤は整った。次は”ログを使って問題を解決する力”を身につけよう

高橋アーキテクトがホワイトボードに書いた。

高橋アーキテクト
障害調査はパターンがある。闇雲にログを眺めるのではなく、体系的なアプローチで原因に素早くたどり着く方法を教えよう

障害調査の基本フロー

graph TD
    S1["Step 1: 影響範囲の把握<br/>どのサービス? どのエンドポイント? どのユーザー?"]
    S2["Step 2: タイムラインの特定<br/>いつから始まった? 何がトリガー?"]
    S3["Step 3: エラーパターンの分析<br/>同じエラーが繰り返されている? 特定の条件?"]
    S4["Step 4: 相関関係の発見<br/>直前にデプロイがあった? 外部サービスの障害?"]
    S5["Step 5: 根本原因の特定<br/>コード? 設定? インフラ? 外部依存?"]

    S1 --> S2 --> S3 --> S4 --> S5

実践テクニック

1. traceIdによるリクエスト追跡

// 1つのリクエストに関するすべてのログを取得
// CloudWatch Logs Insights
const traceQuery = `
  fields @timestamp, service, level, message, duration
  | filter traceId = "abc123def456"
  | sort @timestamp asc
`;

// 結果例:
// 10:30:45.100  api-gateway    INFO   "Received POST /orders"
// 10:30:45.105  auth-service   INFO   "Token validated"          12ms
// 10:30:45.120  order-service  INFO   "Creating order ORD-001"
// 10:30:45.135  order-service  INFO   "Validating inventory"
// 10:30:45.200  inventory-svc  WARN   "Low stock for SKU-042"    65ms
// 10:30:45.250  payment-svc    INFO   "Charging payment"
// 10:30:48.250  payment-svc    ERROR  "Payment timeout"          3000ms ← ここ!
// 10:30:48.260  order-service  ERROR  "Order creation failed"

2. 時系列でのエラー集計

// エラースパイクの検出
const errorSpikeQuery = `
  fields @timestamp
  | filter level = "ERROR"
  | stats count(*) as errorCount by bin(5m)
  | sort @timestamp asc
`;

// 結果例:
// 10:00  errorCount: 3
// 10:05  errorCount: 2
// 10:10  errorCount: 145  ← スパイク発生!
// 10:15  errorCount: 230
// 10:20  errorCount: 180

3. エラーコード別の集計

// エラーの種類を把握
const errorBreakdown = `
  fields errorCode, message
  | filter level = "ERROR"
  | filter @timestamp >= "2025-01-15T10:00:00Z"
  | stats count(*) as cnt by errorCode
  | sort cnt desc
`;

// 結果例:
// PAYMENT_TIMEOUT:    180
// CONNECTION_REFUSED:  45
// VALIDATION_ERROR:    12
// UNKNOWN:             3

4. デプロイとの相関

// デプロイイベントのログ
const deploymentCorrelation = `
  fields @timestamp, message, version
  | filter service = "deployment-system"
  | filter @timestamp >= "2025-01-15T09:00:00Z"
  | sort @timestamp asc
`;

// デプロイ直後にエラーが増えていないか確認
// 09:55 "Deployed payment-service v2.3.1"
// 10:10 エラースパイク開始 → v2.3.1のバグが原因の可能性大

ログベースのアラート設計

// エラー率ベースのアラート
interface LogBasedAlert {
  name: string;
  query: string;
  threshold: number;
  window: string;
  severity: 'warning' | 'critical';
  actions: string[];
}

const alerts: LogBasedAlert[] = [
  {
    name: 'High Error Rate',
    query: 'filter level="ERROR" | stats count(*) as errors by bin(5m)',
    threshold: 50,           // 5分間で50件以上
    window: '5m',
    severity: 'critical',
    actions: ['slack-oncall', 'pagerduty'],
  },
  {
    name: 'Payment Failures',
    query: 'filter service="payment" and level="ERROR" | stats count(*) by bin(1m)',
    threshold: 10,
    window: '1m',
    severity: 'critical',
    actions: ['slack-oncall', 'pagerduty'],
  },
  {
    name: 'Unusual Warn Spike',
    query: 'filter level="WARN" | stats count(*) as warns by bin(10m)',
    threshold: 200,
    window: '10m',
    severity: 'warning',
    actions: ['slack-monitoring'],
  },
];

トラブルシューティングのアンチパターン

アンチパターン問題正しいアプローチ
ログなしデバッグ勘に頼った原因推測ログデータに基づく分析
grep地獄サーバーごとに手動検索集中ログ管理で横断検索
後出しログ障害後にログを追加して再デプロイ事前に十分なログを仕込む
ログの海大量のログで重要情報が埋没ログレベルとフィルタリングの適切な設定
コンテキスト不足"Error occurred" だけのログorderId、userId等のコンテキスト付与

まとめ

ポイント内容
調査フロー影響範囲 → タイムライン → パターン → 相関 → 根本原因
traceId追跡1リクエストの全ログを時系列で確認
集計分析エラースパイク、エラーコード別集計
相関分析デプロイ、外部サービスとの関連

チェックリスト

  • 障害調査の基本フロー(5ステップ)を説明できる
  • traceIdを使ったリクエスト追跡ができる
  • エラーの時系列集計でスパイクを検出できる
  • ログベースのアラート設計ができる

次のステップへ

次は演習「ログ基盤を設計しよう」です。これまで学んだ知識を使って、実際にログ基盤を設計してみましょう。


推定読了時間: 30分