php elephant sticker
Photo by RealToughCandy.com on Pexels.com
目次

【現場完全ガイド】Laravelの可観測性(Observability)――構造化ログ、メトリクス、トレーシング(OpenTelemetry)、Sentry、ダッシュボード、アラート設計とアクセシブルな運用レポート

この記事で学べること(要点)

  • 「ログだけ」から卒業し、障害対応を速くする可観測性(Logs/Metrics/Traces)の全体像
  • Laravelでの構造化ログ(JSON)と、trace_id/request_id の統一運用
  • 遅い原因を辿る分散トレーシング(OpenTelemetry)の考え方と導入パターン
  • 重要メトリクス(p95/エラー率/キュー遅延/外部API失敗)を決める方法
  • アラート設計(通知疲れを防ぐ閾値、抑制、エスカレーション、Runbook)
  • 監視ダッシュボードの作り方(“見る順番”が決まる構成)
  • 可観測性レポートのアクセシビリティ(色に依存しない、読み上げでも理解できる、要点サマリ)

想定読者(だれが得をする?)

  • Laravel 初〜中級エンジニア:障害時に「どこから見ればいいか分からない」状態を卒業したい方
  • テックリード/運用担当:MTTR(復旧時間)を短縮し、アラート疲れを減らしたい方
  • PM/CS:障害報告や月次レポートを、技術と利用者の両方に伝わる形に整えたい方
  • QA/アクセシビリティ担当:運用画面・レポート・ステータス通知を“誰でも分かる”表現に統一したい方

アクセシビリティレベル:★★★★★

ダッシュボードや障害報告は「色やグラフ」だけで伝えると、理解に差が出やすい領域です。要点サマリ、数値の併記、状態ラベル、読み上げ可能な構造、キーボード操作での閲覧を前提にした設計を含めます。


1. はじめに:可観測性は「障害をゼロにする」より「迷わず直す」ための仕組みです

本番運用では、障害は完全には避けられません。外部APIの不調、DBの負荷、デプロイ差分、思わぬ入力データ、ネットワーク揺れなど、原因は多岐にわたります。ここで大切なのは、障害を見つける速さと、原因に辿り着く速さです。つまり「復旧までの道筋が見える」状態を作ることです。

Laravelはログや例外処理が整っている反面、「ログが散らばる」「検索しづらい」「遅い理由が追えない」「アラートが多すぎる」になりやすい面もあります。本記事では、Logs/Metrics/Traces の基本を押さえつつ、Laravelに落とし込める現場の型を、段階的に紹介しますね。


2. 可観測性の三本柱:Logs / Metrics / Traces

可観測性は、よく「三本柱」で語られます。

  • Logs(ログ)
    • 何が起きたかの記録。原因調査の“文章と証拠”
  • Metrics(メトリクス)
    • どれくらい起きているかの数値。異常検知の“体温計”
  • Traces(トレース)
    • どこで遅くなったかの道筋。分散環境での“地図”

ログは詳細、メトリクスは傾向、トレースは経路、という役割分担です。ログだけだと「遅い理由」が追いにくく、メトリクスだけだと「原因」が見えません。現場ではまず、メトリクスで異常を検知し、トレースで遅い箇所を特定し、ログで証拠を固める、という流れが安定します。


3. まずは土台:trace_id を“全て”に通す

障害対応で一番効く小さな施策は、trace_id(または request_id)を全リクエストに付け、ログ・APIレスポンス・画面・ジョブに渡すことです。これだけで「問い合わせ→調査」の往復が激減します。

3.1 方針(おすすめ)

  • リクエスト開始時に trace_id を生成(または受け取る)
  • レスポンスヘッダーに X-Trace-Id を返す
  • 例外ログ、外部APIログ、ジョブログにも同じ trace_id を入れる
  • 画面のエラーページやサポート案内に trace_id を表示(必要時のみ)

画面に表示するときは、個人情報のように扱いすぎる必要はありませんが、問い合わせ時の照合に便利なので「この番号をお知らせください」という形にしておくと親切です。


4. 構造化ログ:人間にも機械にも読みやすくする

ログが“文章”だと検索がつらくなります。現場では JSON 形式の構造化ログがとても強いです。最低限、次のキーがあると検索が速いです。

  • trace_id
  • user_id(未ログインなら null)
  • tenant_id(マルチテナントなら)
  • route / path / method
  • status
  • latency_ms
  • exception(例外クラス)
  • job(ジョブ名、対象ID)

