DEV Community

Vigilmon
Vigilmon

Posted on • Originally published at vigilmon.online

How to Monitor Laravel Background Jobs (Horizon + Queues) with Vigilmon

How to Monitor Laravel Background Jobs (Horizon + Queues) with Vigilmon

Laravel Horizon is the queue monitoring dashboard for Redis-backed queues. But Horizon itself doesn't alert you when queues stop processing or when your app is down. This guide covers a complete monitoring setup for Laravel Horizon and PHP background jobs using Vigilmon.

The Problem with Laravel Queue Monitoring

Laravel Horizon shows you what's happening with your queues — but only if:

  1. The Horizon dashboard itself is accessible
  2. Someone is watching it
  3. The Redis server is up
  4. The queue worker processes are running

Vigilmon provides external monitoring that alerts you when any of these assumptions break.

Setting Up Heartbeat Monitoring for Horizon

The most important monitor for queues is a heartbeat — a job that runs on a schedule and proves the queue is processing.

Step 1: Create a Heartbeat Job

<?php
// app/Jobs/VigilmonHeartbeatJob.php

namespace AppJobs;

use IlluminateBusQueueable;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsQueueShouldQueue;
use IlluminateFoundationBusDispatchable;
use IlluminateSupportFacadesHttp;

class VigilmonHeartbeatJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable;

    public function handle(): void
    {
        Http::get(config('vigilmon.heartbeat_url'));
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Schedule the Job

// app/Console/Kernel.php
protected function schedule(Schedule $schedule): void
{
    $schedule->job(new AppJobsVigilmonHeartbeatJob)
             ->everyFiveMinutes()
             ->name('vigilmon-heartbeat')
             ->withoutOverlapping();
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Configure the Heartbeat URL

# .env
VIGILMON_HEARTBEAT_URL=https://push.vigilmon.online/YOUR_HEARTBEAT_KEY
Enter fullscreen mode Exit fullscreen mode
// config/vigilmon.php
return [
    'heartbeat_url' => env('VIGILMON_HEARTBEAT_URL'),
];
Enter fullscreen mode Exit fullscreen mode

Step 4: Create Heartbeat Monitor in Vigilmon

  1. Log in to vigilmon.online
  2. Click Add MonitorHeartbeat
  3. Set interval to 10 minutes (2x your job frequency)
  4. Alert if no ping received within 10 minutes

Monitoring Horizon's Dashboard Endpoint

Also monitor Horizon's health endpoint:

  1. Add an HTTP monitor in Vigilmon
  2. URL: https://yourapp.com/horizon/api/stats
  3. Check for HTTP 200 status
  4. This verifies Horizon is running and authenticated

Note: Protect your Horizon dashboard with authentication (Laravel's built-in gate).

Monitoring Failed Jobs

Set up a scheduled command that checks for failed jobs and pings Vigilmon differently:

// app/Console/Commands/CheckFailedJobs.php

namespace AppConsoleCommands;

use IlluminateConsoleCommand;
use IlluminateSupportFacadesDB;
use IlluminateSupportFacadesHttp;

class CheckFailedJobs extends Command
{
    protected $signature = 'vigilmon:check-failed-jobs';
    protected $description = 'Alert if failed jobs exceed threshold';

    public function handle(): void
    {
        $failedCount = DB::table('failed_jobs')
            ->where('failed_at', '>', now()->subHour())
            ->count();

        if ($failedCount > 10) {
            // Could ping a separate Vigilmon alert endpoint
            // or just let this fail silently and rely on queue monitor
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

HTTP Uptime Monitoring for Laravel Apps

Beyond queues, monitor your main app:

  1. In Vigilmon, add an HTTP Monitor
  2. URL: https://yourapp.com
  3. Interval: 60 seconds
  4. Enable SSL certificate monitoring for your domain

Health Check Route

// routes/web.php
Route::get('/health', function () {
    try {
        DB::connection()->getPdo();
        $db = 'connected';
    } catch (Exception $e) {
        return response()->json(['status' => 'error', 'db' => 'disconnected'], 503);
    }

    $redis = Cache::store('redis')->ping() === true ? 'connected' : 'disconnected';

    return response()->json([
        'status' => 'ok',
        'db' => $db,
        'redis' => $redis,
        'horizon' => IlluminateSupportFacadesRedis::connection()->ping(),
    ]);
});
Enter fullscreen mode Exit fullscreen mode

Monitor /health in Vigilmon for a real health signal.

Monitoring Horizon Supervisor Processes

Horizon runs supervisor processes for different queues. If a supervisor dies, jobs queue up but don't process. Check Horizon's API:

// app/Console/Commands/CheckHorizonProcesses.php
$stats = json_decode(
    Http::get('http://localhost/horizon/api/stats')->body()
);

if ($stats->processes === 0) {
    // Alert: Horizon has no active processes
}
Enter fullscreen mode Exit fullscreen mode

Recommended Alert Configuration

Monitor Alert When Channel
App HTTP Down 2+ checks Slack + email
Health endpoint Returns 503 Slack
Queue heartbeat Missing 10+ min PagerDuty
SSL cert 14 days to expiry Email

Summary

Laravel Horizon + Vigilmon gives you complete queue monitoring coverage:

  1. Uptime monitorhttps://yourapp.com
  2. Health check monitor/health with DB + Redis checks
  3. Heartbeat monitor — dispatched every 5 minutes via Horizon
  4. SSL monitor — auto-renew failure detection
  5. Status page — public transparency

The heartbeat monitor is the most critical — it proves your queue is actually processing jobs, not just running.


Vigilmon — uptime monitoring and heartbeat checks for Laravel applications.

Top comments (0)