Laravel also has a scheduler functionality to run a command/task on a defined time. It can be every minute, hourly, daily, or even at a certain time. Schedulers commonly used for automatic tasks, such as reporting products/items count daily or sending daily emails. Or if you a developer, you may want to log every kind of data daily for analytic purposes.
PHP-Worker in Laradock still has one functionality to play with. Now it's time for some logging!
Prerequisites
Everything would be easier to tell if you knew about the worker first.
Prepare the scheduler test command
Let's create this artisan command:
app\Console\Commands\ExampleSchedulerTest.php
:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
class ExampleSchedulerTest extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'example:scheduler-test {logLevel} {--message=}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command for logging schedulers';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$arguments = $this->arguments();
$options = $this->options();
$options['message'] = $options['message'] ?? 'lorem ipsum dolor sit amet';
switch ($arguments['logLevel']) {
case 'emergency':
Log::emergency($options['message']);
break;
case 'alert':
Log::alert($options['message']);
break;
case 'critical':
Log::critical($options['message']);
break;
case 'error':
Log::error($options['message']);
break;
case 'warning':
Log::warning($options['message']);
break;
case 'notice':
Log::notice($options['message']);
break;
case 'info':
Log::info($options['message']);
break;
case 'debug':
Log::debug($options['message']);
break;
default:
Log::debug($options['message']);
break;
}
}
}
register the command and make some schedulers to the app\Console\Kernel.php
:
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use App\Console\Commands\ExampleSchedulerTest;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
ExampleSchedulerTest::class,
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('example:scheduler-test debug --message="debug everyMinute"')->everyMinute();
$schedule->command('example:scheduler-test info --message="info everyFiveMinutes"')->everyFiveMinutes();
$schedule->command('example:scheduler-test notice --message="notice everyTenMinutes"')->everyTenMinutes();
$schedule->command('example:scheduler-test warning --message="warning everyFifteenMinutes"')->everyFifteenMinutes();
$schedule->command('example:scheduler-test error --message="error everyThirtyMinutes"')->everyThirtyMinutes();
$schedule->command('example:scheduler-test critical --message="critical hourly"')->hourly();
$schedule->command('example:scheduler-test alert --message="alert hourlyAt 17"')->hourlyAt(17);
$schedule->command('example:scheduler-test emergency --message="emergency daily"')->daily();
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
you can try the command first to make sure it works, by executing this command in your workspace bash inside your project:
php artisan example:scheduler-test debug --message="debug message"
Setup the scheduler configuration
We still use our example directories:
- projects
|_ my-awesome-laravel-app
|_ laradock
Look for this workspace\crontab\laradock
file inside laradock directory.
- projects
|_ my-awesome-laravel-app
|_ laradock
|_ workspace
|_ crontab
|_ laradock
Then make sure the line inside workspace\crontab\laradock
is not commented-out. The content should be like this:
* * * * * laradock /usr/bin/php /var/www/artisan schedule:run >> /dev/null 2>&1
Further inside laradock directory, you will find this file php-worker\supervisord.d\laravel-scheduler.conf.example
. Duplicate this file into my-awesome-laravel-app-scheduler.conf
(the name can be different, as long as you end it with .conf).
- projects
|_ my-awesome-laravel-app
|_ laradock
|_ php-worker
|_ supervisord.d
|_ laravel-scheduler.conf.example
|_ my-awesome-laravel-app-scheduler.conf
|_ workspace
|_ crontab
|_ laradock
Then modify the my-awesome-laravel-app-scheduler.conf
content into:
[program:my-awesome-laravel-app-scheduler]
process_name=%(program_name)s_%(process_num)02d
command=/bin/sh -c "while [ true ]; do (php /var/www/my-awesome-laravel-app/artisan schedule:run --verbose --no-interaction &); sleep 60; done"
autostart=true
autorestart=true
numprocs=1
user=laradock
redirect_stderr=true
And that's all for the scheduler configuration.
Run or restart the PHP-Worker container
If you haven't run the php-worker
container, execute this command inside laradock directory:
docker-compose up -d php-worker
If it's already running, you may want to restart it using this command:
docker-compose restart php-worker
Check the Laravel Log
Look for the latest log file inside storage/logs
in your laravel app, you should see the logs similar to this:
[2020-03-23 17:41:00] local.DEBUG: debug everyMinute
[2020-03-23 17:41:02] local.INFO: info everyFiveMinutes
[2020-03-23 17:41:04] local.NOTICE: notice everyTenMinutes
[2020-03-23 17:41:55] local.DEBUG: debug everyMinute
[2020-03-23 17:42:55] local.DEBUG: debug everyMinute
[2020-03-23 17:43:55] local.DEBUG: debug everyMinute
[2020-03-23 17:44:56] local.DEBUG: debug everyMinute
[2020-03-23 17:45:55] local.DEBUG: debug everyMinute
[2020-03-23 17:45:56] local.INFO: info everyFiveMinutes
[2020-03-23 17:45:57] local.WARNING: warning everyFifteenMinutes
[2020-03-23 17:46:55] local.DEBUG: debug everyMinute
[2020-03-23 17:47:56] local.DEBUG: debug everyMinute
[2020-03-23 17:48:56] local.DEBUG: debug everyMinute
[2020-03-23 17:49:56] local.DEBUG: debug everyMinute
[2020-03-23 17:50:56] local.DEBUG: debug everyMinute
[2020-03-23 17:50:56] local.INFO: info everyFiveMinutes
[2020-03-23 17:50:57] local.NOTICE: notice everyTenMinutes
[2020-03-23 17:51:56] local.DEBUG: debug everyMinute
[2020-03-23 17:52:56] local.DEBUG: debug everyMinute
[2020-03-23 17:53:56] local.DEBUG: debug everyMinute
[2020-03-23 17:54:56] local.DEBUG: debug everyMinute
[2020-03-23 17:55:56] local.DEBUG: debug everyMinute
[2020-03-23 17:55:57] local.INFO: info everyFiveMinutes
[2020-03-23 17:56:56] local.DEBUG: debug everyMinute
[2020-03-23 17:57:56] local.DEBUG: debug everyMinute
[2020-03-23 17:58:56] local.DEBUG: debug everyMinute
[2020-03-23 17:59:56] local.DEBUG: debug everyMinute
[2020-03-23 18:00:56] local.DEBUG: debug everyMinute
[2020-03-23 18:00:58] local.INFO: info everyFiveMinutes
[2020-03-23 18:00:59] local.NOTICE: notice everyTenMinutes
[2020-03-23 18:01:00] local.WARNING: warning everyFifteenMinutes
[2020-03-23 18:01:01] local.ERROR: error everyThirtyMinutes
[2020-03-23 18:01:02] local.CRITICAL: critical hourly
Have fun exploring the scheduler in Laradock!
laravel version used: 6.0 LTS
Top comments (2)
Great articles! Just to be perfectly clear, either crontab setup within workspace or scheduler config in supervisor.d within php-worker is enough. We don't need to have the 2 setups at the same time. To me, having those 2 setups sounds like redundant. Please correct me if I'm wrong.
Maybe, I haven't figured it out how to make it executes
schedule:run
andqueue:work
simultaneously in one worker and worked as we expected.I just following it from the laradock documentation.