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

Документация
L Laravel L intervention/image
Войти

Laravel Pulse

10.x 7 мар 2026 г.

#Введение

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

Для детальной отладки отдельных событий ознакомьтесь с Laravel Telescope.

#Установка

Внимание

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

Поскольку Pulse находится в бета-версии, возможно, потребуется изменить файл composer.json вашего приложения, чтобы разрешить установку бета-версий пакетов:

"minimum-stability": "beta",
"prefer-stable": true

Затем вы можете использовать менеджер пакетов Composer для установки Pulse в ваш проект Laravel:

composer require laravel/pulse

Далее следует опубликовать конфигурационные и миграционные файлы Pulse с помощью Artisan-команды vendor:publish:

php artisan vendor:publish --provider="Laravel\Pulse\PulseServiceProvider"

Наконец, выполните команду migrate для создания таблиц, необходимых для хранения данных Pulse:

php artisan migrate

После выполнения миграций Pulse вы сможете получить доступ к панели Pulse по маршруту /pulse.

Примечание

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

#Настройка

Многие параметры конфигурации Pulse можно управлять через переменные окружения. Чтобы увидеть доступные опции, зарегистрировать новые рекордеры или настроить расширенные параметры, опубликуйте файл конфигурации config/pulse.php:

php artisan vendor:publish --tag=pulse-config

#Панель управления

#Авторизация

Панель Pulse доступна по маршруту /pulse. По умолчанию доступ к панели возможен только в среде local, поэтому для рабочих сред необходимо настроить авторизацию, изменив ворота 'viewPulse'. Это можно сделать в файле app/Providers/AuthServiceProvider.php вашего приложения:

use App\Models\User;
use Illuminate\Support\Facades\Gate;

/**
 * Регистрация сервисов аутентификации и авторизации.
 */
public function boot(): void
{
    Gate::define('viewPulse', function (User $user) {
        return $user->isAdmin();
    });

    // ...
}

#Настройка

Карточки и макет панели Pulse можно настроить, опубликовав представление панели. Представление будет опубликовано в resources/views/vendor/pulse/dashboard.blade.php:

php artisan vendor:publish --tag=pulse-dashboard

Панель работает на базе Livewire и позволяет настраивать карточки и макет без необходимости пересобирать JavaScript-ассеты.

В этом файле компонент <x-pulse> отвечает за рендеринг панели и предоставляет сеточную разметку для карточек. Если вы хотите, чтобы панель занимала всю ширину экрана, передайте компоненту проп full-width:

<x-pulse full-width>
    ...
</x-pulse>

По умолчанию <x-pulse> создаёт сетку из 12 колонок, но вы можете изменить это с помощью пропа cols:

<x-pulse cols="16">
    ...
</x-pulse>

Каждая карточка принимает пропы cols и rows для управления размером и расположением:

<livewire:pulse.usage cols="4" rows="2" />

Большинство карточек также поддерживают проп expand для отображения полной карточки без прокрутки:

<livewire:pulse.slow-queries expand />

#Разрешение пользователей

Для карточек, отображающих информацию о пользователях, например, карточки использования приложения, Pulse сохраняет только ID пользователя. При рендеринге панели Pulse разрешает поля name и email из вашего стандартного Authenticatable-моделя и отображает аватары через сервис Gravatar.

Вы можете настроить поля и аватар, вызвав метод Pulse::user в классе App\Providers\AppServiceProvider вашего приложения.

Метод user принимает замыкание, которое получает Authenticatable-модель для отображения и должно возвращать массив с информацией name, extra и avatar для пользователя:

use Laravel\Pulse\Facades\Pulse;

/**
 * Инициализация сервисов приложения.
 */
