第24回: 構造化ログ設計(JSONログ) — 「grep できないログ」から卒業する

章: 第8章: パフォーマンスと本番運用実践

障害が起きたとき、ログをすぐ検索できますか?

本番障害の対応中、ログを grep で探し回っても欲しい情報が見つからない——そんな経験はありませんか?

テキスト形式のログはフリーフォーマットになりがちで、特定のユーザーID・注文IDで絞り込もうとしても、フォーマットがバラバラで検索できないことがよくあります。構造化ログ(JSONログ)を採用すれば、Datadog・CloudWatch などのログ基盤で即座にフィルタ・集計ができ、障害解析の時間を大幅に短縮できます。

問題の本質と解決策

問題: テキストログは人が読むには良いですが、機械処理には向きません。大量のログから特定の条件を抽出することが難しく、運用コストが上がります。

解決策: Log::info() の第2引数(context)に業務IDや属性情報をキーバリュー形式で渡します。Laravelのログチャネルを json フォーマットにすれば、出力が自動でJSON形式になります。

テキストログ vs 構造化ログ 比較

観点 テキストログ 構造化ログ(JSON)
検索性 grep に依存、フォーマット不定 キー名で即時フィルタ可能
集計・分析 ほぼ手作業 ログ基盤で自動集計
業務IDでの追跡 埋め込み規則がバラバラ context に統一して記録
ログ基盤との連携 加工が必要 そのままインデックス可能

チェックポイント: Log::info('処理完了') だけでなく、trace_idorder_iduser_id などの業務IDを context に入れていますか?messageだけのログは障害時にほぼ役に立ちません。

実装サンプル


<?php
Log::channel('stack')->info('注文処理開始', [
    'trace_id' => $traceId,
    'order_id' => $orderId,
    'user_id' => $userId,
]);

Log::warning('在庫不足', [
    'sku' => $sku,
    'requested' => $qty,
]);

まとめ & 次のステップ

  • 構造化ログはキーバリュー形式でcontextに業務情報を付与します
  • trace_idorder_iduser_id をセットで記録すると障害追跡が格段に速くなります
  • Laravelのログチャネルを json フォーマット化するだけで基盤への連携が楽になります
  • message だけのログは検索性が低く、障害時に役立ちにくいです
  • まずは1つの重要処理に業務IDを3つ付与するところから始めましょう

次回は Sentry連携の実運用 を学びます。エラー通知だけでなくタグ設計まで含めた実践的な連携方法を解説します。

Related Articles