Vigilance en Laravel: Monitorea Queues, Commands y Schedulers
Vigilance en Laravel: Monitorea Queues, Commands y Schedulers
Si trabajas con aplicaciones Laravel en producción, sabes que monitorear la salud de tus colas, comandos Artisan y tareas programadas es crítico. El problema es que no siempre tienes herramientas claras para ver qué está pasando en segundo plano. Vigilance es un dashboard self-hosted que soluciona exactamente esto, proporcionando visibilidad completa sobre el ciclo de vida de jobs, comandos y scheduled tasks.
En este artículo, exploraremos cómo instalar, configurar y usar Vigilance en tus proyectos Laravel para obtener monitoreo profesional sin depender de servicios externos.
¿Qué es Vigilance?
Vigilance es un paquete Laravel que registra el ciclo de vida completo de:
- Jobs en colas: Seguimiento desde que se envían hasta que se completan o fallan
- Comandos Artisan: Ejecución manual de cualquier comando
- Tareas programadas: Monitoreo de todos los scheduled tasks
Lo interesante es que funciona con cualquier driver de colas (Redis, database, sync, SQS, etc.) y ofrece controles específicos para producción como muestreo (sampling) y despacho manual de tareas.
Por qué usar Vigilance
Antes de Vigilance, tus opciones eran limitadas:
- Laravel Horizon: Excelente pero solo para Redis
- Logs manuales: Tedioso y poco visual
- Servicios externos: Costo adicional y dependencia de terceros
Vigilance te da:
- Dashboard limpio y funcional
- Funcionamiento con cualquier driver
- Self-hosted (control total)
- Capacidad de despachar jobs manualmente
- Muestreo inteligente para no saturar la BD
Instalación de Vigilance
El proceso es muy sencillo. Primero, instala el paquete vía Composer:
composer require laravel/vigilance
Luego, publica los assets y migraciones:
php artisan vendor:publish --provider="Laravel\Vigilance\VigilanceServiceProvider"
php artisan migrate
Esto creará las tablas necesarias para almacenar los registros de jobs, comandos y scheduled tasks.
Configuración básica
El archivo de configuración se publica en config/vigilance.php. Aquí está la estructura típica:
<?php
return [
'enabled' => env('VIGILANCE_ENABLED', true),
'path' => 'vigilance',
'middleware' => ['web', 'auth'],
'database' => [
'connection' => env('DB_CONNECTION', 'default'),
'table_prefix' => 'vigilance_',
],
'sampling' => [
'enabled' => env('VIGILANCE_SAMPLING_ENABLED', true),
'percentage' => env('VIGILANCE_SAMPLING_PERCENTAGE', 100),
],
'retention' => [
'days' => env('VIGILANCE_RETENTION_DAYS', 7),
],
];
Explicación de las opciones principales:
- enabled: Activa o desactiva Vigilance globalmente
- path: Ruta donde acceder al dashboard (ej:
/vigilance) - middleware: Middlewares que protegen el acceso (recomendado autenticación)
- sampling: En producción, puedes registrar solo un porcentaje para no saturar BD
- retention: Cuántos días mantener los registros
Configurar Vigilance en tu aplicación
Una vez instalado, Vigilance captura automáticamente jobs y comandos. Sin embargo, necesitas asegurar que tus ServiceProviders estén correctamente configurados.
En app/Providers/AppServiceProvider.php, añade:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Laravel\Vigilance\Vigilance;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
if ($this->app->environment('production')) {
Vigilance::sample(10); // Registra solo el 10% en producción
}
}
}
La método sample() es crucial en producción. Si registras todo, la base de datos crecerá exponencialmente. Con muestreo al 10%, obtienes visibilidad sin sobrecargar.
Trabajar con Jobs
Cuando despaches un job, Vigilance lo registra automáticamente:
<?php
namespace App\Jobs;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
class ProcessPodcast implements ShouldQueue
{
use Queueable;
public function __construct(
public string $podcastId,
public string $episodeId,
) {}
public function handle(): void
{
// Procesar el podcast
sleep(2);
}
}
Para despachar el job:
use App\Jobs\ProcessPodcast;
// Despachar a la cola
ProcessPodcast::dispatch('podcast-123', 'episode-456');
// Despachar en el futuro
ProcessPodcast::dispatch('podcast-123', 'episode-456')
->delay(now()->addMinutes(10));
// Despachar a una cola específica
ProcessPodcast::dispatch('podcast-123', 'episode-456')
->onQueue('high-priority');
Vigilance capturará automáticamente:
- Cuándo fue despachado
- Cuándo comenzó la ejecución
- Cuándo se completó
- Si falló, el error exacto
Monitorear Scheduled Tasks
Para que Vigilance registre tareas programadas, configúralas normalmente en app/Console/Kernel.php:
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
protected function schedule(Schedule $schedule): void
{
// Tarea simple
$schedule->command('emails:send')
->hourly()
->name('Send Emails');
// Tarea con callback
$schedule->call(function () {
\App\Models\User::where('inactive', true)
->delete();
})
->daily()
->name('Delete Inactive Users');
// Comando personalizado
$schedule->command('reports:generate')
->dailyAt('2:00')
->name('Generate Daily Reports');
}
}
Vigilance registrará automáticamente cada ejecución, permitiéndote ver:
- Hora de inicio y fin
- Duración
- Si tuvo errores
- Output del comando
Acceder al Dashboard
Una vez configurado, accede al dashboard en:
https://tuapp.com/vigilance
El dashboard te mostrará:
- Jobs Table: Todos los jobs despachados con su estado
- Commands Table: Comandos Artisan ejecutados
- Scheduled Tasks: Ejecuciones de tareas programadas
Puedes filtrar por estado (pending, running, completed, failed) y ver detalles de cada ejecución.
Despacho Manual de Jobs
Una característica poderosa de Vigilance es que puedes despachar jobs desde el dashboard:
- Ve a la sección “Manual Dispatch”
- Selecciona la clase del job
- Proporciona los parámetros (si los requiere)
- Haz clic en “Dispatch”
Esto es útil para:
- Pruebas rápidas en producción
- Re-ejecutar jobs que fallaron
- Testing de escenarios específicos
Ejemplo completo: Aplicación con Vigilance
Vamos a crear una aplicación pequeña que use Vigilance:
<?php
// app/Jobs/SendNewsletterEmail.php
namespace App\Jobs;
use App\Models\Newsletter;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Mail;
class SendNewsletterEmail implements ShouldQueue
{
use Queueable;
public $tries = 3;
public $backoff = [60, 120, 300]; // Reintentos
public function __construct(
public Newsletter $newsletter,
) {
$this->onQueue('newsletters');
}
public function handle(): void
{
$newsletter->subscribers->each(function ($subscriber) {
Mail::to($subscriber->email)
->queue(new \App\Mail\NewsletterMail($this->newsletter));
});
$this->newsletter->update(['sent_at' => now()]);
}
public function failed(\Throwable $exception): void
{
logger()->error('Newsletter failed', [
'newsletter_id' => $this->newsletter->id,
'error' => $exception->getMessage(),
]);
}
}
Comando para despachar:
<?php
// app/Console/Commands/SendNewsletter.php
namespace App\Console\Commands;
use App\Jobs\SendNewsletterEmail;
use App\Models\Newsletter;
use Illuminate\Console\Command;
class SendNewsletter extends Command
{
protected $signature = 'newsletter:send {newsletter_id?}';
protected $description = 'Send newsletter to all subscribers';
public function handle(): void
{
$query = Newsletter::where('sent_at', null);
if ($newsletter_id = $this->argument('newsletter_id')) {
$query->where('id', $newsletter_id);
}
$newsletters = $query->get();
foreach ($newsletters as $newsletter) {
SendNewsletterEmail::dispatch($newsletter);
$this->line("Newsletter {$newsletter->id} dispatched");
}
$this->info('Done!');
}
}
Scheduler:
<?php
// app/Console/Kernel.php
protected function schedule(Schedule $schedule): void
{
$schedule->command('newsletter:send')
->daily()
->at('09:00')
->name('Send Daily Newsletters')
->emailOutputTo('admin@example.com')
->onFailure(function () {
// Notificación si falla
});
}
Ahora, Vigilance capturará:
- Cada job despachado
- La ejecución del comando
- El resultado de la tarea programada
Optimización en Producción
Muestreo estratégico
// app/Providers/AppServiceProvider.php
public function boot(): void
{
if ($this->app->isProduction()) {
// Registrar solo errores en producción
Vigilance::sampleErrors();
// O un porcentaje específico
Vigilance::sample(5); // 5%
}
}
Limpieza automática
Vigilance incluye un comando para limpiar registros antiguos:
php artisan vigilance:cleanup
Agrégalo a tu scheduler:
$schedule->command('vigilance:cleanup')
->daily()
->at('03:00');
Base de datos dedicada
Para aplicaciones de alto volumen, considera usar una BD separada:
// config/vigilance.php
'database' => [
'connection' => 'monitoring', // Conexión separada
],
Análisis de datos
Puedes consultar los datos de Vigilance programáticamente:
<?php
use Laravel\Vigilance\Models\MonitoredJob;
// Jobs recientes
$recentJobs = MonitoredJob::latest()
->limit(10)
->get();
// Jobs fallidos
$failedJobs = MonitoredJob::where('status', 'failed')
->where('created_at', '>', now()->subDay())
->get();
// Duración promedio
$avgDuration = MonitoredJob::where('job_class', ProcessPodcast::class)
->average('duration_seconds');
Esto es útil para dashboards personalizados o alertas.
Troubleshooting común
Dashboard no aparece
Verifica que Vigilance esté habilitado en .env:
VIGILANCE_ENABLED=true
No se registran jobs
Asegúrate de que tus jobs implementen ShouldQueue:
class MyJob implements ShouldQueue
{
use Queueable;
}
Tabla de Vigilance crece demasiado
Aumenta la retención o reduce el muestreo:
VIGILANCE_SAMPLING_PERCENTAGE=5
VIGILANCE_RETENTION_DAYS=3
Comparativa con otras soluciones
| Característica | Vigilance | Horizon | Logs |
|---|---|---|---|
| Self-hosted | ✅ | ✅ | ✅ |
| Cualquier driver | ✅ | ❌ (Redis) | ❌ |
| Dashboard | ✅ | ✅ | ❌ |
| Muestreo | ✅ | ❌ | ❌ |
| Despacho manual | ✅ | ❌ | ❌ |
| Sin dependencias | ✅ | ❌ (Redis) | ✅ |
Conclusión
Vigilance es una herramienta poderosa para cualquier equipo de desarrollo Laravel que necesite visibilidad sobre sus operaciones en background. Su capacidad de funcionar con cualquier driver de colas, control fino de muestreo y facilidad de instalación lo hacen ideal tanto para startups como para aplicaciones empresariales.
La combinación de un dashboard intuitivo, despacho manual de jobs y análisis de datos la convierte en una solución completa para monitoreo en producción. Si actualmente uses logs manuales o no tengas forma de ver qué está pasando en tus colas, Vigilance es exactamente lo que necesitas.
Puntos clave
- Vigilance es un dashboard self-hosted para monitorear jobs, comandos y scheduled tasks en Laravel
- Funciona con cualquier driver de colas (Redis, database, SQS, etc.)
- Incluye muestreo inteligente para no saturar la base de datos en producción
- Permite despacho manual de jobs desde el dashboard
- La instalación es sencilla:
composer require laravel/vigilance - Ofrece retención configurable para limpiar datos antiguos automáticamente
- Es ideal para debugging en producción sin servicios externos costosos
- Captura automáticamente duración, errores y estado de ejecución
- Puedes consultar los datos programáticamente para análisis personalizados
- Requiere autenticación en el dashboard (configurable en
config/vigilance.php)