Laravel Pulse
简介
Laravel Pulse 提供对应用程序性能和用法的概览。使用 Pulse,您可以跟踪瓶颈(例如缓慢的作业和端点),找到最活跃的用户等等。
有关单个事件的深入调试,请查看 Laravel Telescope。
安装
Pulse 的首选存储实现当前需要 MySQL、MariaDB 或 PostgreSQL 数据库。如果您使用的是其他数据库引擎,则需要一个单独的 MySQL、MariaDB 或 PostgreSQL 数据库来存储 Pulse 数据。
您可以使用 Composer 包管理器安装 Pulse
composer require laravel/pulse
接下来,您应该使用 vendor:publish
Artisan 命令发布 Pulse 配置和迁移文件
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/AppServiceProvider.php
文件中完成此操作
use App\Models\User;use Illuminate\Support\Facades\Gate; /** * Bootstrap any application services. */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 将从默认的 Authenticatable
模型解析 name
和 email
字段,并使用 Gravatar 网络服务显示头像。
您可以在应用程序的 App\Providers\AppServiceProvider
类中调用 Pulse::user
方法来自定义字段和头像。
user
方法接受一个闭包,该闭包将接收要显示的 Authenticatable
模型,并应返回一个包含用户的 name
、extra
和 avatar
信息的数组
use Laravel\Pulse\Facades\Pulse; /** * Bootstrap any application services. */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
命令的所有服务器的系统资源使用情况。有关系统资源报告的更多信息,请参考有关 服务器记录器 的文档。
如果您在基础设施中替换服务器,您可能希望在给定持续时间后停止在 Pulse 仪表盘中显示非活动服务器。您可以使用 ignore-after
属性来完成此操作,该属性接受非活动服务器应从 Pulse 仪表盘中删除后的秒数。或者,您可以提供一个相对时间格式的字符串,例如 1 hour
或 3 days and 1 hour
<livewire:pulse.servers ignore-after="3 hours" />
应用程序使用量
<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 />
卡片显示进入应用程序并超过配置阈值的请求,默认情况下为 1,000 毫秒。有关更多信息,请参阅 缓慢请求记录器 文档。
缓慢作业
<livewire:pulse.slow-jobs />
卡片显示应用程序中超过配置阈值的排队作业,默认情况下为 1,000 毫秒。有关更多信息,请参阅 缓慢作业记录器 文档。
缓慢查询
<livewire:pulse.slow-queries />
卡片显示应用程序中超过配置阈值的数据库查询,默认情况下为 1,000 毫秒。
默认情况下,缓慢查询会根据 SQL 查询(无绑定)及其发生的位置进行分组,但如果您希望仅根据 SQL 查询进行分组,可以选择不捕获位置。
如果您由于极大的 SQL 查询接收语法突出显示而遇到渲染性能问题,您可以通过添加 without-highlighting
属性来禁用突出显示
<livewire:pulse.slow-queries without-highlighting />
有关更多信息,请参阅 缓慢查询记录器 文档。
缓慢的传出请求
<livewire:pulse.slow-outgoing-requests />
卡片展示了使用 Laravel 的 HTTP 客户端 发出的超过配置阈值的请求,默认情况下为 1,000 毫秒。
默认情况下,条目将按完整 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 数据库中。记录器在 Pulse 配置文件 的 recorders
部分中注册和配置。
缓存交互
CacheInteractions
记录器捕获有关 缓存 在您的应用程序中发生的命中和未命中信息,以便在 缓存 卡片上显示。
您也可以选择调整 采样率 和忽略的键模式。
您还可以配置键分组,以便将类似的键分组为单个条目。例如,您可能希望从缓存相同类型信息的键中删除唯一 ID。组是使用正则表达式配置的,用于“查找和替换”键的某些部分。配置示例已包含在配置文件中。
Recorders\CacheInteractions::class => [ // ... 'groups' => [ // '/:\d+/' => ':*', ],],
将使用第一个匹配的模式。如果没有任何模式匹配,则将按原样捕获键。
异常
Exceptions
记录器捕获有关在您的应用程序中发生的已报告异常的信息,以便在 异常 卡片上显示。
您也可以选择调整 采样率 和忽略的异常模式。您还可以配置是否捕获异常起源的位置。捕获的位置将在 Pulse 仪表板上显示,这有助于跟踪异常起源;但是,如果相同的异常在多个位置发生,则它将为每个唯一位置显示多次。
队列
Queues
记录器捕获有关您的应用程序队列的信息,以便在 队列 上显示。
您也可以选择调整 采样率 和忽略的作业模式。
缓慢作业
SlowJobs
记录器捕获有关在您的应用程序中发生的慢速作业的信息,以便在 慢速作业 卡片上显示。
您也可以选择调整慢速作业阈值、采样率 和忽略的作业模式。
您可能有一些作业,您预计它们比其他作业耗时更长。在这种情况下,您可以配置每个作业的阈值。
Recorders\SlowJobs::class => [ // ... 'threshold' => [ '#^App\\Jobs\\GenerateYearlyReports$#' => 5000, 'default' => env('PULSE_SLOW_JOBS_THRESHOLD', 1000), ],],
如果没有任何正则表达式模式与作业的类名匹配,则将使用 'default'
值。
缓慢的传出请求
SlowOutgoingRequests
记录器捕获有关使用 Laravel 的 HTTP 客户端 发出的超过配置阈值的传出 HTTP 请求的信息,以便在 慢速传出请求 卡片上显示。
您也可以选择调整慢速传出请求阈值、采样率 和忽略的 URL 模式。
您可能有一些传出请求,您预计它们比其他请求耗时更长。在这种情况下,您可以配置每个请求的阈值。
Recorders\SlowOutgoingRequests::class => [ // ... 'threshold' => [ '#backup.zip$#' => 5000, 'default' => env('PULSE_SLOW_OUTGOING_REQUESTS_THRESHOLD', 1000), ],],
如果没有任何正则表达式模式与请求的 URL 匹配,则将使用 'default'
值。
您还可以配置 URL 分组,以便将类似的 URL 分组为单个条目。例如,您可能希望从 URL 路径中删除唯一 ID 或仅按域进行分组。组是使用正则表达式配置的,用于“查找和替换”URL 的某些部分。配置示例已包含在配置文件中。
Recorders\SlowOutgoingRequests::class => [ // ... 'groups' => [ // '#^https://api\.github\.com/repos/.*$#' => 'api.github.com/repos/*', // '#^https?://([^/]*).*$#' => '\1', // '#/\d+#' => '/*', ],],
将使用第一个匹配的模式。如果没有任何模式匹配,则将按原样捕获 URL。
缓慢查询
SlowQueries
记录器捕获在您的应用程序中超过配置阈值的任何数据库查询,以便在 慢速查询 卡片上显示。
您也可以选择调整慢速查询阈值、采样率 和忽略的查询模式。您还可以配置是否捕获查询位置。捕获的位置将在 Pulse 仪表板上显示,这有助于跟踪查询起源;但是,如果相同的查询在多个位置执行,则它将为每个唯一位置显示多次。
您可能有一些查询,您预计它们比其他查询耗时更长。在这种情况下,您可以配置每个查询的阈值。
Recorders\SlowQueries::class => [ // ... 'threshold' => [ '#^insert into `yearly_reports`#' => 5000, 'default' => env('PULSE_SLOW_QUERIES_THRESHOLD', 1000), ],],
如果没有任何正则表达式模式与查询的 SQL 语句匹配,则将使用 'default'
值。
缓慢请求
Requests
记录器捕获有关向您的应用程序发出的请求的信息,以便在 慢速请求 和 应用程序使用情况 卡片上显示。
您也可以选择调整慢速路由阈值、采样率 和忽略的路径。
您可能有一些请求,您预计它们比其他请求耗时更长。在这种情况下,您可以配置每个请求的阈值。
Recorders\SlowRequests::class => [ // ... 'threshold' => [ '#^/admin/#' => 5000, 'default' => env('PULSE_SLOW_REQUESTS_THRESHOLD', 1000), ],],
如果没有任何正则表达式模式与请求的 URL 匹配,则将使用 'default'
值。
服务器
Servers
记录器捕获为您的应用程序提供服务的服务器的 CPU、内存和存储使用情况,以便在 服务器 卡片上显示。此记录器要求 pulse:check
命令 在您要监控的每个服务器上运行。
每个报告服务器必须具有唯一的名称。默认情况下,Pulse 将使用 PHP 的 gethostname
函数返回的值。如果您想自定义此值,您可以设置 PULSE_SERVER_NAME
环境变量。
PULSE_SERVER_NAME=load-balancer
Pulse 配置文件还允许您自定义要监控的目录。
用户作业
UserJobs
记录器捕获有关在您的应用程序中调度作业的用户的信息,以便在 应用程序使用情况 卡片上显示。
您也可以选择调整 采样率 和忽略的作业模式。
用户请求
UserRequests
记录器捕获有关向您的应用程序发出请求的用户的信息,以便在 应用程序使用情况 卡片上显示。
您也可以选择调整 采样率 和忽略的 URL 模式。
过滤
如我们所见,许多 记录器 通过配置提供了“忽略”基于其值的传入条目(例如请求的 URL)的功能。但是,有时可能需要根据其他因素(例如当前经过身份验证的用户)来过滤掉记录。要过滤掉这些记录,您可以将闭包传递给 Pulse 的 filter
方法。通常,应在应用程序的 AppServiceProvider
的 boot
方法中调用 filter
方法。
use Illuminate\Support\Facades\Auth;use Laravel\Pulse\Entry;use Laravel\Pulse\Facades\Pulse;use Laravel\Pulse\Value; /** * Bootstrap any application services. */public function boot(): void{ Pulse::filter(function (Entry|Value $entry) { return Auth::user()->isNotAdmin(); }); // ...}
性能
Pulse 的设计目的是集成到现有的应用程序中,而无需任何额外的基础设施。但是,对于高流量应用程序,有几种方法可以消除 Pulse 对应用程序性能的影响。
使用不同的数据库
对于高流量应用程序,您可能更喜欢为 Pulse 使用专用的数据库连接,以避免影响应用程序数据库。
您可以通过设置 PULSE_DB_CONNECTION
环境变量来自定义 Pulse 使用的 数据库连接。
PULSE_DB_CONNECTION=pulse
Redis 导入
Redis Ingest 需要 Redis 6.2 或更高版本以及 phpredis
或 predis
作为应用程序的配置 Redis 客户端驱动程序。
默认情况下,Pulse 会在将 HTTP 响应发送到客户端或处理作业后,将条目直接存储到 配置的数据库连接 中;但是,您可以使用 Pulse 的 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
意味着您只记录大约 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 中创建自定义卡片始于扩展基本 Card
Livewire 组件并定义相应的视图。
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 卡片相应的视图时,您可以利用 Pulse 的 Blade 组件以获得一致的外观和感觉。
<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::component` 方法将组件注册到 Livewire。
样式
如果您的卡片需要超出 Pulse 包含的类和组件的额外样式,您可以选择几种方法来包含卡片的自定义 CSS。
Laravel Vite 集成
如果您的自定义卡片位于应用程序代码库中,并且您使用的是 Laravel 的 Vite 集成,您可以更新您的 `vite.config.js` 文件以包含您的卡片的专用 CSS 入口点。
laravel({ input: [ 'resources/css/pulse/top-sellers.css', // ... ],}),
然后,您可以在您的 仪表板视图 中使用 `@vite` Blade 指令,指定您的卡片的 CSS 入口点。
<x-pulse> @vite('resources/css/pulse/top-sellers.css') ...</x-pulse>
CSS 文件
对于其他用例,包括包含在包中的 Pulse 卡片,您可以通过在 Livewire 组件上定义一个 `css` 方法来指示 Pulse 加载额外的样式表,该方法返回您的 CSS 文件的文件路径。
class TopSellers extends Card{ // ... protected function css() { return __DIR__.'/../../dist/top-sellers.css'; }}
当此卡片包含在仪表板上时,Pulse 会自动将此文件的内容包含在 `<style>` 标签中,因此不需要将其发布到 `public` 目录。
Tailwind CSS
使用 Tailwind CSS 时,您应该创建一个专用的 Tailwind 配置文件,以避免加载不必要的 CSS 或与 Pulse 的 Tailwind 类冲突。
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` 属性,该属性与传递给 Tailwind 的 `important` 选择器策略 的选择器匹配。
<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()` 方法,该方法会尊重对应用程序进行的任何 用户解析器自定义。
检索聚合数据
扩展 Pulse 的 `Card` Livewire 组件时,您可以使用 `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` 键的对象,您可以选择直接将这些键传递给 `<x-pulse::user-card>` Blade 组件。
<x-pulse::user-card :user="{{ $seller->user }}" :stats="{{ $seller->sum }}" />
自定义记录器
包作者可能希望提供记录器类,以允许用户配置数据的捕获。
记录器在应用程序的 `config/pulse.php` 配置文件的 `recorders` 部分注册。
[ // ... '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{ /** * The events to listen for. * * @var array<int, class-string> */ public array $listen = [ Deployment::class, ]; /** * Record the deployment. */ public function record(Deployment $event): void { $config = Config::get('pulse.recorders.'.static::class); Pulse::record( // ... ); }}