> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Logging

> Aprende a registrar el comportamiento de tu aplicación en archivos, Slack o servicios externos usando el sistema de logging de Laravel.

## ¿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](https://github.com/Seldaek/monolog), lo que permite aprovechar sus numerosos handlers y formatters.

<Info>
  Por defecto se usa el canal `stack`. Es un canal "padre" que agrupa varios canales.
</Info>

## Configuración

La configuración se centraliza en `config/logging.php`. La variable de entorno `LOG_CHANNEL` permite cambiar el canal por defecto.

```php theme={null}
// config/logging.php
'default' => env('LOG_CHANNEL', 'stack'),
```

### Drivers de canal disponibles

| Driver     | Descripción                                                            |
| ---------- | ---------------------------------------------------------------------- |
| `single`   | Escribe todos los logs en un único archivo                             |
| `daily`    | Divide los archivos por día (con rotación)                             |
| `slack`    | Envía mensajes al Incoming Webhook de Slack                            |
| `stack`    | Canal padre que agrupa varios canales                                  |
| `syslog`   | Escribe en el syslog del sistema                                       |
| `errorlog` | Escribe en el error log de PHP                                         |
| `monolog`  | Permite especificar un handler de Monolog directamente                 |
| `custom`   | Permite personalizar completamente el canal mediante una clase factory |

### Niveles de log

Laravel soporta los ocho niveles definidos en la [RFC 5424](https://tools.ietf.org/html/rfc5424).
Ordenados de mayor a menor gravedad:

| Nivel       | Ejemplos de uso                                                                 |
| ----------- | ------------------------------------------------------------------------------- |
| `emergency` | El sistema no está operativo. Respuesta inmediata                               |
| `alert`     | Situación que requiere intervención humana inmediata (por ejemplo, corte de BD) |
| `critical`  | Fallo grave que detiene funciones principales                                   |
| `error`     | Error en tiempo de ejecución. Requiere acción, no siempre inmediata             |
| `warning`   | Problema potencial (uso de APIs deprecadas, datos inesperados…)                 |
| `notice`    | Funcionamiento normal pero relevante                                            |
| `info`      | Operaciones habituales (login del usuario, confirmación de pedido…)             |
| `debug`     | Informació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`.

```php theme={null}
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 theme={null}
<?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`.

```php theme={null}
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.

```php theme={null}
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.

```php theme={null}
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.

```php theme={null}
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.

```php theme={null}
// 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`.

<Tip>
  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.
</Tip>

### Canal daily — rotación de logs

El canal `daily` separa los archivos por fecha y borra automáticamente los antiguos.

```php theme={null}
'daily' => [
    'driver' => 'daily',
    'path'   => storage_path('logs/laravel.log'),
    'level'  => env('LOG_LEVEL', 'debug'),
    'days'   => env('LOG_DAILY_DAYS', 14), // Guarda 14 días
],
```

<Warning>
  Un `days` pequeño elimina antes los logs antiguos.
  Asegúrate de mantener el suficiente historial para poder investigar incidentes en producción.
</Warning>

### Notificaciones de error a Slack

Obtén el [Incoming Webhook URL de Slack](https://slack.com/apps/A0F7XDUAZ-incoming-webhooks) y configúralo en `.env`.

```ini theme={null}
LOG_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/xxx/yyy/zzz
```

```php theme={null}
// 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.

```php theme={null}
// 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.

```php theme={null}
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.

<Steps>
  <Step title="Crear el middleware">
    ```shell theme={null}
    php artisan make:middleware AssignRequestId
    ```
  </Step>

  <Step title="Implementar el método handle()">
    ```php theme={null}
    <?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;
        }
    }
    ```
  </Step>

  <Step title="Registrar el middleware">
    Regístralo como middleware global en `bootstrap/app.php`.

    ```php theme={null}
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->append(\App\Http\Middleware\AssignRequestId::class);
    })
    ```
  </Step>
</Steps>

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.

```php theme={null}
// config/logging.php
'deprecations' => [
    'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),
    'trace'   => env('LOG_DEPRECATIONS_TRACE', false),
],
```

Indica el canal en `.env`.

```ini theme={null}
LOG_DEPRECATIONS_CHANNEL=daily
```

## Laravel Pail — observación de logs en tiempo real

[Laravel Pail](https://github.com/laravel/pail) es una herramienta de desarrollo que te permite ver los logs de la aplicación en tiempo real desde la terminal.

<Info>
  Pail requiere la extensión [PCNTL](https://www.php.net/manual/es/book.pcntl.php) de PHP.
</Info>

### Instalación

```shell theme={null}
composer require --dev laravel/pail
```

### Uso básico

```shell theme={null}
# 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

```shell theme={null}
# 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

<AccordionGroup>
  <Accordion title="Cómo elegir el nivel de log">
    | Nivel       | Cuándo usarlo                                                           |
    | ----------- | ----------------------------------------------------------------------- |
    | `emergency` | Fallo catastrófico que detiene todo el sistema                          |
    | `alert`     | Situación que requiere intervención humana inmediata                    |
    | `critical`  | Fallo grave con funciones principales caídas                            |
    | `error`     | Error en tiempo de ejecución inesperado. Requiere acción                |
    | `warning`   | Uso de APIs deprecadas o datos inesperados                              |
    | `notice`    | Operación normal pero relevante de registrar                            |
    | `info`      | Operaciones del usuario o eventos de negocio                            |
    | `debug`     | Información detallada durante el desarrollo (innecesaria en producción) |
  </Accordion>

  <Accordion title="Guía para elegir canal">
    * **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`.
  </Accordion>

  <Accordion title="Consideraciones para producción">
    * 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.
  </Accordion>
</AccordionGroup>


## Related topics

- [Introducción a Laravel Nightwatch](/es/blog/nightwatch-introduction.md)
- [Laravel Pulse](/es/pulse.md)
- [Manejo de errores](/es/error-handling.md)
- [Actualización de Laravel 9 a 10](/es/blog/upgrade-9-to-10.md)
- [Trait Conditionable](/es/advanced/conditionable.md)
