Laravel案件を担当している時に、サーバー側で定期的に自動処理をしてほしいというバッチ処理的な依頼がありました
その時に使ったタスクスケジュールと機能が便利だったので、実装の流れを備忘録として記事にしてみました
環境
- Laravel 6.20.34
- Ubuntu 20.04.2 LTS(homestead)
どうやって実装するか
cronを簡単に利用することのできるLaravelのタスクスケジュールという機能を使うことで実装が可能です
この記事で実装するもの
この記事ではLaravelタスクスケジュールの使い方を理解するために、storage配下のlogファイルへ現在日時を5分毎に残す処理を実装してみます
仮想環境へログイン
今回はhomesteadでLaravelの環境構築をしているので、仮想環境へログインしておきます
vagrant ssh
#crontabへエントリー追加
Laravelではcrontab(crontable)のエントリーがひとつだけで完結します
各タスクのスケジュール設定はLaravelファイル内に記述することで実装できるようになっているためです
まずエントリーを追加するために、crontabの編集を開始します
crontab -e
すると、vimエディタが開くので、insertモードにして下記エントリーを記述します
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
# homesteadなら以下のような感じ
* * * * * cd /home/vagrant/code/app && php artisan schedule:run >> /dev/null 2>&1
この記述で、Laravelのprojectフォルダに移動して、artisanコマンドでタスクスケジュールを実行するという指示がcronに追加されたことになります
path-to-your-projectの箇所はLaravelが保存されているディレクトリに応じて変更します
タスクスケジュールを設定する
cronの準備ができたので、Laravel側のタスクスケジュールを設定していきます
タスクスケジュールの設定は大きく分けて以下の2つの流れで実装します
1. タスク実行するための新規artisanコマンドを登録する
2. 登録したartisanコマンドを自動実行するためのスケジュールを設定する
1. タスク実行する新規artisanコマンドを作成する
AppApp\Console\CommandにAddTimeToLog.phpというファイルを生成します
php artisan make:command AddTimeToLog
AddTimeToLog.phpを以下のように書き換えます
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
// ①以下useを追記
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
class AddTimeToLog extends Command
{
protected $signature = 'command:AddTimeToLog'; // ②変更
protected $description = 'Add Current Time To Log'; // ③変更
public function __construct()
{
parent::__construct();
}
public function handle()
{
// ④追記
$current = Carbon::now('Asia/Tokyo');
Log::info($current);
}
}
- 現在日時を取得するのに便利なCarbonライブラリとLogを残すためのファサードをuseを使って宣言します
- artisanコマンドの名前を入力します。わかりやすい名前であれば大丈夫です
- artisanコマンドの説明を入力します。わかりやすい説明であれば大丈夫です
- handleメソッドの中には実行したい処理を記述します。今回はCarbonで現在日時を取得して、Logファイルに残すという簡単な処理のみ記述しておきます
これでaritsanコマンド新規登録が完了しました。 念の為、ちゃんと登録されているか確認します。
php artisan list
commandのところに先ほど設定した名前と説明を含めて登録されているのが確認できます
下記コマンドで実行してみます
php artisan command:AddTimeToLog
laravel.logを確認すると、ちゃんとログが残っています
[2021-11-14 16:57:01] local.INFO: 2021-11-14 16:50:00
では次にこのコマンドの実行を自動で実行させるように設定していきましょう
2.artisanコマンドを自動実行するスケジュールを設定する
App\Console\Kernelクラス内に、タスクスケジュールを設定することでartisanコマンドの自動実行が可能です
Kernel.phpを以下のように書き換えます(といっても追記するのはscheduleメソッドの中だけ)
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
protected $commands = [
];
protected function schedule(Schedule $schedule)
{
$schedule->command('command:AddTimeToLog')-> everyFiveMinutes(); // ①追記
}
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
- Artisanコマンドをスケジュールするための、commandメソッド(引数は実行したいコマンド)を追記します。また5分毎に実行するオプションをチェーンします
これだけで、タスクスケジュールの設定が完了しました。
なお、他の記事だと$commands変数の配列に、コマンド登録しないといけないという記述が多くありました。
しかし、実際は同ファイル内(Kernel.php)のcommandsファンクションのloadメソッド呼び出しにより、app/Console/Commands ディレクトリ内のすべてのコマンドが自動的にArtisanに登録されているので追記しなくても動くようです。
Because of the load method call in your console kernel's commands method, all commands within the app/Console/Commands directory will automatically be registered with Artisan. In fact, you are free to make additional calls to the load method to scan other directories for Artisan commands:
Logファイルを確認する
最後にLogファイルを確認すると以下のような感じです
[2021-11-14 16:57:01] local.INFO: 2021-11-14 16:50:00
[2021-11-14 16:58:02] local.INFO: 2021-11-14 16:55:00
[2021-11-14 16:59:02] local.INFO: 2021-11-14 17:00:00
参考記事
https://readouble.com/laravel/6.x/ja/scheduling.html
https://reffect.co.jp/laravel/laravel-task-schedule-cron
https://laravel.com/docs/6.x/artisan