LoginSignup
18
15

More than 5 years have passed since last update.

Laravel5: エラーのログレベルを変更してみた

Last updated at Posted at 2015-12-01

2015 Laravel Advent Calendar 1日目! Laravel大好きな @M_Ishikawa と申します。

今年のphpconのLTで「サンタクロースを支えるIT技術」についての話をさせていただき、その際にも触れましたが趣味ではもっぱらLaravelを使用しております。\サンタクロースの活動を支えているLaravel/

今日は初日らしく軽〜い感じの内容で、日本語のTipsがWeb上に見当たらないから書いちゃえ!と思った、「エラーログレベルを操作する」という内容です。

※なお、Laravel5のコードで説明しています。




ずばり以下の通り。コードに説明入れちゃいます。

app/Exceptions/Handler.php

app/Exceptions/Handler.php
class Handler extends ExceptionHandler
{
    /**
     * ロギングの必要のないExceptionを指定できます
     */
    protected $dontReport = [
        HttpException::class,
        ModelNotFoundException::class,
    ];

    /**
     * エラーをロギングするならここです。
     * 3rd partyのエラーロギングWebサービス(SentryやBugsnag等)を挟むならここ!
     * 親メソッドでは  $this->log->error($e); しています。
     */
    public function report(Exception $e)
    {
        return parent::report($e);
    }

    /**
     * エラーをhttpレスポンスとしてレンダリングするならここです。
     */
    public function render($request, Exception $e)
    {
        if ($e instanceof ModelNotFoundException) {
            $e = new NotFoundHttpException($e->getMessage(), $e);
        }
        return parent::render($request, $e);
    }
}

ex: Sentry, Bugsnag

以上、初期のHandlerクラスでは非常にシンプルに必要最低限の調整が可能です。
たとえば csrf対策でLaravel5から実装された TokenMismatchException のログが必要なければ

app/Exceptions/Handler.php
    protected $dontReport = [
        HttpException::class,
        ModelNotFoundException::class,
        TokenMismatchException::class, // 追加
    ];

のように追加すればロギングされなくなります。

もしくはロギングはするけどエラーレベルを変更したいという場合は

app/Exceptions/Handler.php
    public function report(Exception $e)
    {
        if ($e instanceof TokenMismatchException) {
            // csrf tokenチェックはerrorではなくnoticeで
            $this->log->notice($e);
            return;
        }
        return parent::report($e);
    }

とすればerrorからnoticeにレベル変更できます。

ちなみに親メソッドはどうなっているかというと、

vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php

vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php
    public function report(Exception $e)
    {
        if ($this->shouldReport($e)) {
            $this->log->error($e);
        }
    }

ただのこれだけ。 こちらの親クラスのコード をたどるとわかりますが、 $dontReport に含まれていなければ shouldReport() = true となり log->error() が吐かれます。

このLaravelのエラーは

src/Illuminate/Log/Writer.php

src/Illuminate/Log/Writer.php
    protected $levels = [
        'debug'     => MonologLogger::DEBUG,
        'info'      => MonologLogger::INFO,
        'notice'    => MonologLogger::NOTICE,
        'warning'   => MonologLogger::WARNING,
        'error'     => MonologLogger::ERROR,
        'critical'  => MonologLogger::CRITICAL,
        'alert'     => MonologLogger::ALERT,
        'emergency' => MonologLogger::EMERGENCY,
    ];

と8種類用意されていますので、お好みのものを利用できます。




いかがでしたでしょうか。
さらにいろいろカスタマイズしたい場合は、親のHandlerクラス に用意された変数やメソッド(publicとprotectedしか存在しない!)をオーバーライドすることで自由に実現できます。

さくっとやりたいときはズバリ必要最低限のものがイケてる感じで用意されていて、さらにカスタマイズしようと思った時も直感でスマートに実装できるLaravelまじ++。
フレームワーク本体もとても分かり易く書かれているのでソースを追っかけるのが全然苦じゃないどころか、ワクワクしてきます。
ソースコードのコメントに SentryBugsnag といったイマドキのサービスを紹介しちゃうところもますます惚れてしまいます。

いじょーでした!
enjoy! Laravel!!


18
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
15