Laravel 6 を Docker 化する。その 3 。 Docker のログへ Laravel のログを出力

今回やること

docker logs について

The docker logs –follow command will continue streaming the new output from the container’s STDOUT and STDERR.

と公式ドキュメントにあるので、標準出力 (STDOUT) と標準エラー出力 (STDERR) に Laravel アプリのログを出力してやれば良さそうです。

ここで分かるように、このJSONファイルの中には「docker logs」コマンドで確認できる情報に加えて、出力先ストリーム(標準出力なら「stdout」、標準エラー出力なら「stderr」)の情報も記録されている。

とあることから、 Laravel アプリのエラーログは stderr へ、それ以外のログは stdout へ出力するのが理想形ということが言えそうです。

Laravel のログレベルと stdout stderr の出し分け

理想形ではありますけれども、 実際にはどちらか一方へのみ出力する、というのが現実解となるのではないかと考えます。

Laravel のログレベルです。

分類されていますけれども、エラーか否かではありません。となれば、 stdout か stderr へと出し分けたいのであれば、それ専用のロジックをさらに実装する必要がありそうです。

面倒です。やめておきます。

方針

ファイルへ出力するログを、 stdout または stderr のどちらかへも出力します。

実装

先に説明した通り、stackドライバーは、複数のチャンネルを一つのログチャンネルへまとめるために使用します。

ということができますので、デフォルトの daily はそのままにしておきます。 daily は最大 14 日分のログを保持し、それ以上増えることはない (はず。実は未検証) のでそのままにしておきます。

この stack ドライバーに、 stdout または stderr のログチャンネルを追加します。

config/logging.php には、なぜかドキュメントには記述がありませんけれども、初めから次のチャンネルがありました。

        'stderr' => [
            'driver' => 'monolog',
            'handler' => StreamHandler::class,
            'formatter' => env('LOG_STDERR_FORMATTER'),
            'with' => [
                'stream' => 'php://stderr',
            ],
        ],

これを使い、次のようにしました。

$ git diff config/logging.php
diff --git a/config/logging.php b/config/logging.php
index 0df8212..58272ed 100644
--- a/config/logging.php
+++ b/config/logging.php
@@ -37,7 +37,7 @@ return [
     'channels' => [
         'stack' => [
             'driver' => 'stack',
-            'channels' => ['daily'],
+            'channels' => ['daily', 'stderr'],
             'ignore_exceptions' => false,
         ],
$

確認

ログ出力をしませんと、ログがファイルと Docker のログに出ていることを確認できません。一時的に次のように修正し、 http://127.0.0.1/ にアクセスして確認しました。

$ git diff routes/web.php
diff --git a/routes/web.php b/routes/web.php
index 810aa34..a4bdca3 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -12,5 +12,6 @@
 */

 Route::get('/', function () {
+    logger('route get / welcome!!!!!!!!!!');
     return view('welcome');
 });
$

Docker のログは次のようになりました。

$ docker logs  sample_dockerized_laravel6
... 略 ...
[2019-10-27 22:13:06] local.DEBUG: route get / welcome!!!!!!!!!!
172.17.0.1 - - [28/Oct/2019:07:13:05 +0900] "GET / HTTP/1.1" 200 1754 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36"
172.17.0.1 - - [28/Oct/2019:07:13:06 +0900] "GET /favicon.ico HTTP/1.1" 200 295 "http://127.0.0.1/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36"

続いて、 Laravel のログです。

$ docker container exec sample_dockerized_laravel6 cat storage/logs/laravel-2019-10-27.log
[2019-10-27 22:13:06] local.DEBUG: route get / welcome!!!!!!!!!!

両方で、 Laravel のログが出力されています。これでひとまず良さそうです!

補足。 Laravel のタイムゾーン設定

Laravel ログの出力日時が、 UTC です><。コンテナ、 PHP のタイムゾーンは設定済みですけれども、 Laravel の設定が抜けておりました。

次のように修正し、 Asia/Tokyo となっていることを確認しました♪

$ git diff --cached config/app.php
diff --git a/config/app.php b/config/app.php
index c9960cd..c85079c 100644
--- a/config/app.php
+++ b/config/app.php
@@ -67,7 +67,7 @@ return [
     |
     */

-    'timezone' => 'UTC',
+    'timezone' => 'Asia/Tokyo',

     /*
     |--------------------------------------------------------------------------
$

おわりに

が今回の内容です。

以上です。

ディスカッションに参加

1件のコメント

コメントを残す

コメントを残す