構造化ログ
ログを JSON 形式で出力し、機械的な解析・検索・集計を可能にするロギング手法
構造化ログとは
構造化ログ (Structured Logging) は、ログメッセージを人間が読むためのテキストではなく、JSON などの機械可読な形式で出力するロギング手法である。CloudWatch Logs Insights、Elasticsearch、Datadog などのログ分析ツールでのクエリ、フィルタリング、集計が格段に容易になる。
従来の非構造化ログは console.log('Failed to process order 123 for user abc') のように自由形式のテキストだった。障害調査で「特定のエラーコードが何回発生したか」を集計するには正規表現でパースする必要があり、フォーマットが少しでも変わるとパースが壊れる。構造化ログはこの問題を根本的に解決する。
非構造化ログとの比較
// ❌ 非構造化ログ: パースが困難
"2026-04-01 09:00:00 ERROR Failed to process order 123 for user abc"
// ✅ 構造化ログ: 機械的に解析可能
{"timestamp":"2026-04-01T09:00:00Z","level":"ERROR","message":"Failed to process order","orderId":"123","userId":"abc","errorCode":"PAYMENT_FAILED"}
| 観点 | 非構造化ログ | 構造化ログ |
|---|---|---|
| 検索 | 正規表現でパース | フィールド名で直接クエリ |
| 集計 | 困難 (パース精度に依存) | stats count() by errorCode で即座に集計 |
| フォーマット変更 | パーサーが壊れる | フィールド追加は後方互換 |
| 人間の可読性 | 高い | やや低い (ツールで補完) |
| ストレージ | 小さい | JSON のオーバーヘッドで 1.5〜2 倍 |
ストレージコストは増えるが、障害調査の速度向上で十分に元が取れる。本番環境で「あのエラーは今月何回起きたか」を 10 秒で回答できるか、30 分かけて grep するかの違いだ。
Lambda Powertools での実装
AWS Lambda Powertools の Logger は、構造化ログの実装を大幅に簡素化する。
console.log を直接使うと、コンテキスト情報の付与を毎回手動で行う必要があり、漏れが発生する。Powertools の Logger は一度設定すれば全ログに自動付与されるため、漏れがない。
CloudWatch Logs Insights でのクエリ
構造化ログの真価はクエリ時に発揮される。
# エラーコード別の発生回数 (過去24時間)
fields @timestamp, orderId, errorCode
| filter level = "ERROR"
| stats count() by errorCode
| sort count desc
# 特定注文の処理フローを時系列で追跡
fields @timestamp, @log, message, orderId
| filter orderId = "ORD-123"
| sort @timestamp asc
# P99 レイテンシの算出
fields @timestamp, duration
| filter message = "注文処理完了"
| stats percentile(duration, 99) as p99, avg(duration) as avg_ms
非構造化ログでは parse コマンドで正規表現パースが必要だが、構造化ログならフィールド名で直接アクセスできる。
ログに含めるべきフィールド
すべてのログに共通で含めるべきフィールドと、イベントごとに追加するフィールドを分ける。
共通フィールド (自動付与)
timestamp: ISO 8601 形式level: ERROR / WARN / INFO / DEBUGservice: サービス名function_name: Lambda 関数名function_request_id: リクエスト IDcorrelationId: 相関 ID (設定済みの場合)
イベント固有フィールド (手動付与)
- ビジネスコンテキスト:
orderId,userId,productId - エラー情報:
errorCode,errorMessage,stackTrace - パフォーマンス:
duration,itemCount
よくある失敗パターン
個人情報の混入
ログにメールアドレス、氏名、クレジットカード番号を含めてしまうケース。CloudWatch Logs はデフォルトで暗号化されるが、ログへのアクセス権を持つ全員が個人情報を閲覧できてしまう。個人情報はマスキングするか、ID のみをログに記録し、必要時に別途参照する設計にする。
ログレベルの不適切な設定
本番環境で DEBUG レベルを有効にすると、ログ量が爆発して CloudWatch Logs のコストが跳ね上がる。環境ごとにログレベルを制御する。
| 環境 | ログレベル | 理由 |
|---|---|---|
| dev | DEBUG | 開発中の詳細な動作確認 |
| stg | INFO | 統合テストの動作確認 |
| prod | WARN | コスト抑制、重要な情報のみ |
巨大なオブジェクトのログ出力
リクエストボディやレスポンス全体をログに含めると、1 ログエントリが数 KB〜数 MB になる。CloudWatch Logs の 1 イベント上限は 256 KB で、超過分は切り捨てられる。大きなペイロードは S3 に保存し、ログには S3 キーだけを記録する。
構造化ログについては関連書籍でも詳しく扱われている。