Saltar al contenido principal

¿Qué es el logging?

El logging de Laravel se diseña en torno al concepto de canales. Un canal es una unidad de configuración que define dónde y cómo se escriben los logs. Se pueden combinar destinos como archivos, Slack, syslog, etc. Internamente utiliza la librería Monolog, lo que permite aprovechar sus numerosos handlers y formatters.
Por defecto se usa el canal stack. Es un canal “padre” que agrupa varios canales.

Configuración

La configuración se centraliza en config/logging.php. La variable de entorno LOG_CHANNEL permite cambiar el canal por defecto.
// config/logging.php
'default' => env('LOG_CHANNEL', 'stack'),

Drivers de canal disponibles

DriverDescripción
singleEscribe todos los logs en un único archivo
dailyDivide los archivos por día (con rotación)
slackEnvía mensajes al Incoming Webhook de Slack
stackCanal padre que agrupa varios canales
syslogEscribe en el syslog del sistema
errorlogEscribe en el error log de PHP
monologPermite especificar un handler de Monolog directamente
customPermite personalizar completamente el canal mediante una clase factory

Niveles de log

Laravel soporta los ocho niveles definidos en la RFC 5424. Ordenados de mayor a menor gravedad:
NivelEjemplos de uso
emergencyEl sistema no está operativo. Respuesta inmediata
alertSituación que requiere intervención humana inmediata (por ejemplo, corte de BD)
criticalFallo grave que detiene funciones principales
errorError en tiempo de ejecución. Requiere acción, no siempre inmediata
warningProblema potencial (uso de APIs deprecadas, datos inesperados…)
noticeFuncionamiento normal pero relevante
infoOperaciones habituales (login del usuario, confirmación de pedido…)
debugInformación detallada durante el desarrollo
La opción level del canal indica el nivel mínimo. Por ejemplo, con level = error solo se escriben error y niveles superiores (critical, alert, emergency).

Uso básico

Fachada Log

Escribe mensajes de cada nivel con la fachada Illuminate\Support\Facades\Log.
use Illuminate\Support\Facades\Log;

Log::emergency('El sistema está caído.');
Log::alert('Se ha perdido la conexión con la base de datos.');
Log::critical('El servicio de pagos no responde.');
Log::error('Ha fallado la actualización de los datos del usuario.');
Log::warning('Se ha llamado a un método deprecado.');
Log::notice('El archivo de configuración se ha recargado.');
Log::info('El usuario ha iniciado sesión.');
Log::debug('Tiempo de ejecución de la consulta: 42ms');
Uso en un controlador:
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;

class UserController extends Controller
{
    public function show(string $id): View
    {
        Log::info('Se muestra el perfil del usuario.', ['user_id' => $id]);

        return view('user.profile', [
            'user' => User::findOrFail($id),
        ]);
    }
}

Función helper log()

Con el helper log() puedes registrar sin importar la fachada Log.
log('Log desde el helper.');

// También puedes indicar nivel y contexto
log('Usuario creado.', 'info', ['user_id' => $user->id]);

Añadir contexto

Puedes pasar contexto (un array) junto al mensaje para registrar información relacionada.
Log::info('Fallo de inicio de sesión.', [
    'user_id' => $user->id,
    'ip'      => $request->ip(),
    'reason'  => 'Contraseña no coincide',
]);

withContext() — contexto común para todo el canal

Para que todas las entradas siguientes del canal lleven un contexto común, usa withContext(). Es adecuado para información que quieras incluir en todos los logs, como un ID de solicitud.
Log::withContext(['request-id' => (string) Str::uuid()]);

// A partir de aquí todos los logs incluyen automáticamente request-id
Log::info('Comienza el procesamiento.');
Log::error('Se ha producido un error.');

shareContext() — contexto común a todos los canales

withContext() solo afecta al canal en cuestión, pero shareContext() añade el contexto común a todos los canales.
Log::shareContext(['app-version' => config('app.version')]);

Configuración de canales

Canal stack — escribir en varios canales a la vez

Con el canal stack puedes escribir en varios canales con una única llamada de log.
// config/logging.php
'channels' => [
    'stack' => [
        'driver'   => 'stack',
        'channels' => ['daily', 'slack'],
    ],

    'daily' => [
        'driver' => 'daily',
        'path'   => storage_path('logs/laravel.log'),
        'level'  => env('LOG_LEVEL', 'debug'),
        'days'   => 14,
    ],

    'slack' => [
        'driver'   => 'slack',
        'url'      => env('LOG_SLACK_WEBHOOK_URL'),
        'username' => env('LOG_SLACK_USERNAME', 'Laravel Log'),
        'emoji'    => env('LOG_SLACK_EMOJI', ':boom:'),
        'level'    => 'critical',
    ],
],
Con esta configuración, todos los logs debug y superiores se escriben en daily (archivo), y solo los critical y superiores se envían también a slack.
En producción es recomendable configurar el canal slack con nivel error o critical. Si envías logs menores a Slack, se generará mucho ruido y las alertas importantes quedarán enterradas.

Canal daily — rotación de logs

