Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
15
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

Organization

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

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!!


Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
15
Help us understand the problem. What are the problem?