Laravelバッチ(コマンド) のログをバッチ毎にCloudWatch Logsへ出力する
はじめに
EC2上でLaravel APIサーバーが稼働しています。
このAPIサーバーでは$schedule->command
を使用して定期的にバッチ(コマンド)の実行もしています。
(バッチサーバーも兼ねているわけです。)
APIとバッチがあいのりしている件はあまり良くないですが、今回はその改善には触れません。
今回の問題はログです。
storage/logs
配下へログを出力していますが、
1つのログファイルにAPIとバッチのログがまじってしまっており、さらにバッチが10個程度存在していたため、
どれがどのログなのかを理解する・探すのも難しい状態になっていました。
そこで各ログファイルを分け、ついでにCloudWatchLogsへ連携してみました。
バッチごとにログを分ける
logging.phpへチャンネルの設定を追加する
バッチごとに使用するログチャンネルの設定を記載します。
日毎にローテーションしていたり、debugログすべて出力していたりするのでそこは調整してください。
~省略~
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily'],
'ignore_exceptions' => false,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
'permission' => 0777,
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 30,
'permission' => 0777
],
// バッチごとにログファイルを分けるためチャンネルを作成
'batch-a' => [
'driver' => 'daily',
'path' => storage_path('logs/batch-a.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 30,
'permission' => 0777,
'ignore_exceptions' => false
],
'batch-b' => [
'driver' => 'daily',
'path' => storage_path('logs/batch-b.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 30,
'permission' => 0777,
'ignore_exceptions' => false
],
'batch-c' => [
'driver' => 'daily',
'path' => storage_path('logs/batch-c.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 30,
'permission' => 0777,
'ignore_exceptions' => false
],
]
~省略~
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
class BatchA extends Command
{
~省略~
public function handle()
{
Log::setDefaultDriver('batch-a');
処理
}
}
これでBatchAからのログ出力にはbatch-aチャンネルが利用されlogs/batch-a.log
へログが出力されます。
※BatchB、Cも同様です。
下記のようにログ出力するたびにチャンネルを指定する方法もあるようですが、
いちいちチャンネルを指定するのは面倒だったので上記のようにsetDefaultDriver
を利用しています。
Log::channel('batch-a')->info('Something happened!');
また、下記のようにすればlogging.php
へ設定を行わなくてもログの設定ができるようですが、
この設定をsetDefaultDriver
のように全体に反映する方法が見つからなかったため断念しました。
Log::build([
'driver' => 'daily',
'path' => storage_path('logs/batch-a.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 30,
'permission' => 0777,
'ignore_exceptions' => false
])->info('Something happened!');
CloudWatchエージェントを使用してEC2からログを送る
ここまででログの分離は完了したので、そのログをCloudWatch Logsへ連携していきます。
EC2のロールへ「CloudWatchLogsFullAccess」ポリシーを追加
対象となるインスタンスがCloudWatch Logsにアクセス可能とするために、EC2に割り当てるIAMロールを作成します。
こちらを参考に行いました。
EC2へssh接続しCloudWatchエージェントをインストール
以下のコマンドを実行しCloudWatchエージェントをインストールします。
$ wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb
$ sudo dpkg -i -E ./amazon-cloudwatch-agent.deb
$ sudo amazon-cloudwatch-agent-ctl -a start
CloudWatchエージェントの定義ファイルを編集
ログファイルを転送する設定を書いていきます。
$ sudo vi /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/default
バッチのログだけでなく、API側のログやnginxのログの転送設定も行いました。
{
"agent": {
"run_as_user": "root"
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/アプリのパス/storage/logs/laravel*log",
"log_group_name": "api-laravel-log",
"log_stream_name": "ec2-{instance_id}-laravel-log"
},
{
"file_path": "/アプリのパス/storage/logs/batch-a*log",
"log_group_name": "batch-laravel-log",
"log_stream_name": "ec2-{instance_id}-batch-a-log"
},
{
"file_path": "/アプリのパス/storage/logs/batch-b*log",
"log_group_name": "batch-laravel-log",
"log_stream_name": "ec2-{instance_id}-batch-b-log"
},
{
"file_path": "/アプリのパス/storage/logs/batch-c*log",
"log_group_name": "batch-laravel-log",
"log_stream_name": "ec2-{instance_id}-batch-c-log"
},
{
"file_path": "/var/log/nginx/api.log",
"log_group_name": "api-nginx-log",
"log_stream_name": "ec2-{instance_id}-nginx-log"
},
{
"file_path": "/var/log/nginx/api-error.log",
"log_group_name": "api-nginx-error-log",
"log_stream_name": "ec2-{instance_id}-nginx-error-log"
},
{
"file_path": "/var/log/php7.4-fpm.log",
"log_group_name": "php-fpm-log",
"log_stream_name": "ec2-{instance_id}-php-fpm-log"
}
]
}
}
}
}
CloudWatchエージェント再起動,ステータス確認
$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a stop
$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a start
ログがCloudWatchLogsに転送されているか確認
AWSマネージメントコンソールへサインインし、
CloudWatch Logs > ロググループ > batch-laravel-log を確認。
バッチごとにLog Streamが別れていることが確認できました!
最後に
定義ファイルをバッチごとに書かなくてはならないので、
1つの定義でいい感じに設定する方法を模索中。
知っている方いたら是非教えて下さい。
Author And Source
この問題について(Laravelバッチ(コマンド) のログをバッチ毎にCloudWatch Logsへ出力する), 我々は、より多くの情報をここで見つけました https://qiita.com/awakt/items/addea453645bf9cf634f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .