spatie/laravel-schedule-monitor
Monitor Laravel scheduled tasks by logging starts, finishes, failures, and skips to a database table and viewing run history via an Artisan command. Optionally sync with Oh Dear to get alerts when tasks fail or don’t run on time.
Installation:
composer require spatie/laravel-schedule-monitor
php artisan vendor:publish --provider="Spatie\ScheduleMonitor\ScheduleMonitorServiceProvider" --tag="schedule-monitor-migrations"
php artisan migrate
First Sync:
php artisan schedule-monitor:sync
Verify Sync:
php artisan schedule-monitor:list
Monitor a critical scheduled job (e.g., a nightly report) to ensure it runs reliably:
// app/Console/Kernel.php
protected function schedule(Schedule $schedule) {
$schedule->command('generate:nightly-report')
->dailyAt('23:00')
->monitorName('Nightly Report')
->graceTimeInMinutes(10);
}
Run php artisan schedule-monitor:list to check execution status.
Task Monitoring:
monitorName() to override default naming (e.g., closures or ambiguous tasks).Grace Time Management:
$schedule->command('long-running-job')->hourly()->graceTimeInMinutes(30);
Output Storage:
$schedule->command('backup:database')->daily()->storeOutputInDb();
Oh Dear Integration:
php artisan schedule-monitor:sync --keep-old # Non-destructive sync
.env:
OH_DEAR_API_TOKEN=your_token
OH_DEAR_MONITOR_ID=123
Database Maintenance:
schedule-monitor.php):
// app/Console/Kernel.php
$schedule->command('model:prune', [
'--model' => \Spatie\ScheduleMonitor\Models\MonitoredScheduledTaskLogItem::class
])->daily();
schedule-monitor:sync in your deployment script to ensure Oh Dear stays in sync.PingOhDearJob to not_tenant_aware_jobs in config/multitenancy.php.PingOhDearJob to avoid delays:
'oh_dear' => [
'queue' => 'oh-dear-pings',
]
Name Changes:
monitorName()) deletes all historical logs for the old name. Use cautiously in production.Oh Dear Sync Issues:
schedule-monitor:sync removes all non-Laravel cron jobs from Oh Dear. Use --keep-old to preserve external monitors.PingOhDearJob is stuck, check the oh-dear queue and adjust retry_job_for_minutes in config.Grace Time Misconfiguration:
Output Storage Overhead:
storeOutputInDb) can bloat the meta column. Use sparingly for verbose commands.Failed Pings: Enable debug logging:
OH_DEAR_DEBUG_LOGGING=true
Check logs for cURL timing, connection details, and response data.
Missing Logs:
schedule:run command is in your server’s cron (default: * * * * * cd /path-to-project && php artisan schedule:run >> /dev/null 2>&1).doNotMonitor().Oh Dear Verification:
php artisan schedule-monitor:verify
Fix any missing api_token or monitor_id errors.
Custom Models:
MonitoredScheduledTask or MonitoredScheduledTaskLogItem to add fields (e.g., tenant_id for multitenancy).Log Pruning:
app/Console/Kernel.php for custom retention rules.Alert Customization:
PingOhDearJob to modify payloads or add metadata (e.g., environment tags).UI Integration:
MonitoredScheduledTaskLogItem directly for custom dashboards:
$recentFailures = MonitoredScheduledTaskLogItem::where('type', 'failed')
->orderBy('created_at', 'desc')
->limit(10)
->get();
How can I help you explore Laravel packages today?