Alert via Laravel Log
Alert via Laravel Log
The autoscaler already logs its own activity. This recipe adds structured, filterable alert lines to a dedicated channel so your existing log infrastructure (Papertrail, Loggly, CloudWatch, whatever) can trigger on them.
1. Add a dedicated log channel
config/logging.php:
'channels' => [
// ... your existing channels
'queue-alerts' => [
'driver' => 'daily',
'path' => storage_path('logs/queue-alerts.log'),
'level' => 'warning',
'days' => 14,
],
],
Use whatever driver fits your stack — single, syslog, papertrail, stderr for containers, etc.
2. Register the listener
app/Providers/EventServiceProvider.php:
use Cbox\LaravelQueueAutoscale\Events\SlaBreached;
use Cbox\LaravelQueueAutoscale\Events\SlaRecovered;
use Cbox\LaravelQueueAutoscale\Events\WorkersScaled;
use App\Listeners\LogQueueAlerts;
protected $listen = [
SlaBreached::class => [LogQueueAlerts::class.'@onBreach'],
SlaRecovered::class => [LogQueueAlerts::class.'@onRecovery'],
WorkersScaled::class => [LogQueueAlerts::class.'@onScaled'],
];
3. The listener
app/Listeners/LogQueueAlerts.php:
<?php
namespace App\Listeners;
use Cbox\LaravelQueueAutoscale\Alerting\AlertRateLimiter;
use Cbox\LaravelQueueAutoscale\Events\SlaBreached;
use Cbox\LaravelQueueAutoscale\Events\SlaRecovered;
use Cbox\LaravelQueueAutoscale\Events\WorkersScaled;
use Illuminate\Support\Facades\Log;
class LogQueueAlerts
{
public function __construct(private AlertRateLimiter $limiter) {}
public function onBreach(SlaBreached $event): void
{
Log::channel('queue-alerts')->error('Queue SLA breach', [
'connection' => $event->connection,
'queue' => $event->queue,
'oldest_job_age_seconds' => $event->oldestJobAge,
'sla_target_seconds' => $event->slaTarget,
'pending_jobs' => $event->pending,
'active_workers' => $event->activeWorkers,
]);
}
public function onRecovery(SlaRecovered $event): void
{
Log::channel('queue-alerts')->info('Queue SLA recovered', [
'connection' => $event->connection,
'queue' => $event->queue,
'current_job_age_seconds' => $event->currentJobAge,
'sla_target_seconds' => $event->slaTarget,
]);
}
public function onScaled(WorkersScaled $event): void
{
// WorkersScaled fires per action — rate-limit so flapping doesn't spam the log.
$key = "scaled:{$event->connection}:{$event->queue}";
if (! $this->limiter->allow($key)) {
return;
}
Log::channel('queue-alerts')->notice('Workers scaled', [
'connection' => $event->connection,
'queue' => $event->queue,
'from' => $event->from,
'to' => $event->to,
'action' => $event->action,
'reason' => $event->reason,
]);
}
}
Done
Tail the log to verify:
tail -f storage/logs/queue-alerts-*.log
Point your log aggregator's alert rules at the Queue SLA breach message or the queue-alerts channel directly.
Tuning
SlaBreachedandSlaRecoveredfire once per state transition, so they don't need rate-limiting. OnlyWorkersScaled,ScalingDecisionMade, andSlaBreachPredictedcan be chatty.- Change the cooldown in
config/queue-autoscale.php → alerting.cooldown_secondsor viaQUEUE_AUTOSCALE_ALERT_COOLDOWN. - If your aggregator needs JSON, swap the
dailydriver for one that wraps logs in JSON formatters (e.g.papertrailor a custom Monolog processor).