Laravel логирование ошибок

Логирование

  • Введение
  • Конфигурирование

    • Доступные драйверы канала
    • Предварительная подготовка канала
    • Логирование предупреждений об устаревании
  • Построение стека журналов
  • Запись сообщений журнала

    • Контекстная информация
    • Запись в определенные каналы
  • Настройка канала Monolog

    • Настройка Monolog для каналов
    • Создание обработчика каналов Monolog
    • Создание каналов через фабрики

Введение

Чтобы помочь вам узнать больше о том, что происходит в вашем приложении, Laravel предлагает надежные службы ведения журнала, которые позволяют записывать сообщения в файлы, журнал системных ошибок и даже в Slack, чтобы уведомить всю вашу команду.

Ведение журнала Laravel основано на «каналах». Каждый канал представляет собой определенный способ записи информации журнала. Например, канал single записывает файлы журнала в один файл журнала, а канал slack отправляет сообщения журнала в Slack. Сообщения журнала могут быть записаны в несколько каналов в зависимости от их серьезности.

Под капотом Laravel использует библиотеку Monolog, которая обеспечивает поддержку множества мощных обработчиков журналов. Laravel упрощает настройку этих обработчиков, позволяя вам смешивать и сопоставлять их для настройки обработки журналов вашего приложения.

Конфигурирование

Все параметры конфигурации для ведения журнала вашего приложения размещены в файле конфигурации config/logging.php. Этот файл позволяет вам настраивать каналы журнала вашего приложения, поэтому обязательно просмотрите каждый из доступных каналов и их параметры. Ниже мы рассмотрим несколько распространенных вариантов.

По умолчанию Laravel будет использовать канал stack при регистрации сообщений. Канал stack используется для объединения нескольких каналов журнала в один канал. Для получения дополнительной информации о построении стеков ознакомьтесь с документацией ниже.

Настройка имени канала

По умолчанию экземпляр Monolog создается с «именем канала», которое соответствует текущей среде, например, production или local. Чтобы изменить это значение, добавьте параметр name в конфигурацию вашего канала:

'stack' => [
    'driver' => 'stack',
    'name' => 'channel-name',
    'channels' => ['single', 'slack'],
],

Доступные драйверы канала

Каждый канал журнала работает через «драйвер». Драйвер определяет, как и где фактически записывается сообщение журнала. Следующие драйверы канала журнала доступны в каждом приложении Laravel. Запись для большинства этих драйверов уже присутствует в файле конфигурации вашего приложения config/logging.php, поэтому обязательно просмотрите этот файл, чтобы ознакомиться с его содержимым:

Имя Описание
custom Драйвер, который вызывает указанную фабрику для создания канала.
daily Драйвер Monolog на основе RotatingFileHandler с ежедневной ротацией.
errorlog Драйвер Monolog на основе ErrorLogHandler.
monolog Драйвер фабрики Monolog, использующий любой поддерживаемый Monolog обработчик.
null Драйвер, который игнорирует все сообщения.
papertrail Драйвер Monolog на основе SyslogUdpHandler.
single Канал на основе одного файла или пути (StreamHandler)
slack Драйвер Monolog на основе SlackWebhookHandler.
stack Обертка для облегчения создания «многоканальных» каналов.
syslog Драйвер Monolog на основе SyslogHandler.

Изучите документацию по расширенной настройке канала, чтобы узнать больше о драйверах monolog и custom.

Предварительная подготовка канала

Конфигурирование каналов Single и Daily

Каналы single и daily имеют три необязательных параметра конфигурации: bubble, permission, и locking.

Имя Описание По умолчанию
bubble Должны ли сообщения переходить в другие каналы после обработки true
locking Попытаться заблокировать файл журнала перед записью в него false
permission Права доступа на файл журнала 0644

Конфигурирование канала Papertrail

Для канала papertrail требуются параметры конфигурации host и port. Эти значения можно получить из Papertrail.

Конфигурирование канала Slack

Для канала slack требуется параметр конфигурации url. Этот URL-адрес должен соответствовать URL-адресу входящего веб-хука, который вы настроили для своей команды Slack.

По умолчанию Slack будет получать логи только с уровнем critical и выше; однако вы можете настроить это в своем файле конфигурации config/logging.php, изменив параметр конфигурации level в массиве вашего драйвера Slack.

Логирование предупреждений об устаревании

PHP, Laravel и другие библиотеки часто уведомляют своих пользователей о том, что некоторые из их функций устарели и будут удалены в будущей версии. Если вы хотите регистрировать эти предупреждения об устаревании, вы можете указать предпочитаемый канал журнала deprecations в файле конфигурации вашего приложения config/logging.php:

'deprecations' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),

'channels' => [
    ...
]

Или вы можете определить канал журнала с именем deprecations. Если канал журнала с таким именем существует, он всегда будет использоваться для регистрации устаревания:

'channels' => [
    'deprecations' => [
        'driver' => 'single',
        'path' => storage_path('logs/php-deprecation-warnings.log'),
    ],
],

Построение стека журналов

Как упоминалось ранее, драйвер stack позволяет для удобства объединить несколько каналов в один канал журнала. Чтобы проиллюстрировать, как использовать стеки журналов, давайте рассмотрим пример конфигурации, которую вы можете увидеть в эксплуатационном приложении:

'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',
    ],
],

Давайте разберем эту конфигурацию. Во-первых, обратите внимание, что наш канал stack объединяет два других канала с помощью параметра channels: syslog и slack. Таким образом, при регистрации сообщений оба канала будут иметь возможность регистрировать сообщение. Однако, как мы увидим ниже, действительно ли эти каналы регистрируют сообщение, может быть определено серьезностью / «уровнем» сообщения.

Уровни журнала

Обратите внимание на параметр конфигурации level, присутствующий в конфигурациях каналов syslog и slack в приведенном выше примере. Эта опция определяет минимальный «уровень» сообщения, которое должно быть зарегистрировано каналом. Monolog, на котором работают службы ведения журналов Laravel, предлагает все уровни журналов, определенные в спецификации RFC 5424 specification: emergency, alert, critical, error, warning, notice, info, и debug.

Итак, представьте, что мы регистрируем сообщение, используя метод debug:

Log::debug('An informational message.');

Учитывая нашу конфигурацию, канал syslog будет записывать сообщение в системный журнал; однако, поскольку сообщение об ошибке не является уровнем critical или выше, то оно не будет отправлено в Slack. Однако, если мы регистрируем сообщение уровня emergency, то оно будет отправлено как в системный журнал, так и в Slack, поскольку уровень emergency выше нашего минимального порогового значения для обоих каналов:

Log::emergency('The system is down!');

Запись сообщений журнала

Вы можете записывать информацию в журналы с помощью фасада Log. Как упоминалось ранее, средство ведения журнала обеспечивает восемь уровней ведения журнала, определенных в спецификации RFC 5424 specification: emergency, alert, critical, error, warning, notice, info, и debug.

use IlluminateSupportFacadesLog;

Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);

