Документация Laravel 10.x
Здесь ты найдешь сниппеты по Laravel и полезные советы по веб-разработке.
Чтобы узнать больше о том, что происходит в вашем приложении, 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
есть три дополнительные настраиваемые опции: bubble
, permission
и locking
.
Имя | Описание | По умолчанию |
---|---|---|
bubble |
Указывает, следует ли сообщениям всплывать в другие каналы после их обработки | true |
locking |
Попытка блокировки файла журнала перед записью в него | false |
permission |
Разрешения файла журнала | 0644 |
Кроме того, политика удержания для канала daily
может быть настроена с помощью опции days
:
Имя | Описание | По умолчанию |
---|---|---|
days |
Количество дней, в течение которых должны сохраняться ежедневные файлы журнала | 7 |
Канал papertrail
требует наличие опций конфигурации host
и port
. Вы можете получить эти значения из Papertrail.
Канал 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('An informational message.');
Учитывая нашу конфигурацию, канал syslog
будет записывать сообщение в системный журнал; однако, поскольку сообщение об ошибке не является critical
или выше, оно не будет отправлено в Slack. Однако, если мы зарегистрируем сообщение emergency
, оно будет отправлено как в системный журнал, так и в Slack, поскольку уровень emergency
выше нашего минимального порога уровня для обоих каналов:
Log::emergency('The system is down!');
Вы можете записывать информацию в журналы, используя фасад 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;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()
. Этот метод предоставит контекстную информацию всем созданным каналам и любым каналам, которые будут созданы впоследствии. Обычно метод shareContext
следует вызывать из метода boot
сервис-провайдера приложения:
use Illuminate\Support\Facades\Log;use Illuminate\Support\Str; class AppServiceProvider{ /** * Инициализировать любые службы приложения. */ public function boot(): void { Log::shareContext([ 'invocation-id' => (string) Str::uuid(), ]); }}
Иногда вам может потребоваться записать сообщение в канал, отличный от канала по умолчанию вашего приложения. Вы можете использовать метод 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 настроен для существующего канала. Например, вы можете хотеть настроить реализацию пользовательского интерфейса FormatterInterface
Monolog для встроенного канала single
Laravel.
Для начала определите массив 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 есть разнообразие доступных обработчиков, и 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
, добавьте значение конфигурации 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(/* ... */); }}
Часто вам может потребоваться отслеживать логи вашего приложения в реальном времени. Например, при отладке проблемы или мониторинге логов вашего приложения для определенных типов ошибок.
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
Чтобы отобразить только логи, записанные во время аутентификации определенного пользователя, вы можете предоставить идентификатор пользователя опции --user
:
php artisan pail --user=1