Skip to content
Icon

ПРЕДУПРЕЖДЕНИЕ Вы просматриваете документацию к старой версии Laravel. Рассмотрите возможность обновления Вашего проекта до Laravel 9.x.

Логирование

Введение

Чтобы помочь вам узнать больше о том, что происходит в вашем приложении, 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

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

Требования к каналу

Настройка одиночного и ежедневного каналов

Каналы 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: emergency, alert, critical, error, warning, notice, info и debug.

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

Log::debug('Информационное сообщение.');

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

Log::emergency('Система не работает!');

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

Вы можете записывать информацию в журналы, используя Log фасад. Как упоминалось ранее, средство ведения журнала обеспечивает восемь уровней ведения журнала, определенных в спецификации 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;
 
class UserController extends Controller
{
/**
* Show the profile for the given user.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
Log::info('Showing the user profile for user: '.$id);
 
return view('user.profile', [
'user' => User::findOrFail($id)
]);
}
}

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

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

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

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

<?php
 
namespace App\Http\Middleware;
 
use Closure;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
 
class AssignRequestId
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $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 Illuminate\Support\Facades\Log;
 
Log::channel('slack')->info('Something happened!');

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

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

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

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

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 для существующего канала. Например, вы можете настроить собственную реализацию Monolog FormatterInterface для встроенного в Laravel канала 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 Monolog\Formatter\LineFormatter;
 
class CustomizeFormatter
{
/**
* Customize the given logger instance.
*
* @param \Illuminate\Log\Logger $logger
* @return void
*/
public function __invoke($logger)
{
foreach ($logger->getHandlers() as $handler) {
$handler->setFormatter(new LineFormatter(
'[%datetime%] %channel%.%level_name%: %message% %context% %extra%'
));
}
}
}

{tip} All of your "tap" classes are resolved by the service container, so any constructor dependencies they require will automatically be injected.

Создание каналов обработчика 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 в качестве средства форматирования по умолчанию будет использоваться 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, вы можете указать тип драйвера 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
{
/**
* Create a custom Monolog instance.
*
* @param array $config
* @return \Monolog\Logger
*/
public function __invoke(array $config)
{
return new Logger(...);
}
}