4.1 PII(個人情報)をログに残さない

ログの原則は「IDまで」。メールアドレス、住所、カード情報、トークンなどは出さないのが基本です。どうしても必要ならマスクして残します。


5. メトリクス:最初に見るべき数字を“少なく”決める

メトリクスは多すぎると、どれも見なくなります。まずは“サービスの健康状態”を表す最小セットから始めるのがおすすめです。

5.1 最小セット(おすすめ)

  • リクエストレイテンシ(p50/p95/p99)
  • エラー率(5xx、4xx、429)
  • キュー遅延(待ち時間、失敗数)
  • DB(スロークエリ数、接続数、ロック待ち)
  • 外部API(失敗率、タイムアウト数、p95)

5.2 しきい値は「急増」を見る

絶対値だけでアラートを出すと、日内変動で鳴りやすいです。最初は「急増(前週同時刻比、直近平均比)」のような相対指標が扱いやすいです。


6. トレーシング:遅い理由を“道筋”で辿る(OpenTelemetry)

トレーシングは「このリクエストはどこで時間を使った?」を追う仕組みです。画面が遅いとき、原因は次のどれかであることが多いです。

  • DBクエリが遅い
  • 外部APIが遅い
  • キュー待ち(非同期の完了待ち)
  • テンプレートレンダリングが重い
  • キャッシュが効いていない

トレーシングがあると、これが一本のタイムラインで見えます。Laravel単体でも有効ですが、特に「別サービス(検索、決済、通知、画像処理)と連携する」ほど価値が上がります。

6.1 OpenTelemetry の考え方(ざっくり)

  • Trace:1リクエストの全体
  • Span:Traceの中の区間(DB、HTTP、処理ブロックなど)
  • Attributes:Spanに付ける情報(SQL種別、URL、tenant_idなど)

導入は段階的で大丈夫です。まずは

  • HTTPリクエスト
  • DBクエリ
  • 外部HTTP
    の3種類がSpanとして取れるだけでも、体感が変わります。

7. 例外監視(Sentryなど):重複をまとめて“重要”に集中する

例外監視は「ログにある例外」を、集計・グルーピングして、発生頻度や影響を見せてくれる仕組みです。Laravelの例外をそのまま通知するとノイズが増えるので、次の方針にすると運用が落ち着きます。

  • バリデーション(422)は通知しない(ノイズになりやすい)
  • 404は基本通知しない(攻撃/リンク切れで増えがち)
  • 500系は通知する
  • ただし、突然増えた 401/403/429 は“異常”として見る価値がある(認証障害や誤実装の兆候)

「何でも通知」より、「見る価値があるものだけ通知」が正解になりやすいです。


8. キューとスケジューラの可観測性:裏側が止まると気づきにくい

キューやスケジューラは、画面が動いていても止まりがちです。特に問い合わせが増えるのは次のケースです。

  • メールが届かない(ワーカー停止)
  • エクスポートが終わらない(ジョブ詰まり)
  • 夜間バッチが回っていない(cron不備)

ここはメトリクスとアラートで守ると安心です。

  • キューの待ち時間が一定以上
  • 失敗ジョブが急増
  • スケジューラのハートビート(毎日/毎時の “alive” ログ)が来ない

この3点だけでも、裏側停止に早く気づけます。


9. ダッシュボードの作り方:見る順番が決まる構成にする

ダッシュボードは「綺麗なグラフ」より、「見る順番が決まっていて迷わない」ことが重要です。おすすめの並びは次のとおりです。

  1. サービス全体の健康(エラー率、p95)
  2. 影響範囲(どのエンドポイントが遅いか、どのテナントが重いか)
  3. 原因候補(DB、外部API、キュー)
  4. 直近の変更(デプロイ、設定変更)
  5. 深掘り(トレースやログ検索リンク)

10. アラート設計:通知疲れを防ぐ“運用の技術”

アラートは多いほど良いわけではありません。多すぎると、結局見なくなります。現場で効くコツは次です。

  • 重要度を分ける(P1/P2/P3)
  • 同じ原因の連続通知は抑制する(サイレン状態を避ける)
  • 閾値は「急増」と「継続」を見る(5分だけ尖るノイズを減らす)
  • アラートには Runbook(見る場所、手順)へのリンクを付ける
  • “誰が何をするか”を決める(夜間対応、エスカレーション)

