Laravel Telescopeを使った開発中のデバッグとモニタリング

Laravel Telescopeを使った開発中のデバッグとモニタリング

Laravel Telescopeは、開発中のアプリケーション内部で何が起きているかを可視化するための公式デバッグツール。HTTPリクエスト、例外、ログ、SQL、キュー、イベント、メール、通知、キャッシュ操作などをブラウザ上で一覧できるため、「どこで失敗したのか」「なぜ遅いのか」「想定外の副作用が起きていないか」を短時間で切り分けやすくなる。dd() やログ出力だけでは追いにくい処理の流れを、1つの画面でまとめて確認できるのが最大の強みになる。

Laravel Telescopeで何が見えるのか

Telescopeで確認できる代表的な情報は次の通り。
・リクエストURL、メソッド、入力値、レスポンス
・例外内容とスタックトレース
・実行されたSQLと所要時間
・送信されたメール
・発行された通知
・実行されたジョブと失敗ジョブ
・ログ出力
・イベントやキャッシュの動作
つまり、開発中に「アプリの内部で何が起きたか」を横断的に確認できる。特に、Controllerだけではなく、Queue、Mail、Notification、Modelイベントまで追える点が便利。

Telescopeが向いている場面

Telescopeが特に役立つのは、次のようなケース。
・フォーム送信後にどこで失敗しているか分からない
・APIレスポンスが遅い原因を調べたい
・N+1問題や重いSQLを見つけたい
・ジョブが失敗している理由を確認したい
・メールや通知が本当に送られているか見たい
・ログや例外をブラウザ上でまとめて確認したい
逆に、本番監視の主役というよりは、開発・検証中の観測強化に向いている。

インストール手順

まずはパッケージを導入し、初期セットアップを行う。

composer require laravel/telescope

php artisan telescope:install
php artisan migrate

インストール後は通常 /telescope にアクセスするとダッシュボードを確認できる。
エラーの発生条件としては、次のようなものが多い。
・マイグレーション未実行でTelescope用テーブルが無い
・DB接続エラーで記録できない
・ローカル限定設定なのに別環境で見ようとしている
・設定キャッシュが古くて provider が正しく読み込まれていない

ローカル環境だけで有効にする構成

Telescopeは便利だが、開発中の詳細情報を大量に保持するため、まずはローカル専用にするのが安全。
開発依存として導入したい場合は次のようにする。

composer require laravel/telescope --dev

必要に応じて、アプリケーション側で local 環境のみ読み込むようにしておく。

// app/Providers/AppServiceProvider.php
public function register(): void
{
    if ($this->app->environment('local') && class_exists(\Laravel\Telescope\TelescopeServiceProvider::class)) {
        $this->app->register(\Laravel\Telescope\TelescopeServiceProvider::class);
        $this->app->register(\App\Providers\TelescopeServiceProvider::class);
    }
}

この構成にしておくと、誤って本番で有効化するリスクを減らせる。

最初に見るべき画面

Telescopeを使い始めたら、まずは次の3つを見ると使い道が分かりやすい。
・Requests
・Exceptions
・Queries
Requestsでは、どのURLにどんな入力が送られ、どんなレスポンスが返ったかが分かる。
Exceptionsでは、例外の内容と発生箇所を確認できる。
Queriesでは、実行されたSQLと所要時間が見える。
この3つだけでも、バリデーションエラー、500エラー、SQLの遅さなどの切り分けがかなり速くなる。

Request Watcherの活用

Request Watcherでは、HTTPメソッド、URL、ヘッダ、入力パラメータ、レスポンス内容を確認できる。
たとえば「フォームから送った値が想定と違う」「JavaScript側でJSON構造が崩れている」「APIのレスポンスがなぜか空」などの調査に強い。
入力名のtypoや、POSTだと思っていたのにGETで飛んでいたといったミスも発見しやすい。

設定例。

// config/telescope.php
'watchers' => [
    \Laravel\Telescope\Watchers\RequestWatcher::class => [
        'enabled' => env('TELESCOPE_REQUEST_WATCHER', true),
        'size_limit' => env('TELESCOPE_RESPONSE_SIZE_LIMIT', 64),
    ],
],

エラーの発生条件としては、レスポンスサイズが大きすぎて確認しづらくなるケースや、機密データをそのまま記録してしまうケースがある。必要なら記録対象を絞った方がよい。

Query Watcherで遅いSQLやN+1を見つける

一覧画面やAPIが遅いときは、Query Watcherが非常に役立つ。
実行されたSQL文、バインド値、実行時間が一覧で見えるため、「どのクエリが遅いのか」「同じクエリが大量に繰り返されていないか」をすぐ確認できる。
N+1が起きている場合は、似たようなSQLが何十件も並ぶため気づきやすい。

設定例。

// config/telescope.php
'watchers' => [
    \Laravel\Telescope\Watchers\LogWatcher::class => [
        'enabled' => env('TELESCOPE_LOG_WATCHER', true),
        'level' => 'debug',
    ],
],

ここでの発生条件として多いのは、with() を付けていないリレーション参照、select * の多用、ページング無しの大量取得など。Telescopeは原因を見つける入口として非常に有効。

Exception Watcherで例外の流れを追う