Вы можете вызвать любой из этих методов, чтобы записать сообщение для соответствующего уровня. По умолчанию сообщение будет записано в канал журнала по умолчанию, как настроено вашим файлом конфигурации logging:

<?php

namespace AppHttpControllers;

use AppHttpControllersController;
use AppModelsUser;
use IlluminateSupportFacadesLog;

class UserController extends Controller
{
    /**
     * Показать профиль конкретного пользователя.
     *
     * @param  int  $id
     * @return IlluminateHttpResponse
     */
    public function show($id)
    {
        Log::info('Showing the user profile for user: '.$id);

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

Контекстная информация

Методам журнала может быть передан массив контекстных данных. Эти контекстные данные будут отформатированы и отображены в сообщении журнала:

use IlluminateSupportFacadesLog;

Log::info('User failed to login.', ['id' => $user->id]);

Иногда вы можете указать некоторую контекстную информацию, которая должна быть включена во все последующие записи журнала. Например, вы можете захотеть зарегистрировать идентификатор запроса, связанный с каждым входящим запросом к вашему приложению. Для этого вы можете вызвать метод withContext фасада Log:

<?php

namespace AppHttpMiddleware;

use Closure;
use IlluminateSupportFacadesLog;
use IlluminateSupportStr;

class AssignRequestId
{
    /**
     * Обработчик входящего запроса .
     *
     * @param  IlluminateHttpRequest  $request
     * @param  Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $requestId = (string) Str::uuid();

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

        return $next($request)->header('Request-Id', $requestId);
    }
}

Запись в определенные каналы

По желанию можно записать сообщение в канал, отличный от канала по умолчанию вашего приложения. Вы можете использовать метод channel фасада Log для получения и регистрации любого канала, определенного в вашем файле конфигурации:

use IlluminateSupportFacadesLog;

Log::channel('slack')->info('Something happened!');

Если вы хотите создать стек протоколирования по запросу, состоящий из нескольких каналов, вы можете использовать метод stack:

Log::stack(['single', 'slack'])->info('Something happened!');

Каналы по запросу

Также возможно создать канал по запросу, предоставив конфигурацию во время выполнения, без того, чтобы эта конфигурация присутствовала в файле logging вашего приложения. Для этого вы можете передать массив конфигурации методу build фасада Log:

use IlluminateSupportFacadesLog;

Log::build([
  'driver' => 'single',
  'path' => storage_path('logs/custom.log'),
])->info('Something happened!');

Вы также можете включить канал по запросу в стек журналов по запросу. Этого можно добиться, включив экземпляр вашего канала по запросу в массив, переданный в метод stack:

use IlluminateSupportFacadesLog;

$channel = Log::build([
  'driver' => 'single',
  'path' => storage_path('logs/custom.log'),
]);

Log::stack(['slack', $channel])->info('Something happened!');

Настройка канала Monolog

Настройка Monolog для каналов

Иногда требуется полный контроль над настройкой Monolog для существующего канала. Например, бывает необходимо настроить собственную реализацию Monolog FormatterInterface для встроенного в Laravel канала single.

Для начала определите массив tap в конфигурации канала. Массив tap должен содержать список классов, которые должны иметь возможность настраивать (или «касаться») экземпляр Monolog после его создания. Не существует обычного места для размещения этих классов, поэтому вы можете создать каталог в своем приложении, чтобы разместить эти классы:

'single' => [
    'driver' => 'single',
    'tap' => [AppLoggingCustomizeFormatter::class],
    'path' => storage_path('logs/laravel.log'),
    'level' => 'debug',
],

После того как вы настроили опцию tap своего канала, вы готовы определить класс, который будет контролировать ваш экземпляр Monolog. Этому классу нужен только один метод: __invoke, который получает экземпляр IlluminateLogLogger. Экземпляр IlluminateLogLogger передает все вызовы методов базовому экземпляру Monolog:

<?php

namespace AppLogging;

use MonologFormatterLineFormatter;

class CustomizeFormatter
{
    /**
     * Настроить переданный экземпляр регистратора.
     *
     * @param  IlluminateLogLogger  $logger
     * @return void
     */
    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            $handler->setFormatter(new LineFormatter(
                '[%datetime%] %channel%.%level_name%: %message% %context% %extra%'
            ));
        }
    }
}

Все ваши классы «tap» извлекаются через контейнер служб, поэтому любые зависимости конструктора, которые им требуются, будут автоматически внедрены.

Создание обработчика каналов Monolog

В Monolog есть множество доступных обработчиков, а в Laravel из коробки не включены каналы для каждого из них. В некоторых случаях вам может потребоваться создать собственный канал, являющийся просто экземпляром определенного обработчика Monolog, у которого нет соответствующего драйвера журнала Laravel. Эти каналы могут быть легко созданы с помощью драйвера monolog.

При использовании драйвера monolog параметр конфигурации handler используется для указания того, какой обработчик будет создан. При желании любые параметры конструктора, необходимые обработчику, могут быть указаны с помощью опции конфигурации with:

'logentries' => [
    'driver'  => 'monolog',
    'handler' => MonologHandlerSyslogUdpHandler::class,
    'with' => [
        'host' => 'my.logentries.internal.datahubhost.company.com',
        'port' => '10000',
    ],
],

Форматтеры Monolog

При использовании драйвера monolog, Monolog-класс LineFormatter будет использоваться как средство форматирования по умолчанию. Однако вы можете настроить тип средства форматирования, передаваемого обработчику, используя параметры конфигурации formatter и formatter_with:

'browser' => [
    'driver' => 'monolog',
    'handler' => MonologHandlerBrowserConsoleHandler::class,
    'formatter' => MonologFormatterHtmlFormatter::class,
    'formatter_with' => [
        'dateFormat' => 'Y-m-d',
    ],
],

Если вы используете обработчик Monolog, который может предоставлять свой собственный модуль форматирования, вы можете установить для параметра конфигурации formatter значение default:

'newrelic' => [
    'driver' => 'monolog',
    'handler' => MonologHandlerNewRelicHandler::class,
    'formatter' => 'default',
],

Создание каналов через фабрики

Если вы хотите определить полностью настраиваемый канал, в котором у вас есть полный контроль над созданием и конфигурацией Monolog, вы можете указать тип драйвера custom в файле конфигурации config/logging.php. Ваша конфигурация должна включать параметр via, содержащий имя класса фабрики, которая будет вызываться для создания экземпляра Monolog:

'channels' => [
    'example-custom-channel' => [
        'driver' => 'custom',
        'via' => AppLoggingCreateCustomLogger::class,
    ],
],

После того как вы настроили канал драйвера custom, вы готовы определить класс, который будет создавать ваш экземпляр Monolog. Этому классу нужен только один метод __invoke, который должен возвращать экземпляр регистратора Monolog. Метод получит массив конфигурации каналов в качестве единственного аргумента:

<?php

namespace AppLogging;

use MonologLogger;

class CreateCustomLogger
{
    /**
     * Создать экземпляр собственного регистратора Monolog.
     *
     * @param  array  $config
     * @return MonologLogger
     */
    public function __invoke(array $config)
    {
        return new Logger(...);
    }
}

Version


