Documentación de Laravel 10.x
Aquí encontrarás fragmentos de código de Laravel y consejos útiles sobre desarrollo web.
Para ayudarte a aprender más sobre lo que sucede dentro de tu aplicación, Laravel proporciona servicios de registro robustos que te permiten registrar mensajes en archivos, en el registro de errores del sistema e incluso en Slack para notificar a todo tu equipo.
El registro de Laravel se basa en "canales". Cada canal representa una forma específica de escribir información de registro. Por ejemplo, el canal single
escribe archivos de registro en un solo archivo de registro, mientras que el canal slack
envía mensajes de registro a Slack. Los mensajes de registro pueden escribirse en varios canales según su gravedad.
Bajo el capó, Laravel utiliza la biblioteca Monolog, que proporciona soporte para una variedad de controladores de registro poderosos. Laravel facilita la configuración de estos controladores, lo que te permite combinarlos y personalizar el manejo de registros de tu aplicación.
Todas las opciones de configuración del comportamiento de registro de tu aplicación se encuentran en el archivo de configuración config/logging.php
. Este archivo te permite configurar los canales de registro de tu aplicación, así que asegúrate de revisar cada uno de los canales disponibles y sus opciones. Revisaremos algunas opciones comunes a continuación.
De forma predeterminada, Laravel utilizará el canal stack
al registrar mensajes. El canal stack
se utiliza para agregar múltiples canales de registro en un solo canal. Para obtener más información sobre la creación de stacks, consulta la documentación a continuación.
De forma predeterminada, Monolog se instancia con un "nombre de canal" que coincide con el entorno actual, como production
o local
. Para cambiar este valor, agrega una opción name
a la configuración de tu canal:
'stack' => [ 'driver' => 'stack', 'name' => 'channel-name', 'channels' => ['single', 'slack'],],
Cada canal de registro está impulsado por un "controlador" (driver). El controlador determina cómo y dónde se registra realmente el mensaje de registro. Los siguientes controladores de canal de registro están disponibles en cada aplicación Laravel. Ya hay una entrada para la mayoría de estos controladores en el archivo de configuración config/logging.php
de tu aplicación, así que asegúrate de revisar este archivo para familiarizarte con su contenido:
Nombre | Descripción |
---|---|
custom |
Un controlador que llama a una fábrica especificada para crear un canal |
daily |
Un controlador Monolog basado en RotatingFileHandler que rota diariamente |
errorlog |
Un controlador Monolog basado en ErrorLogHandler |
monolog |
Un controlador de fábrica Monolog que puede usar cualquier manejador Monolog compatible |
papertrail |
Un controlador Monolog basado en SyslogUdpHandler |
single |
Un canal de registro basado en un solo archivo o ruta (StreamHandler ) |
slack |
Un controlador Monolog basado en SlackWebhookHandler |
stack |
Un envoltorio para facilitar la creación de canales "multicanal" |
syslog |
Un controlador Monolog basado en SyslogHandler |
Nota Consulta la documentación sobre personalización avanzada de canales para obtener más información sobre los controladores
monolog
ycustom
.
Los canales single
y daily
tienen tres opciones de configuración opcionales: bubble
, permission
y locking
.
Nombre | Descripción | Predeterminado |
---|---|---|
bubble |
Indica si los mensajes deben propagarse a otros canales después de ser manejados | true |
locking |
Intenta bloquear el archivo de registro antes de escribir en él | false |
permission |
Los permisos del archivo de registro | 0644 |
Además, la política de retención para el canal daily
se puede configurar mediante la opción days
:
Nombre | Descripción | Predeterminado |
---|---|---|
days |
El número de días que se deben retener los archivos de registro diarios | 7 |
El canal papertrail
requiere las opciones de configuración host
y port
. Puedes obtener estos valores desde Papertrail.
El canal slack
requiere una opción de configuración url
. Esta URL debe coincidir con una URL para un webhook entrante que hayas configurado para tu equipo de Slack.
Por defecto, Slack solo recibirá registros en el nivel critical
y superior; sin embargo, puedes ajustar esto en tu archivo de configuración config/logging.php
modificando la opción de configuración level
dentro del array de configuración de tu canal de registro de Slack.
PHP, Laravel y otras bibliotecas a menudo notifican a sus usuarios que algunas de sus funciones han sido declaradas obsoletas y se eliminarán en una versión futura. Si deseas registrar estas advertencias de obsolescencia, puedes especificar tu canal de registro preferido deprecations
en el archivo de configuración config/logging.php
de tu aplicación:
'deprecations' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), 'channels' => [ ...]
O puedes definir un canal de registro llamado deprecations
. Si existe un canal de registro con este nombre, siempre se usará para registrar obsolescencias:
'channels' => [ 'deprecations' => [ 'driver' => 'single', 'path' => storage_path('logs/php-deprecation-warnings.log'), ],],
Como se mencionó anteriormente, el controlador stack
te permite combinar varios canales en un solo canal de registro por conveniencia. Para ilustrar cómo usar los stacks de registro, echemos un vistazo a una configuración de ejemplo que podrías ver en una aplicación en producción:
'channels' => [ 'stack' => [ 'driver' => 'stack', 'channels' => ['syslog', 'slack'], ], 'syslog' => [ 'driver' => 'syslog', 'level' => 'debug', ], 'slack' => [ 'driver' => 'slack', 'url' => env('LOG_SLACK_WEBHOOK_URL'), 'username' => 'Laravel Log', 'emoji' => ':boom:', 'level' => 'critical', ],],
Desglosemos esta configuración. Primero, observa que nuestro canal stack
agrega dos canales adicionales mediante su opción channels
: syslog
y slack
. Por lo tanto, al registrar mensajes, ambos de estos canales tendrán la oportunidad de registrar el mensaje. Sin embargo, como veremos a continuación, si estos canales realmente registran el mensaje puede depender de la gravedad o "nivel" del mensaje.
Observa la opción de configuración level
presente en las configuraciones de canal syslog
y slack
en el ejemplo anterior. Esta opción determina el "nivel" mínimo que debe tener un mensaje para ser registrado por el canal. Monolog, que impulsa los servicios de registro de Laravel, ofrece todos los niveles de registro definidos en la especificación RFC 5424. En orden descendente de gravedad, estos niveles de registro son: emergency, alert, critical, error, warning, notice, info y debug.
Entonces, imagina que registramos un mensaje usando el método debug
:
Log::debug('An informational message.');
Dada nuestra configuración, el canal syslog
escribirá el mensaje en el registro del sistema; sin embargo, como el mensaje de error no es critical
o superior, no se enviará a Slack. Sin embargo, si registramos un mensaje emergency
, se enviará tanto al registro del sistema como a Slack, ya que el nivel emergency
está por encima de nuestro umbral mínimo de nivel para ambos canales:
Log::emergency('The system is down!');
Puedes escribir información en los registros utilizando el fachada Log
. Como se mencionó anteriormente, el registrador proporciona los ocho niveles de registro definidos en la especificación RFC 5424: emergency, alert, critical, error, warning, notice, info y debug:
use Illuminate\Support\Facades\Log; Log::emergency($message);Log::alert($message);Log::critical($message);Log::error($message);Log::warning($message);Log::notice($message);Log::info($message);Log::debug($message);
Puedes llamar a cualquiera de estos métodos para registrar un mensaje para el nivel correspondiente. Por defecto, el mensaje se escribirá en el canal de registro predeterminado configurado en tu archivo de configuración logging
:
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller;use App\Models\User;use Illuminate\Support\Facades\Log;use Illuminate\View\View; class UserController extends Controller{ /** * Muestra el perfil del usuario proporcionado. */ public function show(string $id): View { Log::info('Showing the user profile for user: {id}', ['id' => $id]); return view('user.profile', [ 'user' => User::findOrFail($id) ]); }}
Se puede pasar un array de datos contextuales a los métodos de registro. Estos datos contextuales se formatearán y mostrarán con el mensaje de registro:
use Illuminate\Support\Facades\Log; Log::info('User {id} failed to login.', ['id' => $user->id]);
Ocasionalmente, es posible que desees especificar alguna información contextual que deba incluirse con todas las entradas de registro posteriores en un canal específico. Por ejemplo, es posible que desees registrar un ID de solicitud asociado con cada solicitud entrante a tu aplicación. Para lograr esto, puedes llamar al método withContext
de la fachada Log
:
<?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{ /** * Maneja una solicitud entrante. * * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ public function handle(Request $request, Closure $next): Response { $requestId = (string) Str::uuid(); Log::withContext([ 'request-id' => $requestId ]); $response = $next($request); $response->headers->set('Request-Id', $requestId); return $response; }}
Si deseas compartir información contextual en todos los canales de registro, puedes llamar al método Log::shareContext()
. Este método proporcionará la información contextual a todos los canales creados y a cualquier canal que se cree posteriormente. Normalmente, el método shareContext
debería llamarse desde el método boot
de un proveedor de servicios de la aplicación:
use Illuminate\Support\Facades\Log;use Illuminate\Support\Str; class AppServiceProvider{ /** * Inicializa cualquier servicio de la aplicación. */ public function boot(): void { Log::shareContext([ 'invocation-id' => (string) Str::uuid(), ]); }}
A veces, es posible que desees registrar un mensaje en un canal que no sea el canal predeterminado de tu aplicación. Puedes usar el método channel
de la fachada Log
para recuperar y registrar en cualquier canal definido en tu archivo de configuración:
use Illuminate\Support\Facades\Log; Log::channel('slack')->info('Something happened!');
Si deseas crear un stack de registro a pedido que consista en varios canales, puedes usar el método stack
:
Log::stack(['single', 'slack'])->info('Something happened!');
También es posible crear un canal a pedido proporcionando la configuración en tiempo de ejecución sin que esta configuración esté presente en el archivo de configuración logging
de tu aplicación. Para lograr esto, puedes pasar un array de configuración al método build
de la fachada Log
:
use Illuminate\Support\Facades\Log; Log::build([ 'driver' => 'single', 'path' => storage_path('logs/custom.log'),])->info('Something happened!');
También puedes desear incluir un canal a pedido en un stack de registro a pedido. Esto se puede lograr incluyendo tu instancia de canal a pedido en el array pasado al método stack
:
use Illuminate\Support\Facades\Log; $channel = Log::build([ 'driver' => 'single', 'path' => storage_path('logs/custom.log'),]); Log::stack(['slack', $channel])->info('Something happened!');
En ocasiones, es posible que necesites un control completo sobre cómo se configura Monolog para un canal existente. Por ejemplo, es posible que desees configurar una implementación personalizada de FormatterInterface
de Monolog para el canal incorporado single
de Laravel.
Para empezar, define un array tap
en la configuración del canal. El array tap
debe contener una lista de clases que deberían tener la oportunidad de personalizar (o "intervenir" en) la instancia de Monolog después de que se crea. No hay una ubicación convencional donde deberían colocarse estas clases, así que tienes libertad para crear un directorio dentro de tu aplicación para contener estas clases:
'single' => [ 'driver' => 'single', 'tap' => [App\Logging\CustomizeFormatter::class], 'path' => storage_path('logs/laravel.log'), 'level' => 'debug',],
Una vez que hayas configurado la opción tap
en tu canal, estás listo para definir la clase que personalizará tu instancia de Monolog. Esta clase solo necesita un método: __invoke
, que recibe una instancia de Illuminate\Log\Logger
. La instancia de Illuminate\Log\Logger
delega todas las llamadas de método a la instancia subyacente de Monolog:
<?php namespace App\Logging; use Illuminate\Log\Logger;use Monolog\Formatter\LineFormatter; class CustomizeFormatter{ /** * Personaliza la instancia del registrador proporcionada. */ public function __invoke(Logger $logger): void { foreach ($logger->getHandlers() as $handler) { $handler->setFormatter(new LineFormatter( '[%datetime%] %channel%.%level_name%: %message% %context% %extra%' )); } }}
Nota Todas tus clases "tap" son resueltas por el contenedor de servicios, por lo que cualquier dependencia del constructor que requieran se inyectará automáticamente.
Monolog tiene una variedad de manejadores disponibles y Laravel no incluye un canal incorporado para cada uno. En algunos casos, es posible que desees crear un canal personalizado que sea simplemente una instancia de un manejador Monolog específico que no tiene un controlador de registro Laravel correspondiente. Estos canales se pueden crear fácilmente utilizando el controlador monolog
.
Al usar el controlador monolog
, la opción de configuración handler
se utiliza para especificar qué manejador se instanciará. Opcionalmente, se pueden especificar los parámetros del constructor que el manejador necesita mediante la opción de configuración with
:
'logentries' => [ 'driver' => 'monolog', 'handler' => Monolog\Handler\SyslogUdpHandler::class, 'with' => [ 'host' => 'my.logentries.internal.datahubhost.company.com', 'port' => '10000', ],],
Cuando uses el controlador monolog
, se utilizará el LineFormatter
de Monolog como el formateador predeterminado. Sin embargo, puedes personalizar el tipo de formateador que se pasa al manejador mediante las opciones de configuración formatter
y formatter_with
:
'browser' => [ 'driver' => 'monolog', 'handler' => Monolog\Handler\BrowserConsoleHandler::class, 'formatter' => Monolog\Formatter\HtmlFormatter::class, 'formatter_with' => [ 'dateFormat' => 'Y-m-d', ],],
Si estás utilizando un manejador Monolog que es capaz de proporcionar su propio formateador, puedes establecer el valor de la opción de configuración formatter
en default
:
'newrelic' => [ 'driver' => 'monolog', 'handler' => Monolog\Handler\NewRelicHandler::class, 'formatter' => 'default',],
Monolog también puede procesar mensajes antes de registrarlos. Puedes crear tus propios procesadores o utilizar los procesadores existentes ofrecidos por Monolog.
Si deseas personalizar los procesadores para un controlador monolog
, agrega un valor processors
a la configuración de tu canal:
'memory' => [ 'driver' => 'monolog', 'handler' => Monolog\Handler\StreamHandler::class, 'with' => [ 'stream' => 'php://stderr', ], 'processors' => [ // Sintaxis simple... Monolog\Processor\MemoryUsageProcessor::class, // Con opciones... [ 'processor' => Monolog\Processor\PsrLogMessageProcessor::class, 'with' => ['removeUsedContextFields' => true], ], ],],
Si deseas definir un canal completamente personalizado en el que tengas control total sobre la instanciación y configuración de Monolog, puedes especificar un tipo de controlador custom
en tu archivo de configuración config/logging.php
. Tu configuración debe incluir una opción via
que contenga el nombre de la clase de fábrica que se invocará para crear la instancia de Monolog:
'channels' => [ 'example-custom-channel' => [ 'driver' => 'custom', 'via' => App\Logging\CreateCustomLogger::class, ],],
Una vez que hayas configurado el canal de controlador custom
, estás listo para definir la clase que creará tu instancia de Monolog. Esta clase solo necesita un método __invoke
que debería devolver la instancia del registrador Monolog. El método recibirá como único argumento el array de configuración de canales:
<?php namespace App\Logging; use Monolog\Logger; class CreateCustomLogger{ /** * Crea una instancia personalizada de Monolog. */ public function __invoke(array $config): Logger { return new Logger(/* ... */); }}
A menudo, es posible que necesites seguir los registros de tu aplicación en tiempo real. Por ejemplo, al depurar un problema o al monitorear los registros de tu aplicación en busca de tipos específicos de errores.
Laravel Pail es un paquete que te permite sumergirte fácilmente en los archivos de registro de tu aplicación Laravel directamente desde la línea de comandos. A diferencia del comando estándar tail
, Pail está diseñado para funcionar con cualquier controlador de registro, incluidos Sentry o Flare. Además, Pail proporciona un conjunto de filtros útiles para ayudarte a encontrar rápidamente lo que estás buscando.
<img src="https://laravel-docs.com/images/docs/10.x/pail-example.png">
Advertencia Laravel Pail requiere PHP 8.2+ y la extensión PCNTL.
Para comenzar, instala Pail en tu proyecto utilizando el gestor de paquetes Composer:
composer require laravel/pail
Para comenzar a seguir los registros, ejecuta el comando pail
:
php artisan pail
Para aumentar la verbosidad de la salida y evitar la truncación (...), usa la opción -v
:
php artisan pail -v
Para obtener la máxima verbosidad y mostrar trazas de excepciones, usa la opción -vv
:
php artisan pail -vv
Para dejar de seguir los registros, presiona Ctrl+C
en cualquier momento.
--filter
Puedes usar la opción --filter
para filtrar los registros por su tipo, archivo, mensaje y contenido de la traza de la pila:
php artisan pail --filter="QueryException"
--message
Para filtrar los registros solo por su mensaje, puedes usar la opción --message
:
php artisan pail --message="User created"
--level
La opción --level
se puede utilizar para filtrar los registros por su nivel de registro:
php artisan pail --level=error
--user
Para mostrar solo los registros que se escribieron mientras un usuario específico estaba autenticado, puedes proporcionar el ID del usuario a la opción --user
:
php artisan pail --user=1