Laravelにおけるデバッグ用パッケージ4つと具体的なデバッグ・エラーレポート手法
こんにちは。エンジニアの佐々木です。
今年の1月からジムに週1〜2のペースで行ってるんですが、ようやく5キロ減に成功しました。SOFT SKILLSにも書いてありますが、エンジニアの健康管理は本当に重要だと思うので引き続き通い続けようと思います。
さて、今回はLaravelにおけるデバッグ・エラーレポート手法についてまとめていきたいと思います。
LaravelはPHPのフレームワークなので、デバッグしたいなと思った時には伝家の宝刀 var_dump() をもちろん使うことができます。また、Xdebugでのデバッグももちろん可能です。
しかし、Laravelでは他にもデバッグに便利な専用パッケージが存在していたり、便利なヘルパーが用意されています。今回はそれらを紹介していきます。
パッケージ
パッケージで紹介したいものは4つあります。
上から順に個人的にはよくお世話になっているものです。また、主観ではありますが使うタイミングと便利度を記載しました。
一度設定してしまえばあとは勝手に動いてくれるものもありますが、これらのパッケージに関しては、基本的に開発内容に応じて使い分けることになります。
では、さっそくそれぞれ紹介していきます。
Debugbar
最初はDebugbarです。
ブログやQiitaの記事でもたくさん紹介されているので、LaravelでWeb開発をされている方であれば、このパッケージを入れている方はたくさんいらっしゃることでしょう。
導入すると、ページ下部にChromeのdevtoolsのようなデバッグ用のエリアが表示されるようになります。
ソースコード上の任意の場所での変数やオブジェクトのダンプができるのはもちろん、Eloquentで発行されたSQLの確認およびパフォーマンスのチェックができたり、特定箇所の処理速度を測りそれを表示したりと、サーバサイドでの開発を便利にしてくれる機能が豊富に揃っています。
インストールや詳しい使い方に関してはGithubのドキュメントや下記のようなページを参考にしてみてください。
参考
barryvdh/laravel-debugbar
Laravel5.6: Laravel Debugbarを使う
[開発に欠かせない Laravel Debugbar の導入]()
Collision
次はCollisionです。
Collisionはコマンドライン上のエラーレポートを見やすくするためのパッケージです。コマンドライン上でPHPUnitやartisanコマンド実行時にエラーがあった場合に、該当のソースコードが色付きで表示されるので非常に見やすくなります。
Laravel5.6からプリインストールされるようになったのですが、5.6以前のバージョンでも簡単に導入できるようになっているので、未導入の場合は導入できると作業がしやすくなると思います。
参考
PHPでエラーメッセージを更に詳細表示してくれるライブラリ「collision」
Collisionを導入して数分でエラーレポートを見やすくしよう
tinker
次はtinkerです。
tinkerはREPL(Read-eval-print loop)と呼ばれる対話型の評価環境を実現してくれるツールで、Railsでいうところのbinding.pry同等のツールになります。また、tinkerはPsyshのラッパーになります。そのためPsyshの機能をtinkerでも使えます。
tinkerはインタラクティブにEloquentやジョブ、イベントの実行ができるので、簡単に処理の確認を行いたい場合に便利です。
また、デバッグしたいソースコード上に eval(\Psy\sh()); を仕込み、php artisan serv 実行後コードが通過するURLを叩くと、tinkerが起動し仕込んだ場所からtinkerでデバッグすることが可能になります。これは自作のartisanコマンドに仕込んだ場合でも同様です。仕込むと下のキャプチャのように対話形式で実行できます。途中で$aに対して破壊的代入を行ったり、違う名前の変数を定義することもできます。
参考
もっとティンカー(Tinker)を使おう!
【laravel5】 tinkerを利用してpryのように楽にデバッグする!
Clockwork
パッケージの最後はClockworkです。
ClockworkはDebugbar相当のことがChromeのdevtoolなどで確認することができるようになるパッケージです。API開発の場合、DebugbarではSQLの表示などができないのでClockworkを使用したほうが便利です。使用するにはChrome/Firefoxの拡張と、composerでのインストールが必要になります。
実際にインストールして動かしてみると、キャプチャのようにdevtool上で色々と確認することができます。
過去に記載された記事とGithubのREADMEを見比べてみると、微妙に設定方法が変わっていたりするようなので、インストール方法や細かい設定などは https://github.com/itsgoingd/clockwork のREADMEやconfigファイルを見ながら導入すると良いと思います。
なお、アプリケーションをリバースプロキシ構成で動作させている場合は /__clockwork というエンドポイントにアクセスできるようサーバ側(Nginx)での設定が必要になっていました。(これはREADMEでも該当の記述が見当たらず少しハマりました)
ヘルパー
ヘルパーは開発のために一時的に仕込むものと、ログをファイルやログサービスに残して後で調査できるようにするために仕込むものと、2つのグループにわけて紹介します。
開発のために一時的に仕込むもの
開発中よく使うのがこれらのヘルパーになると思います。
dd()
dump()
ログとして残す必要がない、本当に一時的に使うものです。
例えば、
$hoge = ['foo' => ['bar', ['piyo' => true]]];
という内容をヘルパーに渡した場合、ブラウザ上や、テスト時はCLI上にこの内容が表示されます。ブラウザ上での表示は下記になります。
dd()の場合
dump()の場合
「▶」をクリックすると、たたまれた部分が開くようになっています。
dd() と dump() の違いですが、dd() を使用した場合、仕込んだ箇所以降の処理はされないようになっています(dump and dieの略らしい)。一方、dump() を使用するとvar_dump() のように最後まで処理を終えつつ、中身を表示するようになります。タイミングによって使いやすいほうを使うと良いでしょう。
また、Debugbarを導入していれば debug() というヘルパーも使用可能になります。Debugbar用のデバッグエリアで同じようにたたまれた状態で表示されるようになります。
ログを残すためのもの
本番環境やSTG環境で仕込みたいヘルパーです。
info(), logger()
ログに出力してデバッグしたい場合はこのヘルパーで十分かと思います。エラーレベルに応じて記述を変更すると良いと思います。 info()はそのままインフォメーションレベル、logger()はデバッグレベルです。第二引数に連想配列でを渡すとデータを展開してくれます。
info('Some helpful information!');
info('User login attempt failed.', ['id' => $user->id]);
また、これらはLogファサードをグローバルヘルパーにしただけのものなので、Log::debug() と書いても同等のことができます。
infoやdebugより上のレベルでログに残したい場合は、Log ファサードを使うと良いでしょう。
Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);
report()
LaravelでExceptionが発生した場合、基本的に処理は中断され App\Exceptions\Handler 内の report() メソッドと render() メソッドが実行されるようになっています。
そしてこの report() メソッドは、エラーログをログファイルに残すか、 SentryやBugSnagなどの外部サービスにエラー内容を送信するために使われます。
しかし、処理の中断は行いたくない場合もあります。そのときに使うのが report() ヘルパーです。下記の用にExceptionをキャッチし、report()ヘルパーを使用することでエラーページをレンダリングすることなくレポーティングできるようになります。
public function isFoo($bar)
{
try {
// do something
} catch (Exception $e) {
report($e);
return false;
}
}
その他
他にも、開発中は .envファイル内で APP_DEBUG をtrueにしておくだけで、Exceptionが発生した場合スタックトレースとともにエラー箇所、エラーメッセージなどがブラウザ上に表示されるようになり開発が楽になります。
エラーコードによってエラー画面をカスタマイズしている場合もあるかと思いますが、このデバッグ画面は有効になるよう調整しておくとよいでしょう。
まとめ
Laravelでのデバッグ・エラーレポーティングについてまとめました。
いろいろと紹介しましたが、個人的に開発中に一番よく使っているのはdd()とdebug()です。
必要に応じてパッケージや他のヘルパーも使えるようにしておくと、これまで以上に効率的に開発できたり、思わぬバグの発見につながるはずなので、少しでも整備していけるとよいなと思っています。
We're hiring!
クラシコムでは現在、技術や分析の基盤作りを進めており、WebエンジニアとUI/UXデザイナーの募集を行っています。今後、この基盤を元に新しい「買い物」体験を作っていこうと考えているので、ご興味がある方はぜひ一度オフィスに遊びに来てみてください。