Logging

  • Introduction
  • Configuration

    • Available Channel Drivers
    • Channel Prerequisites
    • Logging Deprecation Warnings
  • Building Log Stacks
  • Writing Log Messages

    • Contextual Information
    • Writing To Specific Channels
  • Monolog Channel Customization

    • Customizing Monolog For Channels
    • Creating Monolog Handler Channels
    • Creating Custom Channels Via Factories

Introduction

To help you learn more about what’s happening within your application, Laravel provides robust logging services that allow you to log messages to files, the system error log, and even to Slack to notify your entire team.

Laravel logging is based on «channels». Each channel represents a specific way of writing log information. For example, the single channel writes log files to a single log file, while the slack channel sends log messages to Slack. Log messages may be written to multiple channels based on their severity.

Under the hood, Laravel utilizes the Monolog library, which provides support for a variety of powerful log handlers. Laravel makes it a cinch to configure these handlers, allowing you to mix and match them to customize your application’s log handling.

Configuration

All of the configuration options for your application’s logging behavior are housed in the config/logging.php configuration file. This file allows you to configure your application’s log channels, so be sure to review each of the available channels and their options. We’ll review a few common options below.

By default, Laravel will use the stack channel when logging messages. The stack channel is used to aggregate multiple log channels into a single channel. For more information on building stacks, check out the documentation below.

Configuring The Channel Name

By default, Monolog is instantiated with a «channel name» that matches the current environment, such as production or local. To change this value, add a name option to your channel’s configuration:

'stack' => [

'driver' => 'stack',

'name' => 'channel-name',

'channels' => ['single', 'slack'],

],

Available Channel Drivers

Each log channel is powered by a «driver». The driver determines how and where the log message is actually recorded. The following log channel drivers are available in every Laravel application. An entry for most of these drivers is already present in your application’s config/logging.php configuration file, so be sure to review this file to become familiar with its contents:

Name Description
custom A driver that calls a specified factory to create a channel
daily A RotatingFileHandler based Monolog driver which rotates daily
errorlog An ErrorLogHandler based Monolog driver
monolog A Monolog factory driver that may use any supported Monolog handler
null A driver that discards all log messages
papertrail A SyslogUdpHandler based Monolog driver
single A single file or path based logger channel (StreamHandler)
slack A SlackWebhookHandler based Monolog driver
stack A wrapper to facilitate creating «multi-channel» channels
syslog A SyslogHandler based Monolog driver

Note
Check out the documentation on advanced channel customization to learn more about the monolog and custom drivers.

Channel Prerequisites

Configuring The Single and Daily Channels

The single and daily channels have three optional configuration options: bubble, permission, and locking.

Name Description Default
bubble Indicates if messages should bubble up to other channels after being handled true
locking Attempt to lock the log file before writing to it false
permission The log file’s permissions 0644

Additionally, the retention policy for the daily channel can be configured via the days option:

Name Description Default
days The number of days that daily log files should be retained 7

Configuring The Papertrail Channel

The papertrail channel requires the host and port configuration options. You can obtain these values from Papertrail.

Configuring The Slack Channel

The slack channel requires a url configuration option. This URL should match a URL for an incoming webhook that you have configured for your Slack team.

By default, Slack will only receive logs at the critical level and above; however, you can adjust this in your config/logging.php configuration file by modifying the level configuration option within your Slack log channel’s configuration array.

Logging Deprecation Warnings

PHP, Laravel, and other libraries often notify their users that some of their features have been deprecated and will be removed in a future version. If you would like to log these deprecation warnings, you may specify your preferred deprecations log channel in your application’s config/logging.php configuration file:

'deprecations' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),

'channels' => [

...

]

Or, you may define a log channel named deprecations. If a log channel with this name exists, it will always be used to log deprecations:

'channels' => [

'deprecations' => [

'driver' => 'single',

'path' => storage_path('logs/php-deprecation-warnings.log'),

],

],

Building Log Stacks

As mentioned previously, the stack driver allows you to combine multiple channels into a single log channel for convenience. To illustrate how to use log stacks, let’s take a look at an example configuration that you might see in a production application:

'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',

],

],

Let’s dissect this configuration. First, notice our stack channel aggregates two other channels via its channels option: syslog and slack. So, when logging messages, both of these channels will have the opportunity to log the message. However, as we will see below, whether these channels actually log the message may be determined by the message’s severity / «level».

Log Levels

Take note of the level configuration option present on the syslog and slack channel configurations in the example above. This option determines the minimum «level» a message must be in order to be logged by the channel. Monolog, which powers Laravel’s logging services, offers all of the log levels defined in the RFC 5424 specification. In descending order of severity, these log levels are: emergency, alert, critical, error, warning, notice, info, and debug.

So, imagine we log a message using the debug method:

Log::debug('An informational message.');

Given our configuration, the syslog channel will write the message to the system log; however, since the error message is not critical or above, it will not be sent to Slack. However, if we log an emergency message, it will be sent to both the system log and Slack since the emergency level is above our minimum level threshold for both channels:

Log::emergency('The system is down!');

Writing Log Messages

You may write information to the logs using the Log facade. As previously mentioned, the logger provides the eight logging levels defined in the RFC 5424 specification: emergency, alert, critical, error, warning, notice, info and debug:

use IlluminateSupportFacadesLog;

Log::emergency($message);

Log::alert($message);

Log::critical($message);

Log::error($message);

Log::warning($message);

Log::notice($message);

Log::info($message);

Log::debug($message);

You may call any of these methods to log a message for the corresponding level. By default, the message will be written to the default log channel as configured by your logging configuration file:

<?php

namespace AppHttpControllers;

use AppHttpControllersController;

use AppModelsUser;

use IlluminateSupportFacadesLog;

use IlluminateViewView;

class UserController extends Controller

{

/**

* Show the profile for the given user.

*/

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)

]);

}

}

Contextual Information

An array of contextual data may be passed to the log methods. This contextual data will be formatted and displayed with the log message:

use IlluminateSupportFacadesLog;

Log::info('User {id} failed to login.', ['id' => $user->id]);

Occasionally, you may wish to specify some contextual information that should be included with all subsequent log entries in a particular channel. For example, you may wish to log a request ID that is associated with each incoming request to your application. To accomplish this, you may call the Log facade’s withContext method:

<?php

namespace AppHttpMiddleware;

use Closure;

use IlluminateHttpRequest;

use IlluminateSupportFacadesLog;

use IlluminateSupportStr;

use SymfonyComponentHttpFoundationResponse;

class AssignRequestId

{

/**

* Handle an incoming request.

*

* @param Closure(IlluminateHttpRequest): (SymfonyComponentHttpFoundationResponse) $next

*/

public function handle(Request $request, Closure $next): Response

{

$requestId = (string) Str::uuid();

Log::withContext([

'request-id' => $requestId

]);

return $next($request)->header('Request-Id', $requestId);

}

}

If you would like to share contextual information across all logging channels, you may call the Log::shareContext() method. This method will provide the contextual information to all created channels and any channels that are created subsequently. Typically, the shareContext method should be called from the boot method of an application service provider:

