Laravel Log singleログとdailyログを同時に出力する

# 目的

- Laravelのログ出力にて二種のログを同時出力する方法をまとめる

# 実施環境

- MacのローカルにLaravelの環境を構築して実施する。環境構築手順の記事はリンクを後述する。
- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravel バージョン | 7.0.8 | commposerを用いてこちらの方法で導入→[Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08) |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9) |

# 前提条件

- 下記、または下記に準ずる方法でLaravelの環境構築がされていること。
    - [Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08)

# 前提情報

- ログの出力に関して若干の知識がある物として説明を行う。おそらく一旦ログの出力を経験した方が理解が早いかもしれない。下記にログ出力方法の最短方法を記載した記事のリンクを記載する。
    - [Laravel Logを出力してみる](https://qiita.com/miriwo/items/8d1c7c3a87cc670f6157)
- 今回説明する方法を応用すればdailyログとerrorログを別ファイルに出力することも可能になる考える。
- 説明の便宜上、アプリ作成部分から記載するが各の環境に沿って読み飛ばしていただきたい。

# 読後感

- singleログを`アプリ名ディレクトリ/storage/logs/`直下のsingle.logsファイルに、dailyログを`アプリ名ディレクトリ/storage/logs/`直下のdaily-YYYY-MM-DD.logファイルに`[YYYY-MM-DD HH:MM:SS] local.DEBUG: test`と言う文字列を出力することができる。

# singleログとdailyログ

※singleログとdailyログはログチャンネル(ログを行う設定の種類)の名前である。

- singleログ
    - Laravelアプリのログを`アプリ名ディレクトリ/storage/logs/`直下のlaravel.logファイルに出力するログのチャンネルのこと。(一個のログファイルのみにログを出力する方法と思っていただきたい。)
    - デフォルトではこのチャンネルが有効になっている。
- dailyログ
    - Laravelアプリのログを`アプリ名ディレクトリ/storage/logs/`直下のlaravel-YYYY-MM-DD.logに日毎に分けて出力するログのチャンネルのこと。(singleログを日毎に分けた物と思っていただきたい。)
    - デフォルト設定では14日経過したdailyログは削除される。

# 概要

1. アプリ作成
1. ルーティングの記載
1. UserHomeController作成と記載
1. singleログ出力確認
1. ログの設定変更
1. 確認

# 詳細

1. アプリ作成
    1. アプリを作成する任意のディレクトリに移動して下記コマンドを実行して「test」と言う名前のアプリを作成する。

        ```terminal
        $ laravel new test
        ```
1. ルーティングの記載
    1. testディレクトリで下記コマンドを実行してルーティングファイルを開く。

        ```terminal
        $ routes/web.php
        ```
    1. 開いたルーティングファイルに下記の一行を記載する。

        ```routes/web.php
        Route::get('/user_home', 'UserHomeController@index');
        ```
    1. 記載後のルーティングファイルの内容を下記に記載する。

        ```routes/web.php
        <?php
        
        use Illuminate\Support\Facades\Route;
        
        /*
        |--------------------------------------------------------------------------
        | Web Routes
        |--------------------------------------------------------------------------
        |
        | Here is where you can register web routes for your application. These
        | routes are loaded by the RouteServiceProvider within a group which
        | contains the "web" middleware group. Now create something great!
        |
        */
        
        Route::get('/', function () {
            return view('welcome');
        });
        
        Route::get('/user_home', 'UserHomeController@index');
        ```
    1. 保存して閉じる。
1. UserHomeController作成と記載
    1. testディレクトリで下記コマンドを実行してUserHomeController.phpを作成する。

        ```terminal
        $ php artisan make:controller UserHomeController
        ```
    1. 下記コマンドを実行して先のコマンドで作成したUserHomeController.phpを開く。

        ```terminal
        $ vi app/Http/Controllers/UserHomeController.php
        ```
    1. 開いたUserHomeController.phpを下記の様に修正する。

        ```test/app/Http/Controllers/UserHomeController.php
        <?php
        
        namespace App\Http\Controllers;
        
        use Illuminate\Http\Request;
        //下記を追記する、下記の宣言がないとエラーになる
        use Illuminate\Support\Facades\Log;
        
        class UserHomeController extends Controller
        {
            //下記を追記する
            public function index()
            {
                //Log::debug('ログとして出力したい文字列')の様に記載する
                Log::debug('test');
                return redirect('/');
            }
            //上記までを追記する。
        }
        ```
    1. 保存して閉じる。
1. singleログ出力確認
    1. testディレクトリで下記コマンドを実行してまだlogファイルが存在していないことを確認する。「No such file or directory」が出力されればsingle.logファイルとdaily.logは存在しない。

        ```terminal
        $ ls storage/logs/laravel.log
        >ls: storage/logs/laravel.log: No such file or directory
        ```
    1. testディレクトリで下記コマンドを実行してローカルサーバを起動する。

        ```terminal
        $ php artisan serve
        ```
    1. ブラウザからtestアプリにアクセスする。デフォルトだと[http://127.0.0.1:8000/](http://127.0.0.1:8000/)にアクセスするとブラウザでtestアプリが表示できる。
    1. 下記画面が表示されていることを確認する。

        <img width="1439" alt="Laravel.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b538e184-404a-e00c-6032-a422ae1b914f.png">

    1. [http://127.0.0.1:8000/user_home](http://127.0.0.1:8000/user_home)にアクセスしてみる。(アクセスしても何も起こらず、先の画像と同じLaravelのトップページが表示されると思うがその動作は期待する動作である。)
    1. testディレクトリで下記コマンドを実行してログファイルを開く。

        ```terminal
        $ less storage/logs/laravel.log
        ```
    1. 下記の一行が記載されていることを確認する。(YYYY-MM-DD HH:MM:SSはみなさんがhttp://127.0.0.1:8000/user_homeにアクセスした時間が入る。)

        ```test/storage/logs/laravel.log
        [YYYY-MM-DD HH:MM:SS] local.DEBUG: test 
        ```
1. ログの設定変更
    1. testディレクトリで下記コマンドを実行してログの設定ファイルを開く。

        ```terminal
        $ vi config/logging.php
        ```
    1. 開いた設定ファイルを下記の様に修正する。

        ```test/config/logging.php
        <?php
        
        use Monolog\Handler\NullHandler;
        use Monolog\Handler\StreamHandler;
        use Monolog\Handler\SyslogUdpHandler;
        
        return [
        
            /*
            |--------------------------------------------------------------------------
            | Default Log Channel
            |--------------------------------------------------------------------------
            |
            | This option defines the default log channel that gets used when writing
            | messages to the logs. The name specified in this option should match
            | one of the channels defined in the "channels" configuration array.
            |
            */
        
            'default' => env('LOG_CHANNEL', 'stack'),
        
            /*
            |--------------------------------------------------------------------------
            | Log Channels
            |--------------------------------------------------------------------------
            |
            | Here you may configure the log channels for your application. Out of
            | the box, Laravel uses the Monolog PHP logging library. This gives
            | you a variety of powerful log handlers / formatters to utilize.
            |
            | Available Drivers: "single", "daily", "slack", "syslog",
            |                    "errorlog", "monolog",
            |                    "custom", "stack"
            |
            */
        
            'channels' => [
                'stack' => [
                    'driver' => 'stack',
                    //下記修正・追記する
                    'channels' => [
                        'single',
                        'daily',
                    ],
                    'ignore_exceptions' => false,
                ],
        
                'single' => [
                    'driver' => 'single',
                    //下記を修正する
                    'path' => storage_path('logs/single.log'),
                    'level' => 'debug',
                ],
        
                'daily' => [
                    'driver' => 'daily',
                    //下記を修正する
                    'path' => storage_path('logs/daily.log'),
                    'level' => 'debug',
                    'days' => 14,
                ],
        
                'slack' => [
                    'driver' => 'slack',
                    'url' => env('LOG_SLACK_WEBHOOK_URL'),
                    'username' => 'Laravel Log',
                    'emoji' => ':boom:',
                    'level' => 'critical',
                ],
        
                'papertrail' => [
                    'driver' => 'monolog',
                    'level' => 'debug',
                    'handler' => SyslogUdpHandler::class,
                    'handler_with' => [
                        'host' => env('PAPERTRAIL_URL'),
                        'port' => env('PAPERTRAIL_PORT'),
                    ],
                ],
        
                'stderr' => [
                    'driver' => 'monolog',
                    'handler' => StreamHandler::class,
                    'formatter' => env('LOG_STDERR_FORMATTER'),
                    'with' => [
                        'stream' => 'php://stderr',
                    ],
                ],
        
                'syslog' => [
                    'driver' => 'syslog',
                    'level' => 'debug',
                ],
        
                'errorlog' => [
                    'driver' => 'errorlog',
                    'level' => 'debug',
                ],
        
                'null' => [
                    'driver' => 'monolog',
                    'handler' => NullHandler::class,
                ],
        
                'emergency' => [
                    'path' => storage_path('logs/laravel.log'),
                ],
            ],
        
        ];
        ```
1. 確認
    1. testディレクトリで下記コマンドを実行してまだlogファイルが存在していないことを確認する。「No such file or directory」が出力されればsingle.logファイルとdaily.logは存在しない。

        ```terminal
        $ ls storage/logs/single.log
        >ls: storage/logs/single.log: No such file or directory
        $ ls storage/logs/daily*
        >ls: storage/logs/daily*: No such file or directory
        ```
    1. testディレクトリで下記コマンドを実行してローカルサーバを起動する。

        ```terminal
        $ php artisan serve
        ```
    1. ブラウザからtestアプリにアクセスする。デフォルトだと[http://127.0.0.1:8000/](http://127.0.0.1:8000/)にアクセスするとブラウザでtestアプリが表示できる。
    1. 下記画面が表示されていることを確認する。

        <img width="1439" alt="Laravel.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b538e184-404a-e00c-6032-a422ae1b914f.png">

    1. [http://127.0.0.1:8000/user_home](http://127.0.0.1:8000/user_home)にアクセスしてみる。(アクセスしても何も起こらず、先の画像と同じLaravelのトップページが表示されると思うがその動作は期待する動作である。)
    1. testディレクトリで下記コマンドを実行してログファイルを開く。

        ```terminal
        $ less storage/logs/single.log
        ```
    1. 二つのファイルに下記の一行が記載されていることを確認する。(YYYY-MM-DD HH:MM:SSはみなさんが[http://127.0.0.1:8000/user_home](http://127.0.0.1:8000/user_home)にアクセスした時間が入る。)

        ```test/storage/logs/laravel.log
        [YYYY-MM-DD HH:MM:SS] local.DEBUG: test 
        ```
    1. 正常に書き込まれていた場合作業完了となる。