はじめに
Laravelにてscheduler利用する際に、CloudwatchLogsにログ出力させるためには以下のようにログ出力先に/proc/1/fd/1
を指定する必要があります。
$schedule->command('test')->everyMinute()->appendOutputTo('/proc/1/fd/1');
しかし、Supervisorを利用した構成にした場合、この設定ではCloudwatchLogsにログ出力されず、少し工夫が必要だったため、ひとつの対処方法について本記事で記載します。
設定
Laravel kernel.php 設定
$logFile = '/app/storage/logs/laravel-scheduler.log';
$schedule->command('test')->everyMinute()->appendOutputTo($logFile);
解説
Laravelではコンテナ内の /app/storage/logs/laravel-scheduler.log
にログ出力させるようにします。
supervisord.conf 設定
[supervisord]
pidfile=/var/supervisord_run/supervisord.pid
nodaemon=true
[program:laravel-scheduler]
command = sh -c 'php artisan schedule:run && sleep 60'
autorestart = true
redirect_stderr = true
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes = 0
[program:laravel-scheduler-log]
command=tail -F /app/storage/logs/laravel-scheduler.log
stdout_logfile=/proc/1/fd/1
stdout_logfile_maxbytes=0
autorestart=true
[program:laravel-scheduler-log-rotate]
command=/bin/bash /usr/local/bin/scheduler_log_rotate.sh
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
autorestart=true
解説
[program:laravel-scheduler]
Laravelのschedule:run を実行する設定です。
[program:laravel-scheduler-log]
/app/storage/logs/laravel-scheduler.log
のファイルに出力されたログをtailし、 /proc/1/fd/1
つまり、CloudwatchLogsに出力させるようにします。
-F のオプションを利用しているのは、後述のログローテート時にtailし続けるためです。
[program:laravel-scheduler-log-rotate]
scheduler_log_rotate.sh というシェルスクリプトを指定します。
Laravel側はコンテナ上にそのままログ出力するため、コンテナ内に保存できるストレージの容量を気にする必要があります。
そのため、一定間隔でファイルを削除し再作成することで、ファイルサイズをリセットします。
シェルスクリプト内容は以下の通りです。
#!/bin/bash
LOG_FILE=/app/storage/logs/laravel-scheduler.log
while true
do
until [ "$(date '+%H%M')" -eq "2200" ] # 1日1回、22:00のタイミングでログファイルを再作成する
do
sleep 60
done
rm $LOG_FILE
touch $LOG_FILE
chown www-data:www-data $LOG_FILE # laravelが読み込み可能な権限を指定する
sleep 60
done
まとめ
supervisord.conf の設定のみで上手く /proc/1/fd/1
の指定でCloudwatchLogsにログ出力できなかったため、今回ご紹介した方法で対処しました。
supervisord.conf のみで設定できたほうが簡潔だと思いますので、参考情報あればご教示いただけると幸いです。