use IlluminateSupportFacadesLog;

use IlluminateSupportStr;

class AppServiceProvider

{

/**

* Bootstrap any application services.

*/

public function boot(): void

{

Log::shareContext([

'invocation-id' => (string) Str::uuid(),

]);

}

}

Writing To Specific Channels

Sometimes you may wish to log a message to a channel other than your application’s default channel. You may use the channel method on the Log facade to retrieve and log to any channel defined in your configuration file:

use IlluminateSupportFacadesLog;

Log::channel('slack')->info('Something happened!');

If you would like to create an on-demand logging stack consisting of multiple channels, you may use the stack method:

Log::stack(['single', 'slack'])->info('Something happened!');

On-Demand Channels

It is also possible to create an on-demand channel by providing the configuration at runtime without that configuration being present in your application’s logging configuration file. To accomplish this, you may pass a configuration array to the Log facade’s build method:

use IlluminateSupportFacadesLog;

Log::build([

'driver' => 'single',

'path' => storage_path('logs/custom.log'),

])->info('Something happened!');

You may also wish to include an on-demand channel in an on-demand logging stack. This can be achieved by including your on-demand channel instance in the array passed to the stack method:

use IlluminateSupportFacadesLog;

$channel = Log::build([

'driver' => 'single',

'path' => storage_path('logs/custom.log'),

]);

Log::stack(['slack', $channel])->info('Something happened!');

Monolog Channel Customization

Customizing Monolog For Channels

Sometimes you may need complete control over how Monolog is configured for an existing channel. For example, you may want to configure a custom Monolog FormatterInterface implementation for Laravel’s built-in single channel.

To get started, define a tap array on the channel’s configuration. The tap array should contain a list of classes that should have an opportunity to customize (or «tap» into) the Monolog instance after it is created. There is no conventional location where these classes should be placed, so you are free to create a directory within your application to contain these classes:

'single' => [

'driver' => 'single',

'tap' => [AppLoggingCustomizeFormatter::class],

'path' => storage_path('logs/laravel.log'),

'level' => 'debug',

],

Once you have configured the tap option on your channel, you’re ready to define the class that will customize your Monolog instance. This class only needs a single method: __invoke, which receives an IlluminateLogLogger instance. The IlluminateLogLogger instance proxies all method calls to the underlying Monolog instance:

<?php

namespace AppLogging;

use IlluminateLogLogger;

use MonologFormatterLineFormatter;

class CustomizeFormatter

{

/**

* Customize the given logger instance.

*/

public function __invoke(Logger $logger): void

{

foreach ($logger->getHandlers() as $handler) {

$handler->setFormatter(new LineFormatter(

'[%datetime%] %channel%.%level_name%: %message% %context% %extra%'

));

}

}

}

Note
All of your «tap» classes are resolved by the service container, so any constructor dependencies they require will automatically be injected.

Creating Monolog Handler Channels

Monolog has a variety of available handlers and Laravel does not include a built-in channel for each one. In some cases, you may wish to create a custom channel that is merely an instance of a specific Monolog handler that does not have a corresponding Laravel log driver. These channels can be easily created using the monolog driver.

When using the monolog driver, the handler configuration option is used to specify which handler will be instantiated. Optionally, any constructor parameters the handler needs may be specified using the with configuration option:

'logentries' => [

'driver' => 'monolog',

'handler' => MonologHandlerSyslogUdpHandler::class,

'with' => [

'host' => 'my.logentries.internal.datahubhost.company.com',

'port' => '10000',

],

],

Monolog Formatters

When using the monolog driver, the Monolog LineFormatter will be used as the default formatter. However, you may customize the type of formatter passed to the handler using the formatter and formatter_with configuration options:

'browser' => [

'driver' => 'monolog',

'handler' => MonologHandlerBrowserConsoleHandler::class,

'formatter' => MonologFormatterHtmlFormatter::class,

'formatter_with' => [

'dateFormat' => 'Y-m-d',

],

],

If you are using a Monolog handler that is capable of providing its own formatter, you may set the value of the formatter configuration option to default:

'newrelic' => [

'driver' => 'monolog',

'handler' => MonologHandlerNewRelicHandler::class,

'formatter' => 'default',

],

Monolog Processors

Monolog can also process messages before logging them. You can create your own processors or use the existing processors offered by Monolog.

If you would like to customize the processors for a monolog driver, add a processors configuration value to your channel’s configuration:

'memory' => [

'driver' => 'monolog',

'handler' => MonologHandlerStreamHandler::class,

'with' => [

'stream' => 'php://stderr',

],

'processors' => [

// Simple syntax...

MonologProcessorMemoryUsageProcessor::class,

// With options...

[

'processor' => MonologProcessorPsrLogMessageProcessor::class,

'with' => ['removeUsedContextFields' => true],

],

],

],

Creating Custom Channels Via Factories

If you would like to define an entirely custom channel in which you have full control over Monolog’s instantiation and configuration, you may specify a custom driver type in your config/logging.php configuration file. Your configuration should include a via option that contains the name of the factory class which will be invoked to create the Monolog instance:

'channels' => [

'example-custom-channel' => [

'driver' => 'custom',

'via' => AppLoggingCreateCustomLogger::class,

],

],

Once you have configured the custom driver channel, you’re ready to define the class that will create your Monolog instance. This class only needs a single __invoke method which should return the Monolog logger instance. The method will receive the channels configuration array as its only argument:

<?php

namespace AppLogging;

use MonologLogger;

class CreateCustomLogger

{

/**

* Create a custom Monolog instance.

*/

public function __invoke(array $config): Logger

{

return new Logger(/* ... */);

}

}

  1. 1. Введение
  2. 2. Настройка

    1. 2.1. Детализация ошибок
    2. 2.2. Хранилище журналов
    3. 2.3. Уровни важности событий
  3. 3. Обработчик исключений

    1. 3.1. Метод PHPreport()
    2. 3.2. Метод PHPrender()
  4. 4. HTTP-исключения

    1. 4.1. Свои страницы HTTP-ошибок
  5. 5. Журналы

Введение

Когда вы начинаете новый Laravel проект, обработка ошибок и исключений уже настроена для вас. Все происходящие в вашем приложении исключения записываются в журнал и отображаются пользователю в классе AppExceptionsHandler. В этой статье мы подробно рассмотрим этот класс.

Для журналирования Laravel использует библиотеку Monolog, которая обеспечивает поддержку различных мощных обработчиков журналов. В Laravel настроены несколько из них, благодаря чему вы можете выбрать между единым файлом журнала, ротируемыми файлами журналов и записью информации в системный журнал.

Настройка

Детализация ошибок

Параметр confdebug в файле настроек config/app.php определяет, сколько информации об ошибке показывать пользователю. По умолчанию этот параметр установлен в соответствии со значением переменной среды APP_DEBUG, которая хранится в файле .env.

Для локальной разработки вам следует установить переменную среды APP_DEBUG в значение true. В продакшн-среде эта переменная всегда должна иметь значение false. Если значение равно true на продакшн-сервере, вы рискуете раскрыть важные значения настроек вашим конечным пользователям.

