Docker前提のLaravelログ設定

## 概要

Laravelでのログ設定についてまとめした。

* この記事のゴール
	* 任意のログを stdout で書き出す


最終的にDockerコンテナのログを書き出すことを前提にしてるため、`stdout`のみに焦点を当てています。

Laravelには上記のゴール以外にも、ログをファイルに書き出したり、Slackに通知するよう設定できます。

詳しく知りたい方は以下のリンクをご覧ください。

* [Laravel.5.7 ログ]
(https://readouble.com/laravel/5.7/ja/logging.html) 

※監視ド素人が書いたものですので、間違い等ありましたらご指摘いただけると幸いです！

## 目次

1. ログ設定
2. ログレベル
3. なにをログとして書き出すか

## 1. ログ設定

### 設定ファイル

Laraveのログシステム設定には、`config/logging.php`を使用します（デフォルトで存在します）。
基本的にこのファイルしか触りません。

ファイルにはチャンネルという単位で設定が記述されており、
デフォルトでは`stack`チャンネルが使用されます。

以下は設定例です。

```php
// logging.php
<?php

use Monolog\\Handler\\StreamHandler;

return [
	// デフォルトでstackチャンネルを使用
	'default' => env('LOG_CHANNEL', 'stack'),  
	
	'channels' => [
		'stack' => [
            'driver' => 'stack',
            'channels' => ['stdout'], // stdoutチャンネルを使用
      ],

		'stdout' => [
            'driver' => 'monolog',
            'handler' => StreamHandler::class,
            'with' => [
                'stream' => 'php://stdout',
            ],
            'level' => 'debug',
      ],

		'single' => [
            'driver' => 'single',
            'path' => storage_path('logs/laravel.log'),
            'level' => 'debug',
        ],

        'daily' => [
            'driver' => 'daily',
            'path' => storage_path('logs/laravel.log'),
            'level' => 'debug',
            'days' => 7,
        ],

        'slack' => [
            'driver' => 'slack',
            'url' => env('LOG_SLACK_WEBHOOK_URL'),
            'username' => 'Laravel Log',
            'emoji' => ':boom:',
            'level' => 'critical',
        ],

        'stderr' => [
            'driver' => 'monolog',
            'handler' => StreamHandler::class,
            'with' => [
                'stream' => 'php://stderr',
            ],
        ],

        'syslog' => [
            'driver' => 'syslog',
            'level' => 'debug',
        ],

        'errorlog' => [
            'driver' => 'errorlog',
            'level' => 'debug',
        ],
]
```


用途に合わせてチャンネルを使っていくのですが、
今回は `stdout`のみなので、設定は上記のままでOKです。

## 2. ログレベル

ログには重要度などで分類されたレベルがあります。

- **emergency**
- **alert**
- **critical**
- **error**
- **warning**
- **notice**
- **info**
- **debug**

上から高→低レベルです。

各チャンネルでは、`level`オプションで指定されたレベル以上のログが書き出されます。

```php
'stdout' => [
            'driver' => 'monolog',
            'handler' => StreamHandler::class,
            'with' => [
                'stream' => 'php://stdout',
            ],
				// debugは最低レベルなので全レベルのログを書き出す
            'level' => 'debug', 
      ],
```

`logging.php`での設定は以上です。

あとは各処理にログを仕込んでいきます。

```php
// 本家HPより引用
<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Support\Facades\Log;
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)]);
    }
}
```

```php
// 各レベルの書き出し方
Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);
```

※引用元:[ログ 5.7 Laravel](https://readouble.com/laravel/5.7/ja/logging.html)


## 3. なにをログとして書き出すか
ログを残す目的は大きく分けて2つ。

1. 障害発生時、原因究明の手がかりとする
2. 改善に役立てる

主にひとつ目の目的が大きいです。
どこで問題が起きたか、なにが問題となったか等を知るため、各処理にたいしてログを残すことが必要です。

ただし、すべての処理に対してログを差し込むのは大変ですし、すんごい小さな処理にまでログを残してると、本当に必要なログが埋もれてしまいます。

まずはリクエストごと、コントローラの各処理を1単位として、
あとは必要に応じてログを残すようにします。

### どんなログを残すか

ここは[ログ設計指針 - Qiita](https://qiita.com/nanasess/items/350e59b29cceb2f122b3#web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E5%A0%B4%E5%90%88)から引用させていただきます。


> * **INFO**リクエスト開始時 - 処理概要、実行クラス名、メソッド名
* **INFO**途中経過 - 実行条件、処理対象オブジェクトのキーとなる値等(customer_id, order_id 等)
* **INFO**処理終了時 - 実行結果(OK/NG 等)、リダイレクト先
* **WARN**イベント発生時 - 画面に表示したエラーメッセージ等
* **ERROR**例外発生時 - 例外クラス、例外メッセージ
* **INFO**その他、必要に応じて


### おわりに

Laravelのログ設定は`logging.php`のみで完結してて取っつきやすく、デフォルトでslack通知にも対応してたり（使わないけど）パワフルで良いですね。



次はDockerでのログの扱いについてまとめます。

## 参考

- [Laravel.5.7 ログ]
(https://readouble.com/laravel/5.7/ja/logging.html) 
- [ログ設計指針 - Qiita](https://qiita.com/nanasess/items/350e59b29cceb2f122b3#web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E5%A0%B4%E5%90%88)
- [O’Reilly Japan - 入門 監視](https://www.oreilly.co.jp/books/9784873118642/)