public function boot(): void
{
    Pulse::user(fn ($user) => [
        'name' => $user->name,
        'extra' => $user->email,
        'avatar' => $user->avatar_url,
    ]);

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

Вы можете полностью настроить способ получения и отображения аутентифицированного пользователя, реализовав контракт Laravel\Pulse\Contracts\ResolvesUsers и зарегистрировав его в контейнере сервисов Laravel.

#Карточки

#Серверы

Карточка <livewire:pulse.servers /> отображает использование системных ресурсов для всех серверов, на которых запущена команда pulse:check. Подробнее о сборе данных о системных ресурсах см. в документации по рекордеру серверов.

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

Карточка <livewire:pulse.usage /> показывает топ-10 пользователей, которые делают запросы к приложению, запускают задания и испытывают медленные запросы.

Если вы хотите одновременно видеть все метрики использования, можно включить карточку несколько раз, указав атрибут type:

<livewire:pulse.usage type="requests" />
<livewire:pulse.usage type="slow_requests" />
<livewire:pulse.usage type="jobs" />

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

Примечание

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

#Исключения

Карточка <livewire:pulse.exceptions /> показывает частоту и свежесть исключений в вашем приложении. По умолчанию исключения группируются по классу и месту возникновения. Подробнее см. в документации по рекордеру исключений.

#Очереди

Карточка <livewire:pulse.queues /> отображает пропускную способность очередей вашего приложения, включая количество заданий в очереди, обрабатываемых, обработанных, освобождённых и неудачных. Подробнее см. в документации по рекордеру очередей.

#Медленные запросы

Карточка <livewire:pulse.slow-requests /> показывает входящие запросы к вашему приложению, превышающие установленный порог, который по умолчанию равен 1000 мс. Подробнее см. в документации по рекордеру медленных запросов.

#Медленные задания

Карточка <livewire:pulse.slow-jobs /> отображает задания в очереди, которые превышают установленный порог, по умолчанию 1000 мс. Подробнее см. в документации по рекордеру медленных заданий.

#Медленные запросы к базе данных

Карточка <livewire:pulse.slow-queries /> показывает запросы к базе данных, которые превышают установленный порог, по умолчанию 1000 мс.

По умолчанию медленные запросы группируются по SQL-запросу (без параметров) и месту возникновения, но вы можете отключить захват места, если хотите группировать только по SQL-запросу.

Подробнее см. в документации по рекордеру медленных запросов.

#Медленные исходящие запросы

Карточка <livewire:pulse.slow-outgoing-requests /> показывает исходящие запросы, сделанные с помощью HTTP клиента Laravel, которые превышают установленный порог, по умолчанию 1000 мс.

По умолчанию записи группируются по полному URL. Однако вы можете нормализовать или группировать похожие исходящие запросы с помощью регулярных выражений. Подробнее см. в документации по рекордеру медленных исходящих запросов.

#Кэш

Карточка <livewire:pulse.cache /> показывает статистику попаданий и промахов кэша вашего приложения, как глобально, так и по отдельным ключам.

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

#Сбор записей

Большинство рекордеров Pulse автоматически собирают записи на основе событий фреймворка Laravel. Однако рекордер серверов и некоторые сторонние карточки должны регулярно опрашивать информацию. Для их работы необходимо запускать демон pulse:check на каждом сервере приложения:

php artisan pulse:check
Примечание

Чтобы процесс pulse:check постоянно работал в фоне, рекомендуется использовать мониторинг процессов, например Supervisor, чтобы команда не останавливалась.

Поскольку команда pulse:check является долгоживущим процессом, она не увидит изменения в коде без перезапуска. Рекомендуется аккуратно перезапускать команду через pulse:restart во время деплоя приложения:

php artisan pulse:restart
Примечание

Pulse использует кэш для хранения сигналов перезапуска, поэтому убедитесь, что драйвер кэша корректно настроен перед использованием этой функции.

#Рекордеры

Рекордеры отвечают за сбор записей из вашего приложения для сохранения в базе данных Pulse. Рекордеры регистрируются и настраиваются в разделе recorders файла конфигурации Pulse.

#Взаимодействия с кэшем

Рекордер CacheInteractions фиксирует информацию о попаданиях и промахах в кэше, происходящих в вашем приложении, для отображения на карточке Кэш.

Вы можете настроить частоту выборки и шаблоны игнорируемых ключей.

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

Recorders\CacheInteractions::class => [
    // ...
    'groups' => [
        // '/:\d+/' => ':*',
    ],
],

Будет использован первый подходящий шаблон. Если ни один не подходит, ключ сохраняется как есть.

#Исключения

Рекордер Exceptions собирает информацию о регистрируемых исключениях в вашем приложении для отображения на карточке Исключения.

Вы можете настроить частоту выборки и шаблоны игнорируемых исключений. Также можно указать, захватывать ли место возникновения исключения. Захваченное место отображается на панели Pulse и помогает найти источник исключения; однако если одно и то же исключение возникает в разных местах, оно будет отображаться несколько раз для каждого уникального места.

#Очереди

Рекордер Queues собирает информацию о ваших очередях для отображения на карточке Очереди.

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

#Медленные задания

Рекордер SlowJobs собирает информацию о медленных заданиях в вашем приложении для отображения на карточке Медленные задания.

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

#Медленные исходящие запросы

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

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

Также можно настроить группировку URL, чтобы похожие URL объединялись в одну запись. Например, можно убрать уникальные ID из путей URL или группировать по домену. Группы настраиваются с помощью регулярных выражений для поиска и замены частей URL. В конфигурационном файле приведены примеры:

Recorders\OutgoingRequests::class => [
    // ...
    'groups' => [
        // '#^https://api\.github\.com/repos/.*$#' => 'api.github.com/repos/*',
        // '#^https?://([^/]*).*$#' => '\1',
        // '#/\d+#' => '/*',
    ],
],

Будет использован первый подходящий шаблон. Если ни один не подходит, URL сохраняется как есть.

#Медленные запросы к базе данных

Рекордер SlowQueries собирает запросы к базе данных, которые превышают установленный порог, для отображения на карточке Медленные запросы.

Вы можете настроить порог медленных запросов, частоту выборки и шаблоны игнорируемых запросов. Также можно указать, захватывать ли место выполнения запроса. Захваченное место отображается на панели Pulse и помогает найти источник запроса; однако если один и тот же запрос выполняется в разных местах, он будет отображаться несколько раз для каждого уникального места.

#Медленные запросы

Рекордер Requests собирает информацию о запросах к вашему приложению для отображения на карточках Медленные запросы и Использование приложения.

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

#Серверы

Рекордер Servers собирает данные об использовании CPU, памяти и хранилища серверов, на которых работает ваше приложение, для отображения на карточке Серверы. Для работы этого рекордера необходимо запускать pulse:check команду на каждом сервере, который вы хотите мониторить.

Каждый сервер должен иметь уникальное имя. По умолчанию Pulse использует значение, возвращаемое функцией PHP gethostname. Если хотите изменить это, установите переменную окружения PULSE_SERVER_NAME:

PULSE_SERVER_NAME=load-balancer

В конфигурационном файле Pulse также можно настроить директории для мониторинга.

#Задания пользователей

Рекордер UserJobs собирает информацию о пользователях, запускающих задания в вашем приложении, для отображения на карточке Использование приложения.

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

#Запросы пользователей

Рекордер UserRequests собирает информацию о пользователях, делающих запросы к вашему приложению, для отображения на карточке Использование приложения.

Вы можете настроить частоту выборки и шаблоны игнорируемых запросов.

#Фильтрация

Как мы видели, многие рекордеры позволяют через конфигурацию "игнорировать" записи на основе их значений, например URL запроса. Но иногда полезно фильтровать записи по другим критериям, например, по текущему аутентифицированному пользователю. Для этого можно передать замыкание в метод filter Pulse. Обычно вызов filter происходит в методе boot класса AppServiceProvider вашего приложения:

use Illuminate\Support\Facades\Auth;
use Laravel\Pulse\Entry;
use Laravel\Pulse\Facades\Pulse;
use Laravel\Pulse\Value;

/**
 * Инициализация сервисов приложения.
 */
public function boot(): void
{
    Pulse::filter(function (Entry|Value $entry) {
        return Auth::user()->isNotAdmin();
    });

    // ...
}

#Производительность

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

#Использование другой базы данных

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

Вы можете настроить подключение к базе данных, используемое Pulse, установив переменную окружения PULSE_DB_CONNECTION.

PULSE_DB_CONNECTION=pulse

#Redis Ingest

Внимание

Redis Ingest требует Redis версии 6.2 или выше и клиента phpredis или predis в качестве драйвера Redis для приложения.

По умолчанию Pulse сохраняет записи напрямую в настроенную базу данных после отправки HTTP-ответа клиенту или обработки задания; однако вы можете использовать драйвер Redis ingest, чтобы отправлять записи в поток Redis. Это можно включить, настроив переменную окружения PULSE_INGEST_DRIVER:

PULSE_INGEST_DRIVER=redis

Pulse по умолчанию использует ваше стандартное подключение Redis, но вы можете изменить его через переменную окружения PULSE_REDIS_CONNECTION:

PULSE_REDIS_CONNECTION=pulse

При использовании Redis ingest необходимо запускать команду pulse:work, которая будет следить за потоком и переносить записи из Redis в таблицы базы данных Pulse.

php artisan pulse:work
Примечание

Чтобы процесс pulse:work постоянно работал в фоне, рекомендуется использовать мониторинг процессов, например Supervisor, чтобы воркер Pulse не останавливался.

Поскольку команда pulse:work является долгоживущим процессом, она не увидит изменения в коде без перезапуска. Рекомендуется аккуратно перезапускать команду через pulse:restart во время деплоя приложения:

php artisan pulse:restart
Примечание

Pulse использует кэш для хранения сигналов перезапуска, поэтому убедитесь, что драйвер кэша корректно настроен перед использованием этой функции.

#Выборка

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

Вы можете включить "выборку" для некоторых рекордеров Pulse. Например, установка частоты выборки 0.1 для рекордера User Requests означает, что будет записано примерно 10% запросов к вашему приложению. В панели значения будут масштабированы и помечены префиксом ~, указывающим на приближённость данных.

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

#Обрезка

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

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

Если при сборе данных Pulse возникает исключение, например, из-за невозможности подключения к базе данных, Pulse тихо игнорирует ошибку, чтобы не повлиять на работу приложения.

Если вы хотите настроить обработку таких исключений, можно передать замыкание в метод handleExceptionsUsing:

use Laravel\Pulse\Facades\Pulse;
use Illuminate\Support\Facades\Log;

Pulse::handleExceptionsUsing(function ($e) {
    Log::debug('An exception happened in Pulse', [
        'message' => $e->getMessage(),
        'stack' => $e->getTraceAsString(),
    ]);
});

#Пользовательские карточки

Pulse позволяет создавать пользовательские карточки для отображения данных, специфичных для вашего приложения. Pulse использует Livewire, поэтому перед созданием первой карточки рекомендуется ознакомиться с его документацией.

#Компоненты карточек

Создание пользовательской карточки в Laravel Pulse начинается с расширения базового Livewire-компонента Card и определения соответствующего представления:

namespace App\Livewire\Pulse;

use Laravel\Pulse\Livewire\Card;
use Livewire\Attributes\Lazy;

#[Lazy]
class TopSellers extends Card
{
    public function render()
    {
        return view('livewire.pulse.top-sellers');
    }
}

При использовании функции ленивой загрузки Livewire компонент Card автоматически предоставляет плейсхолдер, учитывающий атрибуты cols и rows, переданные вашему компоненту.

При написании представления для вашей карточки Pulse вы можете использовать Blade-компоненты Pulse для единообразного внешнего вида:

<x-pulse::card :cols="$cols" :rows="$rows" :class="$class" wire:poll.5s="">
    <x-pulse::card-header name="Top Sellers">
        <x-slot:icon>
            ...
        </x-slot:icon>
    </x-pulse::card-header>

    <x-pulse::scroll :expand="$expand">
        ...
    </x-pulse::scroll>
</x-pulse::card>

Переменные $cols, $rows, $class и $expand должны передаваться соответствующим Blade-компонентам, чтобы макет карточки можно было настраивать из представления панели. Также можно добавить атрибут wire:poll.5s="" для автоматического обновления карточки.

После определения Livewire-компонента и шаблона карточку можно включить в представление панели:

<x-pulse>
    ...

    <livewire:pulse.top-sellers cols="4" />
</x-pulse>
Примечание

Если ваша карточка входит в состав пакета, необходимо зарегистрировать компонент в Livewire с помощью метода Livewire::component.

#Стилизация

Если вашей карточке требуется дополнительная стилизация помимо классов и компонентов Pulse, есть несколько способов добавить пользовательский CSS.

#Интеграция с Laravel Vite

Если ваша пользовательская карточка находится в кодовой базе приложения и вы используете интеграцию Laravel с Vite, вы можете обновить файл vite.config.js, добавив отдельную точку входа CSS для карточки:

laravel({
    input: [
        'resources/css/pulse/top-sellers.css',
        // ...
    ],
}),

Затем в представлении панели используйте директиву Blade @vite, указав CSS-точку входа для вашей карточки:

<x-pulse>
    @vite('resources/css/pulse/top-sellers.css')

    ...
</x-pulse>

#CSS-файлы

В других случаях, включая карточки Pulse, содержащиеся в пакете, можно указать Pulse загружать дополнительные стили, определив метод css в вашем Livewire-компоненте, который возвращает путь к CSS-файлу:

class TopSellers extends Card
{
    // ...

    protected function css()
    {
        return __DIR__.'/../../dist/top-sellers.css';
    }
}

Когда карточка включена на панели, Pulse автоматически вставит содержимое этого файла в тег <style>, поэтому его не нужно публиковать в директорию public.

#Tailwind CSS

При использовании Tailwind CSS рекомендуется создать отдельный конфигурационный файл Tailwind, чтобы избежать загрузки лишнего CSS и конфликтов с классами Tailwind Pulse:

export default {
    darkMode: 'class',
    important: '#top-sellers',
    content: [
        './resources/views/livewire/pulse/top-sellers.blade.php',
    ],
    corePlugins: {
        preflight: false,
    },
};

Затем укажите этот конфигурационный файл в точке входа CSS:

@config "../../tailwind.top-sellers.config.js";
@tailwind base;
@tailwind components;
@tailwind utilities;

Также в представлении карточки необходимо добавить атрибут id или class, соответствующий селектору, переданному в стратегию селектора important Tailwind:

<x-pulse::card id="top-sellers" :cols="$cols" :rows="$rows" class="$class">
    ...
</x-pulse::card>

#Сбор и агрегация данных

Пользовательские карточки могут получать и отображать данные из любых источников; однако вы можете использовать мощную и эффективную систему записи и агрегации данных Pulse.

#Сбор записей

Pulse позволяет записывать "записи" с помощью метода Pulse::record:

use Laravel\Pulse\Facades\Pulse;

Pulse::record('user_sale', $user->id, $sale->amount)
    ->sum()
    ->count();

Первый аргумент метода record — это type записи, которую вы фиксируете, второй — key, определяющий, как агрегированные данные должны группироваться. Для большинства методов агрегации также нужно указать value для агрегации. В приведённом примере агрегируется значение $sale->amount. Затем можно вызвать один или несколько методов агрегации (например, sum), чтобы Pulse мог сохранять предварительно агрегированные значения в "корзинах" для эффективного последующего получения.

Доступные методы агрегации:

  • avg
  • count
  • max
  • min
  • sum
Примечание

При создании пакета карточек, который фиксирует ID аутентифицированного пользователя, следует использовать метод Pulse::resolveAuthenticatedUserId(), который учитывает любые настройки разрешения пользователя в приложении.

#Получение агрегированных данных

При расширении Livewire-компонента Card Pulse можно использовать метод aggregate для получения агрегированных данных за период, отображаемый на панели:

class TopSellers extends Card
{
    public function render()
    {
        return view('livewire.pulse.top-sellers', [
            'topSellers' => $this->aggregate('user_sale', ['sum', 'count']);
        ]);
    }
}

Метод aggregate возвращает коллекцию объектов PHP stdClass. Каждый объект содержит ранее зафиксированное свойство key и ключи для каждого запрошенного агрегата:

@foreach ($topSellers as $seller)
    {{ $seller->key }}
    {{ $seller->sum }}
    {{ $seller->count }}
@endforeach

Pulse в основном получает данные из предварительно агрегированных корзин; поэтому указанные агрегаты должны быть зафиксированы заранее с помощью метода Pulse::record. Самая старая корзина обычно частично выходит за пределы периода, поэтому Pulse агрегирует старые записи, чтобы заполнить пробел и дать точное значение за весь период без необходимости агрегировать весь период при каждом запросе.

Также можно получить общее значение для заданного типа с помощью метода aggregateTotal. Например, следующий метод вернёт сумму всех продаж пользователей без группировки по пользователям.

$total = $this->aggregateTotal('user_sale', 'sum');

#Отображение пользователей

При работе с агрегатами, где ключом является ID пользователя, можно разрешить ключи в записи пользователей с помощью метода Pulse::resolveUsers:

$aggregates = $this->aggregate('user_sale', ['sum', 'count']);

$users = Pulse::resolveUsers($aggregates->pluck('key'));

return view('livewire.pulse.top-sellers', [
    'sellers' => $aggregates->map(fn ($aggregate) => (object) [
        'user' => $users->find($aggregate->key),
        'sum' => $aggregate->sum,
        'count' => $aggregate->count,
    ])
]);

Метод find возвращает объект с ключами name, extra и avatar, которые можно передать напрямую в Blade-компонент <x-pulse::user-card>:

<x-pulse::user-card :user="{{ $seller->user }}" :stats="{{ $seller->sum }}" />

#Пользовательские рекордеры

Авторы пакетов могут предоставить классы рекордеров, чтобы пользователи могли настраивать сбор данных.

Рекордеры регистрируются в разделе recorders конфигурационного файла приложения config/pulse.php:

[
    // ...
    'recorders' => [
        Acme\Recorders\Deployments::class => [
            // ...
        ],

        // ...
    ],
]

Рекордеры могут слушать события, указывая свойство $listen. Pulse автоматически зарегистрирует слушателей и вызовет метод record рекордера:

<?php

namespace Acme\Recorders;

use Acme\Events\Deployment;
use Illuminate\Support\Facades\Config;
use Laravel\Pulse\Facades\Pulse;

class Deployments
{
    /**
     * События для прослушивания.
     *
     * @var list<class-string>
     */
    public array $listen = [
        Deployment::class,
    ];

    /**
     * Записать деплоймент.
     */
    public function record(Deployment $event): void
    {
        $config = Config::get('pulse.recorders.'.static::class);

        Pulse::record(
            // ...
        );
    }
}