Хранилище журналов

Изначально Laravel поддерживает запись журналов в единый файл (single), в отдельные файлы за каждый день (daily), в syslog и errorlog. Для использования определённого механизма хранения вам надо изменить параметр conflog в файле config/app.php. Например, если вы хотите использовать ежедневные файлы журнала вместо единого файла, вам надо установить значение log равное daily в файле настроек app:


+
5.3 5.2

добавлено в

5.3

(28.01.2017)

5.2

(08.12.2016)

Максимальное число ежедневных файлов журнала

При использовании режима daily Laravel по умолчанию хранит журналы только за последние 5 дней. Если вы хотите изменить число хранимых файлов, добавьте в файл app значение для параметра log_max_files:


+
5.3 5.2

добавлено в

5.3

(28.01.2017)

5.2

(08.12.2016)

Уровни важности событий

При использовании Monolog сообщения в журнале могут иметь разные уровни важности. По умолчанию Laravel сохраняет в журнал события всех уровней. Но на продакшн-сервере вы можете задать минимальный уровень важности, который необходимо заносить в журнал, добавив параметр conflog_level в файл app.php.

После задания этого параметра Laravel будет записывать события всех уровней начиная с указанного и выше. Например, при conflog_level равном error будут записываться события error, critical, alert и emergency:

conf'log_level' => env('APP_LOG_LEVEL', 'error'),

В Monolog используются следующие уровни важности — от меньшего к большему: debug, info, notice, warning, error, critical, alert, emergency.

Изменение настроек Monolog

Если вы хотите иметь полный контроль над конфигурацией Monolog для вашего приложения, вы можете использовать метод приложения PHPconfigureMonologUsing(). Вызов этого метода необходимо поместить в файл bootstrap/app.php прямо перед тем, как в нём возвращается переменная PHP$app:

PHP

$app->configureMonologUsing(function ($monolog) {
  
$monolog->pushHandler(...);
});

return 

$app;

Обработчик исключений

Метод PHPreport()

Все исключения обрабатываются классом AppExceptionsHandler. Этот класс содержит два метода: PHPreport() и PHPrender(). Рассмотрим каждый из них подробнее. Метод PHPreport() используется для занесения исключений в журнал или для отправки их во внешний сервис, такой как BugSnag или Sentry. По умолчанию метод PHPreport() просто передаёт исключение в базовую реализацию родительского класса, где это исключение зафиксировано. Но вы можете регистрировать исключения как пожелаете.

Например, если вам необходимо сообщать о различных типах исключений разными способами, вы можете использовать оператор сравнения PHP PHPinstanceof::

PHP

/**
 * Сообщить или зарегистрировать исключение.
 *
 * Это отличное место для отправки исключений в Sentry, Bugsnag, и т.д.
 *
 * @param  Exception  $exception
 * @return void
 */
public function report(Exception $exception)
{
  if (
$exception instanceof CustomException) {
    
//
  
}

  return 

parent::report($exception);
}

Игнорирование исключений заданного типа

Свойство обработчика исключений PHP$dontReport содержит массив с типами исключений, которые не будут заноситься в журнал. Например, исключения, возникающие при ошибке 404, а также при некоторых других типах ошибок, не записываются в журналы. При необходимости вы можете включить другие типы исключений в этот массив:

PHP

/**
 * Список типов исключений, о которых не надо сообщать.
 *
 * @var array
 */
protected $dontReport = [
  
IlluminateAuthAuthenticationException::class,
  
IlluminateAuthAccessAuthorizationException::class,
  
SymfonyComponentHttpKernelExceptionHttpException::class,
  
IlluminateDatabaseEloquentModelNotFoundException::class,
  
IlluminateValidationValidationException::class,
];

Метод PHPrender()

Метод PHPrender() отвечает за конвертацию исключения в HTTP-отклик, который должен быть возвращён браузеру. По умолчанию исключение передаётся в базовый класс, который генерирует для вас отклик. Но вы можете проверить тип исключения или вернуть ваш собственный отклик:

PHP

/**
 * Отрисовка HTTP-оклика для исключения.
 *
 * @param  IlluminateHttpRequest  $request
 * @param  Exception  $exception
 * @return IlluminateHttpResponse
 */
public function render($requestException $exception)
{
  if (
$exception instanceof CustomException) {
    return 
response()->view('errors.custom', [], 500);
  }

  return 

parent::render($request$exception);
}

HTTP-исключения

Некоторые исключения описывают коды HTTP-ошибок от сервера. Например, это может быть ошибка «страница не найдена» (404), «ошибка авторизации» (401) или даже сгенерированная разработчиком ошибка 500. Для возврата такого отклика из любого места в приложении можете использовать вспомогательный метод PHPabort():

Вспомогательный метод PHPabort() немедленно создаёт исключение, которое будет отрисовано обработчиком исключений. Или вы можете предоставить такой отклик:

PHP

abort(403'Unauthorized action.');

Свои страницы HTTP-ошибок

В Laravel можно легко возвращать свои собственные страницы для различных кодов HTTP-ошибок. Например, для выдачи собственной страницы для ошибки 404 создайте файл resources/views/errors/404.blade.php. Этот файл будет использован для всех ошибок 404, генерируемых вашим приложением. Представления в этой папке должны иметь имена, соответствующие кодам ошибок. Экземпляр HttpException, созданный функцией PHPabort(), будет передан в представление как переменная PHP$exception.

Журналы

Laravel обеспечивает простой простой уровень абстракции над мощной библиотекой Monolog. По умолчанию Laravel настроен на создание файла журнала в storage/logs. Вы можете записывать информацию в журнал при помощи фасада Log:

PHP

<?phpnamespace AppHttpControllers;

use 

IlluminateSupportFacadesLog;
//для версии 5.2 и ранее:
//use Log;
use AppUser;
use 
AppHttpControllersController;

class 