Exception Watcherでは、例外内容だけでなく、「どのリクエストで発生したか」「その直前に何が起きていたか」を追いやすい。
ログファイルだけを追うよりも、Requestとセットで確認できるのが強い。
特に、認証エラー、権限エラー、Null参照、SQL例外、外部API失敗などが混在している画面では役に立つ。

たとえば次のような問題を切り分けやすい。
・ログイン中なのに403になる
・フォーム送信後だけ500になる
・特定のレコードだけ保存失敗する
・あるリクエストだけ外部APIエラーになる

Job Watcherで非同期処理を確認する

Laravelのジョブキューを使っている場合、Job Watcherは重要になる。
ジョブが dispatch されたか、成功したか、失敗したかをブラウザから確認できるため、「ジョブが投げられていない」のか「投げられたけど失敗した」のかを分けて考えやすい。
メール送信やCSV生成、外部連携などをキューに逃がしているプロジェクトでは特に便利。

発生しやすい問題は次のようなもの。
・ジョブ自体が dispatch されていない
・ワーカー未起動で処理が進んでいない
・ジョブが毎回例外で失敗している
・重いジョブだけ極端に遅い

Mail WatcherとNotification Watcherの使いどころ

Mail Watcherでは、送信されたメールの宛先・件名・本文を確認できる。
Notification Watcherでは、通知がどのチャネルで送られたかを追える。
「メールが送られたはずなのに届かない」「通知本文のデータが崩れている」などの確認に向いている。

たとえば次のような場面で役立つ。
・登録完了メールの件名や本文をチェックしたい
・通知が本当に発火しているか確かめたい
・意図せず同じメールが複数回送られていないか見たい

本番用のメール送信設定に依存せず、開発画面で確認できるのが利点。

Log Watcherでlogger()出力を時系列で追う

TelescopeのLog Watcherを使うと、logger()->info()logger()->error() の出力をリクエスト文脈と一緒に確認できる。
ログファイル全体から grep するよりも、そのリクエストに関連したログだけを見られるため、調査効率が上がる。

設定例。

// config/telescope.php
'watchers' => [
    \Laravel\Telescope\Watchers\LogWatcher::class => [
        'enabled' => env('TELESCOPE_LOG_WATCHER', true),
        'level' => 'debug',
    ],
],

debugレベルまで広げると情報量が多くなりすぎることがあるため、開発中にだけ有効にする方が扱いやすい。

Model WatcherでEloquentの変化を追う

Model Watcherを使うと、どのモデルが作成・更新・削除されたかを確認できる。
「意図しない更新が起きている」「保存したつもりがDBに入っていない」といったときに役立つ。
特に、Observerやイベント経由で副作用が多いプロジェクトでは効果が高い。

設定例。

// config/telescope.php
'watchers' => [
    \Laravel\Telescope\Watchers\ModelWatcher::class => [
        'enabled' => env('TELESCOPE_MODEL_WATCHER', true),
        'events' => ['eloquent.created*', 'eloquent.updated*'],
        'hydrations' => true,
    ],
],

ただし、記録対象が多すぎるとノイズが増えるため、イベント種別は絞る方が見やすい。

Filter機能でノイズを減らす

Telescopeは便利な反面、何でも記録すると情報量が膨れ上がる。
そのため、必要なデータだけを残すフィルタ運用が大事になる。
たとえば次のような考え方がある。
・例外が発生したリクエストだけ残す
・遅いクエリが含まれるものだけ残す
・ローカル環境だけ全件、共有検証環境は一部だけ残す

大量のエントリが溜まると、逆に「欲しい情報が埋もれる」状態になるので、Telescopeは“全部見る”より“価値ある情報を残す”方が実務向き。

Prune運用で肥大化を防ぐ

Telescopeは内部テーブルに記録を蓄積するため、放置するとデータが増え続ける。
長く使う場合は定期的に prune して古いエントリを削除する。

// スケジュール定義例
use Illuminate\Support\Facades\Schedule;

Schedule::command('telescope:prune')->daily();

共有の検証環境や長期間使うローカル環境では、これを入れておかないと telescope_entries が膨らみ、管理しづらくなる。

よくあるエラーと発生条件

Telescope導入時によく起きる問題は次の通り。
/telescope が404
発生条件:インストール未完了、provider未登録、local限定設定
・画面は出るがデータが無い
発生条件:watcher無効、DB接続不良、設定キャッシュ不整合
・Telescope自体が重い
発生条件:watcherを全部有効、ログ量が多すぎる、レスポンス記録が大きすぎる
・共有環境で情報が漏れる
発生条件:認可制御なしで /telescope を開放している
こうした問題を避けるためにも、開発環境中心で使い、認可や prune をセットで考えるのが安全。

まとめ

Laravel Telescopeは、開発中のデバッグとモニタリングをまとめて強化できる強力なツール。
特に、Requests、Exceptions、Queries、Jobs、Logs を中心に使うと、エラーや遅延の原因特定がかなり速くなる。
一方で、記録量が増えすぎると逆に見づらくなるため、watcherの有効化範囲、フィルタ、prune運用まで含めて設計することが重要になる。
単なる「便利な画面」ではなく、「調査の時間を減らすための観測基盤」として使うと価値が大きい。