【現場完全ガイド】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_iduser_id(未ログインなら null)tenant_id(マルチテナントなら)route/path/methodstatuslatency_msexception(例外クラス)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. ダッシュボードの作り方:見る順番が決まる構成にする
ダッシュボードは「綺麗なグラフ」より、「見る順番が決まっていて迷わない」ことが重要です。おすすめの並びは次のとおりです。
- サービス全体の健康(エラー率、p95)
- 影響範囲(どのエンドポイントが遅いか、どのテナントが重いか)
- 原因候補(DB、外部API、キュー)
- 直近の変更(デプロイ、設定変更)
- 深掘り(トレースやログ検索リンク)
10. アラート設計:通知疲れを防ぐ“運用の技術”
アラートは多いほど良いわけではありません。多すぎると、結局見なくなります。現場で効くコツは次です。
- 重要度を分ける(P1/P2/P3)
- 同じ原因の連続通知は抑制する(サイレン状態を避ける)
- 閾値は「急増」と「継続」を見る(5分だけ尖るノイズを減らす)
- アラートには Runbook(見る場所、手順)へのリンクを付ける
- “誰が何をするか”を決める(夜間対応、エスカレーション)
10.1 例:Runbookに書く最低限
- 影響確認:ユーザー影響、対象機能
- 最初に見るメトリクス:p95、エラー率
- 次に見る場所:トレース、ログ
- 直近デプロイ:差分、ロールバック条件
- 一時対処:機能OFF、レート制限、メンテページ
- 恒久対処:修正、テスト追加、再発防止
11. 運用レポートのアクセシビリティ:色とグラフだけに頼らない
可観測性は“人に伝える”までがセットです。月次レポートや障害報告、ステータス更新が読みにくいと、技術者以外が理解できず、チームの意思決定が遅れます。
11.1 伝わるレポートの型
- 最初に要点(3行):何が起きたか、影響、対応状況
- 数値は必ず併記:例「p95 300ms → 900ms」
- 色に依存しない:赤/緑だけで判断させない。ラベルで「正常/注意/異常」
- グラフには短い説明:何を見れば良いか
- 用語の補足:専門用語は短い注釈を付ける
- 読み上げ前提の見出し構造:h2/h3を正しく
12. 段階導入プラン:今日から始める最小ステップ
いきなり全部は大変なので、次の順番が現実的です。
trace_idを全リクエストに付与(ログ/レスポンスに返す)- 構造化ログ(JSON)で key を固定
- メトリクス:p95、5xx、キュー遅延、外部API失敗 をダッシュボード化
- アラート:5xx急増、キュー停止、外部APIタイムアウト急増 だけ入れる
- 余裕が出たらトレーシング(OpenTelemetry)を導入し、遅い道筋を辿れるようにする
- 例外監視(Sentry等)でグルーピングと影響評価を回す
- 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等の例外監視を加えると、“遅い理由”や“増えている原因”が道筋で見えるようになり、復旧が速くなります。さらに、運用レポートをアクセシブルに整えておくと、技術者以外にも状況が伝わり、意思決定が滑らかになります。小さく始めて、少しずつ育てていきましょうね。