UserController extends Controller
{
  
/**
   * Показать профиль данного пользователя.
   *
   * @param  int  $id
   * @return Response
   */
  
public function showProfile($id)
  {
    
Log::info('Showing user profile for user: '.$id);

    return 

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

Регистратор событий предоставляет восемь уровней журналирования, описанных в RFC 5424: debug, info, notice, warning, error, critical, alert и emergency.

PHP

Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);

Контекстная информация

Также в методы журналирования может быть передан массив контекстных данных:

PHP

Log::info('User failed to login.', ['id' => $user->id]);

Обращение к низкоуровневому экземпляру Monolog

В Monolog доступно множество дополнительных обработчиков для журналов. При необходимости вы можете получить доступ к низкоуровневому экземпляру Monolog, используемому в Laravel:

PHP

$monolog Log::getMonolog();


+
5.0

добавлено в

5.0

(08.02.2016)

Вы также можете зарегистрировать событие для перехвата всех сообщений, передаваемых в журнал.

Регистрация слушателя событий журнала

PHP

Log::listen(function($level$message$context)
{
  
//
});

Laravel 9 · Логирование

  • Введение
  • Конфигурирование
    • Доступные драйверы канала
    • Предварительная подготовка канала
    • Логирование предупреждений об устаревании
  • Построение стека журналов
  • Запись сообщений журнала
    • Контекстная информация
    • Запись в определенные каналы
  • Настройка канала Monolog
    • Настройка Monolog для каналов
    • Создание обработчика каналов Monolog
    • Создание каналов через фабрики

Введение

Чтобы помочь вам узнать больше о том, что происходит в вашем приложении, Laravel предлагает надежные службы ведения журнала, которые позволяют записывать сообщения в файлы, журнал системных ошибок и даже в Slack, чтобы уведомить всю вашу команду.

Ведение журнала Laravel основано на «каналах». Каждый канал представляет собой определенный способ записи информации журнала. Например, канал single записывает файлы журнала в один файл журнала, а канал slack отправляет сообщения журнала в Slack. Сообщения журнала могут быть записаны в несколько каналов в зависимости от их серьезности.

Под капотом Laravel использует библиотеку Monolog, которая обеспечивает поддержку множества мощных обработчиков журналов. Laravel упрощает настройку этих обработчиков, позволяя вам смешивать и сопоставлять их для настройки обработки журналов вашего приложения.

Конфигурирование

Все параметры конфигурации для ведения журнала вашего приложения размещены в файле конфигурации config/logging.php. Этот файл позволяет вам настраивать каналы журнала вашего приложения, поэтому обязательно просмотрите каждый из доступных каналов и их параметры. Ниже мы рассмотрим несколько распространенных вариантов.

По умолчанию Laravel будет использовать канал stack при регистрации сообщений. Канал stack используется для объединения нескольких каналов журнала в один канал. Для получения дополнительной информации о построении стеков ознакомьтесь с документацией ниже.

Настройка имени канала

По умолчанию экземпляр Monolog создается с «именем канала», которое соответствует текущей среде, например, production или local. Чтобы изменить это значение, добавьте параметр name в конфигурацию вашего канала:

'stack' => [
    'driver' => 'stack',
    'name' => 'channel-name',
    'channels' => ['single', 'slack'],
],

Доступные драйверы канала

Каждый канал журнала работает через «драйвер». Драйвер определяет, как и где фактически записывается сообщение журнала. Следующие драйверы канала журнала доступны в каждом приложении Laravel. Запись для большинства этих драйверов уже присутствует в файле конфигурации вашего приложения config/logging.php, поэтому обязательно просмотрите этот файл, чтобы ознакомиться с его содержимым:

Имя Описание
custom Драйвер, который вызывает указанную фабрику для создания канала.
daily Драйвер Monolog на основе RotatingFileHandler с ежедневной ротацией.
errorlog Драйвер Monolog на основе ErrorLogHandler.
monolog Драйвер фабрики Monolog, использующий любой поддерживаемый Monolog обработчик.
null Драйвер, который игнорирует все сообщения.
papertrail Драйвер Monolog на основе SyslogUdpHandler.
single Канал на основе одного файла или пути (StreamHandler)
slack Драйвер Monolog на основе SlackWebhookHandler.
stack Обертка для облегчения создания «многоканальных» каналов.
syslog Драйвер Monolog на основе SyslogHandler.

Примечание
Изучите документацию по расширенной настройке канала, чтобы узнать больше о драйверах monolog и custom.

Предварительная подготовка канала

Конфигурирование каналов Single и Daily

Каналы single и daily имеют три необязательных параметра конфигурации: bubble, permission и locking.

Имя Описание По умолчанию
bubble Должны ли сообщения переходить в другие каналы после обработки true
locking Попытаться заблокировать файл журнала перед записью в него false
permission Права доступа на файл журнала 0644

Кроме того, политику хранения для канала daily можно настроить с помощью параметра days:

Имя Описание По умолчанию
days Количество дней, в течение которых файлы ежедневного журнала должны храниться 7

Конфигурирование канала Papertrail

Для канала papertrail требуются параметры конфигурации host и port. Эти значения можно получить из Papertrail.

Конфигурирование канала Slack

Для канала slack требуется параметр конфигурации url. Этот URL-адрес должен соответствовать URL-адресу входящего веб-хука, который вы настроили для своей команды Slack.

По умолчанию Slack будет получать логи только с уровнем critical и выше; однако вы можете настроить это в своем файле конфигурации config/logging.php, изменив параметр конфигурации level в массиве вашего драйвера Slack.

Логирование предупреждений об устаревании

PHP, Laravel и другие библиотеки часто уведомляют своих пользователей о том, что некоторые из их функций устарели и будут удалены в будущей версии. Если вы хотите регистрировать эти предупреждения об устаревании, вы можете указать предпочитаемый канал журнала deprecations в конфигурационном файле config/logging.php вашего приложения:

'deprecations' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),

'channels' => [
    ...
]

Или вы можете определить канал журнала с именем deprecations. Если канал журнала с таким именем существует, то он всегда будет использоваться для регистрации устаревания:

'channels' => [
    'deprecations' => [
        'driver' => 'single',
        'path' => storage_path('logs/php-deprecation-warnings.log'),
    ],
],

Построение стека журналов

Как упоминалось ранее, драйвер stack позволяет для удобства объединить несколько каналов в один канал журнала. Чтобы проиллюстрировать, как использовать стеки журналов, давайте рассмотрим пример конфигурации, которую вы можете увидеть в эксплуатационном приложении:

'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',
    ],
],

Давайте разберем эту конфигурацию. Во-первых, обратите внимание, что наш канал stack объединяет два других канала с помощью параметра channels: syslog и slack. Таким образом, при регистрации сообщений оба этих канала будут иметь возможность регистрировать сообщение. Однако, как мы увидим ниже, действительно ли эти каналы регистрируют сообщение, может быть определено серьезностью / «уровнем» сообщения.

Уровни регистрации сообщений

Обратите внимание на параметр конфигурации level, присутствующий в конфигурациях каналов syslog и slack в приведенном выше примере. Эта опция определяет минимальный «уровень» сообщения, которое должно быть зарегистрировано каналом. Monolog, на котором работают службы ведения журналов Laravel, предлагает все уровни регистрации сообщений, определенные в спецификации RFC 5424 specification. В порядке убывания серьезности уровни регистрации: emergency, alert, critical, error, warning, notice, info и debug.

Итак, представьте, что мы регистрируем сообщение, используя метод debug:

Log::debug('An informational message.');

Учитывая нашу конфигурацию, канал syslog будет записывать сообщение в системный журнал; однако, поскольку сообщение об ошибке не является уровнем critical или выше, то оно не будет отправлено в Slack. Однако, если мы регистрируем сообщение уровня emergency, то оно будет отправлено как в системный журнал, так и в Slack, поскольку уровень emergency выше нашего минимального порогового значения для обоих каналов:

Log::emergency('The system is down!');

Запись сообщений журнала

Вы можете записывать информацию в журналы с помощью фасада Log. Как упоминалось ранее, средство ведения журнала обеспечивает восемь уровней ведения журнала, определенных в спецификации RFC 5424 specification: emergency, alert, critical, error, warning, notice, info, и debug.

