posts/BtqwzDuGCAoeihnNbeCmH0GeYFnM5WFlr9h8lasr.png

Logs para procesos largos en Laravel: monitoreo y trazabilidad

Guía práctica para diseñar logs efectivos en procesos largos con Laravel: Jobs, batch, ETL y tareas programadas. Aprende a monitorear, depurar y auditar flujos reales en producción.

En Laravel, los procesos largos son inevitables:

  • Jobs pesados

  • ETL

  • Importaciones masivas

  • Cierres contables

  • Sincronizaciones externas

  • Procesos programados por Scheduler

El problema no es que tarden.
El problema es no saber qué está pasando mientras corren.

Un proceso largo sin logs útiles es una caja negra:

  • No sabes si sigue vivo

  • No sabes en qué paso va

  • No sabes qué falló

  • No sabes si ya terminó

Este artículo explica cómo diseñar logs útiles para procesos largos en Laravel, no solo cómo “loggear algo”.

Error común: loggear solo errores

Muchos proyectos solo tienen:

Log::error($e->getMessage());

Eso sirve cuando ya falló, pero no ayuda a responder preguntas como:

  • ¿En qué parte va el proceso?

  • ¿Cuántos registros ya procesó?

  • ¿Cuánto tiempo lleva?

  • ¿Dónde se quedó colgado?

Para procesos largos, los logs deben contar una historia.

Qué es un proceso largo (desde logs)

Desde el punto de vista de logging, un proceso largo es aquel que:

  • Dura más de unos segundos

  • Tiene múltiples pasos

  • Procesa múltiples registros

  • Puede fallar parcialmente

  • No tiene feedback inmediato al usuario

Esto exige logs estructurados y progresivos.

Principio base: logs por etapas, no por líneas

Un buen proceso largo tiene etapas claras:

  • Inicio

  • Preparación

  • Procesamiento

  • Finalización

  • Error (si ocurre)

Ejemplo básico:

Log::info('[IMPORT] Started', [
    'job_id' => $this->job?->getJobId(),
]);
Log::info('[IMPORT] Processing chunk', [
    'chunk' => $index,
    'count' => $items->count(),
]);
Log::info('[IMPORT] Completed', [
    'processed' => $total,
    'duration' => $seconds,
]);

Logs con contexto (no texto suelto)

Nunca loggees solo texto.

❌ Mal:

Log::info('Processing item');

✅ Bien:

Log::info('[ETL] Processing item', [
    'external_id' => $row['id'],
    'step' => 'transform',
]);

Esto permite:

  • Filtrar

  • Buscar

  • Correlacionar

  • Analizar en herramientas externas

Identificadores obligatorios en procesos largos

Todo proceso largo debe tener al menos uno de estos:

  • job_id

  • process_id

  • batch_id

  • run_id

Ejemplo:

$runId = Str::uuid();

Log::info('[BATCH] Started', [
    'run_id' => $runId,
]);

Y reutilizarlo en todos los logs del proceso.

Esto es oro puro para debugging.

Logs de progreso (heartbeat)

En procesos que duran minutos:

Log::info('[ETL] Progress', [
    'processed' => $current,
    'total' => $total,
    'percentage' => round($current / $total * 100, 2),
]);

Esto responde:

  • ¿Sigue vivo?

  • ¿Avanza?

  • ¿Está atorado?

Logs de errores por registro (no por proceso)

En ETL o batch:

try {
    $this->processRow($row);
} catch (\Throwable $e) {
    Log::warning('[ETL] Row failed', [
        'external_id' => $row['id'] ?? null,
        'error' => $e->getMessage(),
    ]);
}

Regla clave:

Un error de datos no debe ensuciar el log general del proceso.

Logs y Jobs: cuidado con el ruido

En Jobs reintentables:

  • No loggees el mismo error 10 veces

  • Loggea:

    • Inicio

    • Reintento

    • Fallo final

Ejemplo:

public function failed(\Throwable $e)
{
    Log::critical('[JOB] Failed permanently', [
        'job_id' => $this->job?->getJobId(),
        'error' => $e->getMessage(),
    ]);
}

Logs separados por proceso

Para procesos largos críticos, usa canales dedicados:

'channels' => [
    'etl' => [
        'driver' => 'single',
        'path' => storage_path('logs/etl.log'),
        'level' => 'info',
    ],
],

Y luego:

Log::channel('etl')->info('[ETL] Started');

Ventajas:

  • Menos ruido

  • Logs legibles

  • Debugging rápido

Qué NO debes loggear

Evita:

  • Datos sensibles

  • Payloads gigantes sin control

  • Logs dentro de loops sin límite

  • Dumps completos de excepciones en producción

Un buen log informa, no satura.

Logs + Scheduler + ETL

Relación directa:

  • Scheduler → log de disparo

  • Job → log de ejecución

  • ETL → log por etapa

  • Error → log estructurado

Así puedes reconstruir:

“Qué pasó anoche a las 2:00 am”

Sin adivinar.

Relación con la serie completa

Este artículo conecta directamente con:

  • Idempotencia → logs ayudan a detectar duplicados

  • Transacciones → logs marcan commits/rollbacks

  • ETL → logs por registro y fase

  • Scheduler → logs de ejecución programada

Sin logs, todo lo anterior es invisible.

Conclusión

Los logs en procesos largos no son para “ver errores”.
Son para entender el sistema mientras vive.

Un buen logging:

  • Reduce tiempos de debugging

  • Evita reprocesos innecesarios

  • Da confianza en producción

  • Permite escalar sin miedo

Si un proceso largo no tiene buenos logs,
no está listo para producción.

Comparte esta publicación

0 comentarios

Únete a la conversación y comparte tu experiencia.

Dejar un comentario

Comparte dudas, propuestas o mejoras para la comunidad.