Fun Done Run

yazawa's tech blog

リクエストをすべてログに出したい / Laravel の Middleware を使ってリクエストをログに出す

f:id:yazawa_tech:20190617172010p:plain

Laravel で受け取ったリクエストをログ出力するために、Middlewareの機能を使って実装してみた。個人的なメモとして忘れないようにまとめておく。

完成形

  • RequestLogging.php
<?php
namespace App\Http\Middleware;
use Closure;
class RequestLogging
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $query = collect($request->all())->except("q")->all();
        \Log::debug($request->method(), ["IP" => $request->ip(), "path" => $request->path(), "query" => http_build_query($query)]);
        return $next($request);
    }
}
  • Kernel.php (該当部分のみ)
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        \App\Http\Middleware\RequestLogging::class,
    ];

目次

  • Middleware とは
  • Middleware の作成
    • Middlewareクラスの作成
    • ログ出力処理の実装
  • Kernel.php の設定

Middleware とは

公式 より以下を抜粋して和訳してみる。

# Introduction
Middleware provide a convenient mechanism for filtering HTTP requests entering your application. For example, Laravel includes a middleware that verifies the user of your application is authenticated. If the user is not authenticated, the middleware will redirect the user to the login screen. However, if the user is authenticated, the middleware will allow the request to proceed further into the application.

Additional middleware can be written to perform a variety of tasks besides authentication. A CORS middleware might be responsible for adding the proper headers to all responses leaving your application. A logging middleware might log all incoming requests to your application.

There are several middleware included in the Laravel framework, including middleware for authentication and CSRF protection. All of these middleware are located in the  app/Http/Middleware directory.

(出典: Middleware - Laravel - The PHP Framework For Web Artisans)

和訳(Google翻訳より)

ミドルウェアは、アプリケーションに入るHTTPリクエストをフィルタリングするための便利なメカニズムを提供します。たとえば、Laravelには、アプリケーションのユーザーが認証されていることを確認するためのミドルウェアが含まれています。ユーザーが認証されていない場合、ミドルウェアはユーザーをログイン画面にリダイレクトします。ただし、ユーザーが認証された場合、ミドルウェアはリクエストがアプリケーション内部にさらに進むことを許可します。

認証以外にもさまざまなタスクを実行するために、追加のミドルウェアを作成することができます。 CORSミドルウェアは、アプリケーションから送信されるすべてのレスポンスに適切なヘッダーを追加する責任があります。ロギングミドルウェアはあなたのアプリケーションへの全ての入ってくるリクエストをログするかもしれません。

認証およびCSRF保護のためのミドルウェアを含む、Laravelフレームワークにはいくつかのミドルウェアが含まれています。これらのミドルウェアはすべて app/Http/Middleware ディレクトリにあります。

概要をまとめると以下のようになる。

今回は和訳の部分にもあるロギングのためのミドルウェアを作成したので、以下手順をまとめる。

Middleware の作成

Middlewareクラスの作成

php artisan コマンドを使用してMiddlewareのクラスを作成。

$ php artisan make:middleware RequestLogging
Middleware created successfully.

以下のようなファイルができあがる。

<?php
namespace App\Http\Middleware;
use Closure;
class RequestLogging
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request);
    }
}

ログ出力処理の実装

ログを出力する処理を handle メソッドの中に記述する

    public function handle($request, Closure $next)
    {
        $query = collect($request->all())->except("q")->all();
        \Log::debug($request->method(), ["IP" => $request->ip(), "path" => $request->path(), "query" => http_build_query($query)]);
        return $next($request);
    }

Kernel.php の設定

Middleware を作成したら、 Kernel.php で読み込むよう 必ず追加する

    protected $middleware = [
        :
        \App\Http\Middleware\RequestLogging::class,
    ];

試しにローカルホストでサーバーを起動してリクエストすると、以下のようにログが出力される - リクエス

curl -X POST \
-F 'server=example.com' \
-F 'id=test' \
-F 'item=piyo' \
-F 'option=true' \
http://localhost:8000/path/to/api
  • ログ
[2019-06-17 00:10:20] localhost.DEBUG: POST {"IP":"127.0.0.1","path":"path/to/api","query":"server=example.com&id=test&item=piyo&option=1"}

まとめ

  • Laravel で全てのリクエストをログに出すように設定してみました
  • Middleware はartisanのコマンドで簡単に生成できるし、ログの出力もファサードを使うだけなのでとっても簡単
  • 今回はすべての環境でログが出力されるようにしているが、環境に合わせて出力の有無も切り替えられるので、必要に応じて実装できるようにしておく

参考サイト