use IlluminateSupportFacadesLog;

Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);

Вы можете вызвать любой из этих методов, чтобы записать сообщение для соответствующего уровня. По умолчанию сообщение будет записано в канал журнала по умолчанию, как настроено вашим файлом конфигурации logging:

<?php

namespace AppHttpControllers;

use AppHttpControllersController;
use AppModelsUser;
use IlluminateSupportFacadesLog;

class UserController extends Controller
{
    /**
     * Показать профиль конкретного пользователя.
     *
     * @param  int  $id
     * @return IlluminateHttpResponse
     */
    public function show($id)
    {
        Log::info('Showing the user profile for user: '.$id);

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

Контекстная информация

Также, методам журнала может быть передан массив контекстных данных. Эти контекстные данные будут отформатированы и отображены в сообщении журнала:

use IlluminateSupportFacadesLog;

Log::info('User failed to login.', ['id' => $user->id]);

По желанию можно указать некоторую контекстную информацию, которая должна быть включена во все последующие записи журнала конкретного канала. Например, логирование идентификатора запроса, связанного с каждым входящим запросом к вашему приложению. Для этого вы можете вызвать метод withContext фасада Log:

<?php

namespace AppHttpMiddleware;

use Closure;
use IlluminateSupportFacadesLog;
use IlluminateSupportStr;

class AssignRequestId
{
    /**
     * Обработка входящего запроса.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $requestId = (string) Str::uuid();

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

        return $next($request)->header('Request-Id', $requestId);
    }
}

Если вы хотите передавать контекстную информацию во все каналы, то вы можете вызвать метод Log::shareContext(). Этот метод предоставит контекстную информацию для всех имеющихся каналов и любых каналов, которые будут созданы впоследствии. Как правило, вызов этого метода осуществляется в методе boot поставщика:

use IlluminateSupportFacadesLog;
use IlluminateSupportStr;

class AppServiceProvider
{
    /**
     * Загрузка любых служб приложения.
     *
     * @return void
     */
    public function boot()
    {
        Log::shareContext([
            'invocation-id' => (string) Str::uuid(),
        ]);
    }
}

Запись в определенные каналы

По желанию можно записать сообщение в канал, отличный от канала по умолчанию вашего приложения. Вы можете использовать метод channel фасада Log для получения и регистрации любого канала, определенного в вашем файле конфигурации:

use IlluminateSupportFacadesLog;

Log::channel('slack')->info('Something happened!');

Если вы хотите создать стек протоколирования по запросу, состоящий из нескольких каналов, вы можете использовать метод stack:

Log::stack(['single', 'slack'])->info('Something happened!');

Каналы по запросу

По желанию можно создать канал по требованию, используя конкретную конфигурацию, без ее фактического присутствия в конфигурационном файле logging вашего приложения. Для этого вы можете передать массив конфигурации методу build фасада Log:

use IlluminateSupportFacadesLog;

Log::build([
  'driver' => 'single',
  'path' => storage_path('logs/custom.log'),
])->info('Something happened!');

Такой канал вы можете задействовать в стеке, созданном также по запросу. Этого можно добиться, добавив экземпляр вашего канала в массив, передаваемый методу stack:

use IlluminateSupportFacadesLog;

$channel = Log::build([
  'driver' => 'single',
  'path' => storage_path('logs/custom.log'),
]);

Log::stack(['slack', $channel])->info('Something happened!');

Настройка канала Monolog

Настройка Monolog для каналов

Иногда требуется полный контроль над настройкой Monolog для существующего канала. Например, бывает необходимо настроить собственную реализацию FormatterInterface Monolog для встроенного в Laravel канала single.

Для начала определите массив tap в конфигурации канала. Массив tap должен содержать список классов, которые должны иметь возможность настраивать (или «касаться») экземпляр Monolog после его создания. Не существует обычного места для размещения этих классов, поэтому вы можете создать каталог в своем приложении, чтобы разместить эти классы:

'single' => [
    'driver' => 'single',
    'tap' => [AppLoggingCustomizeFormatter::class],
    'path' => storage_path('logs/laravel.log'),
    'level' => 'debug',
],

После того, как вы настроили опцию tap своего канала, вы готовы определить класс, который будет контролировать ваш экземпляр Monolog. Этому классу нужен только один метод: __invoke, который получает экземпляр IlluminateLogLogger. Экземпляр IlluminateLogLogger передает все вызовы методов базовому экземпляру Monolog:

<?php

namespace AppLogging;

use MonologFormatterLineFormatter;

class CustomizeFormatter
{
    /**
     * Настроить переданный экземпляр регистратора.
     *
     * @param  IlluminateLogLogger  $logger
     * @return void
     */
    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            $handler->setFormatter(new LineFormatter(
                '[%datetime%] %channel%.%level_name%: %message% %context% %extra%'
            ));
        }
    }
}

Примечание
Все ваши классы, определенные в опции tap, извлекаются через контейнер служб Laravel, поэтому будут автоматически внедрены любые объявленные зависимости конструктора.

Создание обработчика каналов Monolog

В Monolog есть множество доступных обработчиков, но в Laravel из коробки не включены каналы для каждого из них. А иногда требуется создать собственный канал, который является просто экземпляром определенного обработчика Monolog, у которого нет соответствующего драйвера журнала Laravel. Эти каналы могут быть легко созданы с помощью драйвера monolog.

При использовании драйвера monolog параметр конфигурации handler используется для указания того, какой обработчик будет создан. При желании любые параметры конструктора, необходимые обработчику, могут быть указаны с помощью опции конфигурации with:

'logentries' => [
    'driver'  => 'monolog',
    'handler' => MonologHandlerSyslogUdpHandler::class,
    'with' => [
        'host' => 'my.logentries.internal.datahubhost.company.com',
        'port' => '10000',
    ],
],

Форматеры Monolog

При использовании драйвера monolog, Monolog LineFormatter будет использоваться как средство форматирования по умолчанию. Однако вы можете настроить тип средства форматирования, передаваемого обработчику, используя параметры конфигурации formatter и formatter_with:

'browser' => [
    'driver' => 'monolog',
    'handler' => MonologHandlerBrowserConsoleHandler::class,
    'formatter' => MonologFormatterHtmlFormatter::class,
    'formatter_with' => [
        'dateFormat' => 'Y-m-d',
    ],
],

Если вы используете обработчик Monolog, который может предоставлять свой собственный модуль форматирования, вы можете установить для параметра конфигурации formatter значение default:

'newrelic' => [
    'driver' => 'monolog',
    'handler' => MonologHandlerNewRelicHandler::class,
    'formatter' => 'default',
],

Создание каналов через фабрики

Если вы хотите определить полностью настраиваемый канал, в котором у вас есть полный контроль над созданием и конфигурацией Monolog, вы можете указать тип драйвера custom в файле конфигурации config/logging.php. Ваша конфигурация должна включать параметр via, который содержит имя класса фабрики, которая будет вызываться для создания экземпляра Monolog:

'channels' => [
    'example-custom-channel' => [
        'driver' => 'custom',
        'via' => AppLoggingCreateCustomLogger::class,
    ],
],

