laravel-http-loggerを使ってアクセスログ機能を実装する

## laravel-http-loggerを使ってロギング機能を実装

とあるAPIにモニタリング用のアクセスログ機能を追加実装する事となりまして。

laravel-http-loggerというライブラリを使うと簡単に実装できそうなので利用しました。
復習がてら実装方法や手順を書いてみます。

※公式の説明とは若干実装の順番が異なります

## 事前学習のオススメリンク

Laravelのログについて(公式)
https://readouble.com/laravel/6.x/ja/logging.html

ログ出力のカスタマイズ例
https://www.zu-min.com/archives/567

PHPの標準出力について(公式)
https://www.php.net/manual/ja/wrappers.php.php


## laravel-http-loggerをインストールする

↓公式はこちら。具体的な方法が掲載されています(英語)
https://github.com/spatie/laravel-http-logger

laravel-http-loggerをinstallします

```
composer require spatie/laravel-http-logger
```

## MiddlewareにLogWriter.phpを追加する

ミドルウェアに専用のディレクトリを作って、その中にファイルを入れました。

app\Http\Middleware\accesslog\LogWriter.php

```php
<?php

namespace App\Http\Middleware\accesslog;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Spatie\HttpLogger\DefaultLogWriter as DefaultLogWriter;

class LogWriter extends DefaultLogWriter
{
    public function logRequest(Request $request): void
    {
        $method = strtoupper($request->getMethod());
        
        $uri = $request->getPathInfo();
        
        $bodyAsJson = json_encode($request->except(config('http-logger.except')));
    
        $message = "{$method} {$uri} - Body: {$bodyAsJson}";
    
        Log::info($message);
    }
}

```

## configにhttp-logger.phpを追加する
http-logger.phpを追加します

config\http-logger.php

```php

<?php

return [

/*
 * The log profile which determines whether a request should be logged.
 * It should implement `LogProfile`.
 */
'log_profile' => \Spatie\HttpLogger\LogNonGetRequests::class,

/*
 * The log writer used to write the request to a log.
 * It should implement `LogWriter`.
 */
// 'log_writer' => \Spatie\HttpLogger\DefaultLogWriter::class,
// パスをMiddleWareに作ったファイルに変える
'log_writer' => \App\Http\Middleware\accesslog\LogWriter::class,

/*
 * Filter out body fields which will never be logged.
 */
'except' => [
    'password',
    'password_confirmation',
],
];
```

## logging.phpに標準出力用のチャンネルを作る

config\logging.php

```php

'channels' => [
        'stack' => [
            'driver' => 'stack',
            'channels' => ['single'],
            'ignore_exceptions' => false,
        ],

        'stdout' => [
            'driver' => 'monolog',
            'handler' => StreamHandler::class,
            'with' => [
                'stream' => 'php://stdout', // 標準出力にログを吐き出す
            ],
            'level' => 'debug',
        ],
```

## 環境変数のLOG_CHANNELをstdoutにする

```
LOG_CHANNEL=stdout
```

## Kernel.phpのミドルウェアにルートを追加する

add\Http\Kernel.php

```php

protected $middleware = [
        // \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\TrustProxies::class,
        \Fruitcake\Cors\HandleCors::class,
        \App\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \Spatie\HttpLogger\Middlewares\HttpLogger::class // ライブラリのパスを追加
    ];
```

## ログを出力してみる

試しにCurlでAPIを叩いてみます

```
curl http://localhost:8080/qiita/article/third -X POST -H 'Content-Type: application/json'
```

結果↓

```
[2020-06-15 09:00:00] local.INFO: POST /qiita/article/third - Body: {"hogehuga"} 
```

無事出力が確認できました!

ライブラリを使う以外にも色んな方法があると思いますので、
やりたい事に合わせて試してみて下さい。