イントロダクション
新しいLaravelプロジェクトを開始する時点で、エラーと例外の処理は既に設定済みです。それに加えLaravelは、パワフルで様々なログハンドラをサポートしているMonologログライブラリーと統合されています。
設定
エラーの詳細
アプリケーションエラー発生時にブラウザに表示される詳細の表示量は、config/app.php
設定ファイルのdebug
設定オプションでコントロールします。デフォルト状態でこの設定オプションは、.env
ファイルで指定されるAPP_DEBUG
環境変数の値を反映します。
local環境ではAPP_DEBUG
環境変数をtrue
に設定すべきでしょう。実働環境ではこの値をいつもfalse
にすべきです。
ログモード
Laravelは初めから単一ファイル(single
)、日別ファイル(daily
)、
システムログ(syslog
)、エラーログ(errorlog
)ログモードをサポートしています。たとえば単一ファイルにログする代わりに日別ログを取りたい場合は、config/app.php
設定ファイルのlog
をただ設定するだけです。
'log' => 'daily'
daily
ログモードを使用する場合、Laravelはデフォルトで5日分のログのみ残します。保存する日数を調整したい場合は、app.php
設定ファイルへlog_max_files
設定値を追加してください。
'log_max_files' => 30
カスタムMonolog設定
Monologがアプリケーションのために設定している内容を完全にコントロールしたければ、アプリケーションのconfigureMonologUsing
メソッドを使ってください。このメソッドはbootstrap/app.php
ファイルの中の$app
変数が返される直前に呼びださなくてはなりません。
$app->configureMonologUsing(function($monolog) {
$monolog->pushHandler(...);
});
return $app;
Laravelはデフォルトで全ログレベルを書き出します。実働環境では、このデフォルトログレベルを変更することが多いでしょう。app.php
設定ファイルへlog_level
オプション値を付け加えてください。Laravelは指定されたレベル以上をログします。例えば、log_level
をerror
にすれば、error、critical、alert、emergencyメッセージがログされます。
'log_level' => env('APP_LOG_LEVEL', 'debug'),
例外ハンドラ
全例外はApp\Exceptions\Handler
クラスで処理されます。このクラスはreport
とrender
二つのメソッドで構成されています。両メソッドの詳細を見ていきましょう。
reportメソッド
report
メソッドは例外をログするか、BugSnagやSentryのような外部サービスに送信するために使います。デフォルト状態のreport
メソッドは、ただ渡された例外をベースクラスに渡し、そこで例外はログされます。しかし好きなように例外をログすることが可能です。
たとえば異なった例外を別々の方法レポートする必要がある場合、PHPのinstanceof
比較演算子を使ってください。
/**
* 例外をレポート、もしくはログする
*
* ここは例外をSentryやBugsnagなどへ送るために適した場所
*
* @param \Exception $e
* @return void
*/
public function report(Exception $e)
{
if ($e instanceof CustomException) {
//
}
return parent::report($e);
}
タイプによる例外の無視
例外ハンドラの$dontReport
プロパティーは、ログしない例外のタイプの配列で構成します。デフォルトでは、404エラー例外はログされません。必要に応じてこの配列へ他の例外を付け加えてください。
renderメソッド
render
メソッドは与えられた例外をブラウザーに送り返すHHTPレスポンスへ変換することに責任を持っています。デフォルトで例外はベースクラスに渡され、そこでレスポンスが生成されます。しかし例外のタイプをチェックし、お好きなようにレスポンスを返してかまいません。
/**
* HTTPレスポンスへ例外をレンダー
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if ($e instanceof CustomException) {
return response()->view('errors.custom', [], 500);
}
return parent::render($request, $e);
}
HTTP例外
例外の中にはサーバでのHTTPエラーコードを表しているものがあります。たとえば「ページが見つかりません」エラー(404)や「未認証エラー」(401)、開発者が生成した500エラーなどです。アプリケーションのどこからでもこの種のレスポンスを生成するには、次のように実行します。
abort(404);
abort
メソッドは即座に例外を発生させ、その例外は例外ハンドラによりレンダーされることになります。オプションとしてレスポンスのテキストを指定することもできます。
abort(403, 'Unauthorized action.');
このメソッドはリクエストのライフサイクル中であればいつでも使用できます。
カスタムHTTPエラーページ
様々なHTTPステータスコードごとに、Laravelはカスタムエラーページを簡単に返せます。たとえば404
HTTPステータスコードに対してカスタムエラーページを返したければ、resources/views/errors/404.blade.php
を作成してください。このファイルはアプリケーションで起こされる全404エラーに対し動作します。
abort
メソッドにより例外が投げられると、ビューへ$exception
変数として渡されます。必要であればエラーメッセージをユーザへ表示するために使用することができます。
$exception->getMessage()
ビューはこのディレクトリに置かれ、対応するHTTPコードと一致した名前にしなくてはなりません。
ログ
Laravelのログ機能は、強力なMonologライブラリーのシンプルな上位レイヤーを提供します。Laravelはデフォルトで、アプリケーションの日別ログファイルをstorage/logs
ディレクトリへ作成するように設定されています。ログへ情報を書き込むにはLog
ファサードを使います。
<?php
namespace App\Http\Controllers;
use Log;
use App\User;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* 指定ユーザーのプロフィールを表示
*
* @param int $id
* @return Response
*/
public function showProfile($id)
{
Log::info('Showing user profile for user: '.$id);
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
ログはRFC 5424で定義されているemergency、alert、critical、error、warning、notice、info 、debugの8レベルをサポートしています。
Log::emergency($error);
Log::alert($error);
Log::critical($error);
Log::error($error);
Log::warning($error);
Log::notice($error);
Log::info($error);
Log::debug($error);
コンテキストデータ
ログメソッドにはコンテキストデータを配列で渡すこともできます。このコンテキストデータはログメッセージと一緒に整形され、表示されます。
Log::info('User failed to login.', ['id' => $user->id]);
裏で動作するMonologインスタンスへのアクセス
Monologはログに使用できる様々な追加のハンドラを提供しています。必要であれば、Laravelが裏で使用しているMonologインスタンスへアクセスすることもできます。
$monolog = Log::getMonolog();