После того, как вы настроили канал драйвера custom, вы готовы определить класс, который будет создавать ваш экземпляр Monolog. Этому классу нужен только один метод __invoke, который должен возвращать экземпляр регистратора Monolog. Метод получит массив конфигурации каналов в качестве единственного аргумента:

<?php

namespace AppLogging;

use MonologLogger;

class CreateCustomLogger
{
    /**
     * Создать экземпляр собственного регистратора Monolog.
     *
     * @param  array  $config
     * @return MonologLogger
     */
    public function __invoke(array $config)
    {
        return new Logger(/* ... */);
    }
}

How Logging Works in Laravel Applications

Logs are records of the events happening with your application. Laravel, by default, writes log information into the laravel.log file that ships with a fresh Laravel installation. The file is housed within the storage > logs directory.

In this tutorial, you’ll learn the following:

  • Introduction to logging
  • Understanding log configurations
  • Channel drivers for log files
  • Formatting log messages

Screenshot-2023-01-05-at-23.26.03

Log file image

Introduction to Logging

Laravel provides a log of what’s happening in your application. The log service is built upon the Monolog open-source library.

The logging service is robust as it allows you to write log messages to files and send critical ones to teams on Slack (if configured), Socket, databases, and other web services.

The channel you wish to write your log information on is defined by the team, as there are a couple of channels supported by Laravel. Based on the severity of log information, the write information can also be done in multiple channels. You’ll see how you can do this in the configuration section.

How to Configure Your Laravel Logs

Laravel log configuration is located in the config > logging.php file. Consider using a couple of log channels based on your preferences, such as stack, single, daily, syslogs, slack, papertail, and so on.

The channels are where you send log information. The default channel for every project is usually stack. You can change it by defining the LOG_CHANNEL in the env or specifying the channel name as the second parameter in the same logging.php file.

'default' => env('LOG_CHANNEL', 'stack')

The stack channel has a driver name set to stack. Channels set to single means you get all logs in a single log file. You can also use daily which means a new log is auto-generated every day. It is an array.

You can also use multiple channels, 'channels' => ['daily', 'slack'], and ignore_exception is a boolean (true, false).

I highly recommend using the daily channel, as this helps you keep track of daily logs by auto-generating a new log file every day (laravel-2023-01-15.log, laravel-2023-01-16.log and so on) without having to clear logs for the previous day.

The daily options keep you updated each day with log info in your log files for as long as you want. It also enables you to monitor frequent errors within the application if they occur on different days.

 'channels' => [        
	'stack' => [ 
		'driver' => 'stack',            
		'channels' => ['daily'],    
		'ignore_exceptions' => false,        
	    ],
....],
Laravel log channels

Channel Drivers for Log Files

Here’s the list of the channel drivers Laravel offers:

  1. Single: The Single driver ensures log information is sent to a single file. The driver sends logs to storage > logs > laravel.log by default.
  2. daily: The driver ensures that logs are written daily. The beauty about this is that every day new log file is auto-generated. Compared to the Single driver, there’s no need to clear up the previous day’s log information frequently. But the drawback to this channel is that you might have several log files. Every week/month, you should clear up all unused files.

Within the logs directory, you often get logs like this:

Screenshot-2022-12-26-at-13.29.50

Daily log file

3.  slack: The slack driver ensures that all logs are sent to Slack. Slack needs to be configured to get user credentials (username, webhook) to help with error logging. This is super helpful as it allows your team to stay updated about what’s happening right in a Slack channel.

Screenshot-2022-12-26-at-13.19.26

4.  syslog: Logs using this driver will send log reports to the system log. The location of this log driver is dependent on the server operating system.

5.  errorlog: Logs set up to use this driver will send log reports to the error logs file setup on the web server operating system.

6.  monolog: This driver provides support for all Monolog handlers.

7.  custom: This driver helps create a custom channel based on user preference. It could be to a third-party service that needs log reports.

8.  stack: The stack driver is responsible for creating multiple channels

9.  null: All log messages get discarded by the driver.

How to Format Log Messages

If you need a refresher on how facades work or how to create one, you should refer to this article about how facades work in Laravel.

Laravel has a Log facade that helps with writing logs. Import the facade at the top of the file to use any log level.

<?php

use IlluminateSupportFacadesLog; 


Log::info($message);
Import Log facade

You can also choose to escape the Log facade, so you won’t need to import anything. This is suitable if you’re logging a single instance of log info.

<?php

Log::info($message);
Escape Log facade

In a recent Laravel release, logging has greatly improved. You can do away with the Log facade while logging info and reference the info from within your Laravel application.

<?php

info($message);
info without the log facade

Other logging levels used to write information include alert, emergency, critical, warning, error, notice, and debug.

Within a file, you can log any of the data types or messages and even format the output of text you wish to write to the log file.

How to format strings, booleans, and integers:

<?php

use IlluminateSupportFacadesLog;


Log::warning('There is a warning'); 

Log::error(false);

Log::notice(500); 
Write String, bool and integer to log file

How to format to an array:

You can also format to an array. With the array function, a new array is created. So we can write an array to the log file by passing the log info to the array function. The json_decode converts the JSON object to a PHP object, and the true ensure it returns associative arrays (key and value pairs).

<?php

$person = '{"Peter":35, "John":37, "Yinka":43}'; 

$data = json_decode($person, true);

info($data);
Write array to log file

How to format to an object:

You can also write JSON objects to the log file when working with logs. Use the json_encode to encode values into JSON format.

<?php 

$data = ["Peter"=> 35, "John"=> 37, "Yinka" => 43];

info(json_encode($data));
Write object to log file

How to concatenate string with array or objects:

This is helpful when including a string to track the log information. You can do this using the concatenation operator (.)

<?php

$persons = ["Peter"=> 35, "John"=> 37, "Yinka" => 43];

info('The person info ' . json_encode($persons));
Log info with strings and object

How to write to dedicated channels:

This method is helpful when you feel there’s a need to write into specific channels aside from the default log channel. It would help if you had to specify the channel name when calling the Log facade.

<?php


Log::channel('slack')->info('registeration successful');
Logging to dedicated channel

The snippet above ensures the write operation is done on the Slack channel. Also, the stack method allows logging on multiple channels.

<?php


Log::stack(['single', 'slack'])->info('registeration successful!');
Logging on multiple channels

You can learn more about custom channels via factories and monolog channel customization from the official documentation.

Wrapping up

In this article, you have learnt about logging, configuring logs in your Laravel application, available channel drivers, and how to write log files in different formats.

You should now have a better understanding of laravel logging. Keep learning, and Happy Coding!

You can find me on LinkedIn and Twitter.



Learn to code for free. freeCodeCamp’s open source curriculum has helped more than 40,000 people get jobs as developers. Get started

Понравилась статья? Поделить с друзьями:
  • Laravel логи ошибок
  • Laravel 500 ошибка после переноса
  • Land rover discovery ограничение мощности ошибка
  • Land rover discovery 3 ошибка пневмы
  • Land rover discovery 3 ошибка c1a13 64