Идёт обновление сайта. Несколько дней возможны сбои в оформлении и переводах. Документация работает — если страница выглядит сломанной, обновите её позже.

Документация
L Laravel L intervention/image
Войти
Главная Laravel 10.x Логирование

Логирование

10.x 7 мар 2026 г.

#Введение

Чтобы помочь вам лучше понимать, что происходит в вашем приложении, 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
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 для входящего webhook, который вы настроили для вашей команды в 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. В порядке убывания важности уровни таковы: 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 facade. Как уже упоминалось, логгер поддерживает восемь уровней логирования, определённых в RFC 5424: emergency, alert, critical, error, warning, notice, info и 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);

Вы можете вызвать любой из этих методов для записи сообщения соответствующего уровня. По умолчанию сообщение будет записано в канал по умолчанию, настроенный в вашем файле конфигурации 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
{
    /**
     * Показать профиль указанного пользователя.
     */
    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)
        ]);
    }
}

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

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

use Illuminate\Support\Facades\Log;

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

Иногда может потребоваться указать контекстную информацию, которая будет добавляться ко всем последующим записям в определённом канале. Например, вы можете захотеть логировать идентификатор запроса, связанный с каждым входящим запросом к вашему приложению. Для этого можно вызвать метод withContext фасада 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
{
    /**
     * Обработать входящий запрос.
     *
     * @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;
    }
}

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

<?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
{
    /**
     * Обработать входящий запрос.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        $requestId = (string) Str::uuid();

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

        // ...
    }
}
Примечание

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

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

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

use Illuminate\Support\Facades\Log;

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

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

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

#Каналы на лету

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

use Illuminate\Support\Facades\Log;

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

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

use Illuminate\Support\Facades\Log;

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

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

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

#Кастомизация Monolog для каналов

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

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

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

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

<?php

namespace App\Logging;

use Illuminate\Log\Logger;
use Monolog\Formatter\LineFormatter;

class CustomizeFormatter
{
    /**
     * Кастомизировать переданный экземпляр логгера.
     */
    public function __invoke(Logger $logger): void
    {
        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' => Monolog\Handler\SyslogUdpHandler::class,
    'with' => [
        'host' => 'my.logentries.internal.datahubhost.company.com',
        'port' => '10000',
    ],
],

#Форматтеры Monolog

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

'browser' => [
    'driver' => 'monolog',
    'handler' => Monolog\Handler\BrowserConsoleHandler::class,
    'formatter' => Monolog\Formatter\HtmlFormatter::class,
    'formatter_with' => [
        'dateFormat' => 'Y-m-d',
    ],
],

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

'newrelic' => [
    'driver' => 'monolog',
    'handler' => Monolog\Handler\NewRelicHandler::class,
    'formatter' => 'default',
],

#Процессоры Monolog

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

Чтобы настроить процессоры для драйвера monolog, добавьте опцию processors в конфигурацию канала:

 'memory' => [
     'driver' => 'monolog',
     'handler' => Monolog\Handler\StreamHandler::class,
     'with' => [
         'stream' => 'php://stderr',
     ],
     'processors' => [
         // Простой синтаксис...
         Monolog\Processor\MemoryUsageProcessor::class,

         // С опциями...
         [
            'processor' => Monolog\Processor\PsrLogMessageProcessor::class,
            'with' => ['removeUsedContextFields' => true],
        ],
     ],
 ],

#Создание пользовательских каналов через фабрики

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

'channels' => [
    'example-custom-channel' => [
        'driver' => 'custom',
        'via' => App\Logging\CreateCustomLogger::class,
    ],
],

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

<?php

namespace App\Logging;

use Monolog\Logger;

class CreateCustomLogger
{
    /**
     * Создать кастомный экземпляр Monolog.
     */
    public function __invoke(array $config): Logger
    {
        return new Logger(/* ... */);
    }
}

#Просмотр логов в реальном времени с помощью Pail

Часто возникает необходимость просматривать логи приложения в реальном времени. Например, при отладке или мониторинге определённых ошибок.

Laravel Pail — это пакет, который позволяет легко просматривать файлы логов вашего Laravel-приложения прямо из командной строки. В отличие от стандартной команды tail, Pail работает с любым драйвером логов, включая Sentry или Flare. Кроме того, Pail предоставляет набор полезных фильтров для быстрого поиска нужных записей.

#Установка

Внимание

Laravel Pail требует PHP 8.2+ и расширение PCNTL.

Для начала установите Pail в ваш проект с помощью менеджера пакетов Composer:

composer require laravel/pail

#Использование

Чтобы начать просмотр логов, выполните команду pail:

php artisan pail

Чтобы увеличить подробность вывода и избежать усечения (…), используйте опцию -v:

php artisan pail -v

Для максимальной подробности и отображения трассировок исключений используйте опцию -vv:

php artisan pail -vv

Чтобы остановить просмотр логов, нажмите Ctrl+C в любой момент.

#Фильтрация логов

#--filter

Вы можете использовать опцию --filter для фильтрации логов по типу, файлу, сообщению и содержимому трассировки стека:

php artisan pail --filter="QueryException"

#--message

Для фильтрации логов только по сообщению используйте опцию --message:

php artisan pail --message="User created"

#--level

Опция --level позволяет фильтровать логи по уровню логирования:

php artisan pail --level=error

--user

Чтобы отображать только логи, записанные во время аутентификации конкретного пользователя, укажите его ID в опции --user:

php artisan pail --user=1