El canal daily separa los archivos por fecha y borra automáticamente los antiguos.
'daily' => [
    'driver' => 'daily',
    'path'   => storage_path('logs/laravel.log'),
    'level'  => env('LOG_LEVEL', 'debug'),
    'days'   => env('LOG_DAILY_DAYS', 14), // Guarda 14 días
],
Un days pequeño elimina antes los logs antiguos. Asegúrate de mantener el suficiente historial para poder investigar incidentes en producción.

Notificaciones de error a Slack

Obtén el Incoming Webhook URL de Slack y configúralo en .env.
LOG_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/xxx/yyy/zzz
// config/logging.php
'slack' => [
    'driver'   => 'slack',
    'url'      => env('LOG_SLACK_WEBHOOK_URL'),
    'username' => 'Laravel Error Bot',
    'emoji'    => ':fire:',
    'level'    => 'error',
],
Incluye slack en el canal stack y establece LOG_CHANNEL=stack para notificar automáticamente los errores.

Escribir en un canal concreto

Con Log::channel() puedes indicar explícitamente el canal.
// Escribe solo en el canal slack
Log::channel('slack')->error('El servicio de pagos no responde.');

// Escribe en varios canales a la vez
Log::stack(['daily', 'slack'])->critical('Ha fallado la conexión con la base de datos.');

Canales on-demand

Con Log::build() puedes crear un canal personalizado en el momento, sin definirlo en el archivo de configuración. Útil para pruebas o destinos de salida temporales.
use Illuminate\Support\Facades\Log;

$channel = Log::build([
    'driver' => 'single',
    'path'   => storage_path('logs/import-' . now()->format('Ymd') . '.log'),
]);

Log::stack([$channel])->info('Comienza la importación de CSV.');

Casos prácticos

Añadir un ID de solicitud desde un middleware

Añadir a todos los logs un ID de solicitud común facilita el seguimiento del flujo de una solicitud.
1

Crear el middleware

php artisan make:middleware AssignRequestId
2

Implementar el método handle()

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;

class AssignRequestId
{
    public function handle(Request $request, Closure $next): Response
    {
        $requestId = (string) Str::uuid();

        Log::withContext(['request-id' => $requestId]);

        $response = $next($request);

        $response->headers->set('X-Request-Id', $requestId);

        return $response;
    }
}
3

Registrar el middleware

Regístralo como middleware global en bootstrap/app.php.
->withMiddleware(function (Middleware $middleware) {
    $middleware->append(\App\Http\Middleware\AssignRequestId::class);
})
Tras esta configuración, todos los logs incluirán automáticamente request-id.
[2026-03-01 12:00:00] local.INFO: El usuario ha iniciado sesión. {"request-id":"550e8400-...","user_id":1}
[2026-03-01 12:00:00] local.INFO: Se muestra el dashboard. {"request-id":"550e8400-..."}

Registro de avisos de deprecación

Puedes dejar en el log los avisos de uso de funciones deprecadas de PHP o Laravel.
// config/logging.php
'deprecations' => [
    'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),
    'trace'   => env('LOG_DEPRECATIONS_TRACE', false),
],
Indica el canal en .env.
LOG_DEPRECATIONS_CHANNEL=daily

Laravel Pail — observación de logs en tiempo real

Laravel Pail es una herramienta de desarrollo que te permite ver los logs de la aplicación en tiempo real desde la terminal.
Pail requiere la extensión PCNTL de PHP.

Instalación

composer require --dev laravel/pail

Uso básico

# Ver los logs en streaming
php artisan pail

# Vista detallada (sin abreviaciones)
php artisan pail -v

# Mostrar también la traza
php artisan pail -vv

Filtrado de logs

# Filtrar por palabra clave
php artisan pail --filter="QueryException"

# Filtrar solo por el mensaje
php artisan pail --message="login"

# Filtrar por nivel
php artisan pail --level=error

# Mostrar solo los logs de un usuario
php artisan pail --user=1

Resumen

NivelCuándo usarlo
emergencyFallo catastrófico que detiene todo el sistema
alertSituación que requiere intervención humana inmediata
criticalFallo grave con funciones principales caídas
errorError en tiempo de ejecución inesperado. Requiere acción
warningUso de APIs deprecadas o datos inesperados
noticeOperación normal pero relevante de registrar
infoOperaciones del usuario o eventos de negocio
debugInformación detallada durante el desarrollo (innecesaria en producción)
  • Desarrollo: escribe en un archivo con single o daily.
  • Producción: usa stack combinando daily (guardado en archivo) y slack (notificaciones de error).
  • Logs de tareas concretas: crea un canal on-demand con Log::build() para escribir en un archivo independiente.
  • Observación en tiempo real: consúltalos desde la terminal con php artisan pail.
  • Los logs debug pueden contener información sensible. En producción se recomienda LOG_LEVEL=error o superior.
  • Rota los archivos regularmente para no saturar el disco (ajuste days del canal daily).
  • Ten en cuenta el rate limit de servicios externos como Slack. Configura el nivel para notificar solo errores importantes.
Última modificación el 13 de julio de 2026