10.1 例:Runbookに書く最低限

  • 影響確認:ユーザー影響、対象機能
  • 最初に見るメトリクス:p95、エラー率
  • 次に見る場所:トレース、ログ
  • 直近デプロイ:差分、ロールバック条件
  • 一時対処:機能OFF、レート制限、メンテページ
  • 恒久対処:修正、テスト追加、再発防止

11. 運用レポートのアクセシビリティ:色とグラフだけに頼らない

可観測性は“人に伝える”までがセットです。月次レポートや障害報告、ステータス更新が読みにくいと、技術者以外が理解できず、チームの意思決定が遅れます。

11.1 伝わるレポートの型

  • 最初に要点(3行):何が起きたか、影響、対応状況
  • 数値は必ず併記:例「p95 300ms → 900ms」
  • 色に依存しない:赤/緑だけで判断させない。ラベルで「正常/注意/異常」
  • グラフには短い説明:何を見れば良いか
  • 用語の補足:専門用語は短い注釈を付ける
  • 読み上げ前提の見出し構造:h2/h3を正しく

12. 段階導入プラン:今日から始める最小ステップ

いきなり全部は大変なので、次の順番が現実的です。

  1. trace_id を全リクエストに付与(ログ/レスポンスに返す)
  2. 構造化ログ(JSON)で key を固定
  3. メトリクス:p95、5xx、キュー遅延、外部API失敗 をダッシュボード化
  4. アラート:5xx急増、キュー停止、外部APIタイムアウト急増 だけ入れる
  5. 余裕が出たらトレーシング(OpenTelemetry)を導入し、遅い道筋を辿れるようにする
  6. 例外監視(Sentry等)でグルーピングと影響評価を回す
  7. Runbookとレポートのテンプレを整備

13. よくある落とし穴と回避策

  • ログが多すぎて探せない
    • 回避:構造化ログ+キー固定+trace_idで絞る
  • 例外通知が多すぎて麻痺する
    • 回避:通知対象を絞る、急増のみアラート、Runbook付き通知
  • メトリクスが多すぎて見ない
    • 回避:最小セットに絞り、重要画面のp95/エラー率から始める
  • グラフだけで説明がない
    • 回避:要点サマリと数値差分を必ず併記(アクセシビリティにも効きます)
  • 可観測性が“導入して終わり”になる
    • 回避:毎月1回でも「振り返り」をやり、アラートとダッシュボードを育てる

14. チェックリスト(配布用)

土台

  • [ ] trace_id を全リクエストで生成/伝搬し、レスポンスにも返す
  • [ ] 構造化ログ(JSON)で trace_id/user_id/path/status/latency_ms を固定
  • [ ] PIIやトークンをログに出さない方針がある

メトリクス

  • [ ] p50/p95/p99 のレイテンシ
  • [ ] 5xx/4xx/429 のエラー率
  • [ ] キューの待ち時間と失敗数
  • [ ] 外部APIの失敗率とタイムアウト
  • [ ] DBのスロークエリ/ロック

アラート

  • [ ] 重要度(P1/P2/P3)と通知先が決まっている
  • [ ] 重大アラートにRunbookリンクがある
  • [ ] 通知抑制(同一原因の連続通知)がある

トレーシング

  • [ ] HTTP/DB/外部HTTPのSpanが取れる
  • [ ] trace_id からトレースへ飛べる導線がある

アクセシビリティ(レポート/運用画面)

  • [ ] 要点サマリ(3行)が最初にある
  • [ ] 数値を必ず併記し、色だけに依存しない
  • [ ] 見出し構造が正しく、読み上げで理解できる

15. まとめ

Laravelの可観測性は、難しい道具をいきなり全部入れるより、「trace_id」「構造化ログ」「最小メトリクス」「厳選アラート」の4点を先に固めると、驚くほど運用が落ち着きます。そこからOpenTelemetryのトレーシングやSentry等の例外監視を加えると、“遅い理由”や“増えている原因”が道筋で見えるようになり、復旧が速くなります。さらに、運用レポートをアクセシブルに整えておくと、技術者以外にも状況が伝わり、意思決定が滑らかになります。小さく始めて、少しずつ育てていきましょうね。


参考リンク

投稿者 greeden

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)