Laravel Pulse cung cấp cho bạn một cái nhìn tổng quan về hiệu suất và mức độ sử dụng trong ứng dụng của bạn. Với Pulse, bạn có thể theo dõi các slow job và request, tìm ra người dùng hoạt động tích cực nhất, vv...
Để debug chuyên sâu hơn cho từng event, hãy xem Laravel Telescope.
[!WARNING] Hiện tại việc lưu trữ của Pulse sẽ yêu cầu cơ sở dữ liệu MySQL, MariaDB, hoặc PostgreSQL. Nếu bạn đang sử dụng một cơ sở dữ liệu khác, bạn sẽ cần một cơ sở dữ liệu MySQL, MariaDB, hoặc PostgreSQL riêng cho việc lưu trữ dữ liệu Pulse của bạn.
Bạn có thể cài đặt Pulse bằng trình quản lý package Composer:
composer require laravel/pulse
Tiếp theo, bạn nên export ra các file cấu hình và migration Pulse bằng lệnh Artisan vendor:publish:
php artisan vendor:publish --provider="Laravel\Pulse\PulseServiceProvider"
Cuối cùng, bạn chạy lệnh migrate để tạo ra các bảng cần thiết để lưu trữ dữ liệu của Pulse:
php artisan migrate
Sau khi migration cơ sở dữ liệu của Pulse hoàn tất, bạn có thể truy cập vào bảng điều khiển của Pulse thông qua route /pulse.
[!NOTE] Nếu bạn không muốn lưu dữ liệu Pulse trong cơ sở dữ liệu chính của ứng dụng, bạn có thể chỉ định một kết nối cơ sở dữ liệu khác.
Nhiều tùy chọn cấu hình của Pulse có thể được kiểm soát bằng các biến môi trường. Để xem các tùy chọn có sẵn, đăng ký recorder mới hoặc cấu hình các tùy chọn nâng cao, bạn có thể export file cấu hình config/pulse.php:
php artisan vendor:publish --tag=pulse-config
Bảng điều khiển của Pulse có thể được truy cập thông qua đường dẫn /pulse. Mặc định, bạn chỉ có thể truy cập vào bảng điều khiển này trong môi trường local, vì vậy bạn sẽ cần cấu hình quyền cho môi trường production của bạn bằng cách tùy chỉnh authorization gate 'viewPulse'. Bạn có thể thực hiện việc này trong file app/Providers/AppServiceProvider.php của ứng dụng:
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();
});
// ...
}
Các card và layout của bảng điều khiển Pulse có thể được cấu hình bằng cách export ra các view. Các view sẽ được export vào resources/views/vendor/pulse/dashboard.blade.php:
php artisan vendor:publish --tag=pulse-dashboard
Bảng điều khiển của Pulse được tạo bởi Livewire và cho phép bạn tùy chỉnh các card và layout mà không cần phải xây dựng lại bất kỳ nội dung JavaScript nào.
Trong file này, component <x-pulse> chịu trách nhiệm hiển thị bảng điều khiển và cung cấp layout dưới dạng lưới cho các card. Nếu bạn muốn bảng điều khiển trải dài trên toàn bộ chiều rộng của màn hình, bạn có thể cung cấp thuộc tính full-width cho component:
<x-pulse full-width>
...
</x-pulse>
Mặc định, component <x-pulse> sẽ tạo dạng lưới 12 cột, nhưng bạn có thể tùy chỉnh hành động này bằng cách sử dụng thuộc tính cols:
<x-pulse cols="16">
...
</x-pulse>
Mỗi card sẽ chấp nhận thuộc tính cols và rows để kiểm soát khoảng cách và vị trí:
<livewire:pulse.usage cols="4" rows="2" />
Hầu hết các card cũng chấp nhận thuộc tính expand để hiển thị toàn bộ card thay vì phải scroll:
<livewire:pulse.slow-queries expand />
Đối với các card hiển thị thông tin về người dùng, chẳng hạn như card mức độ sử dụng application, Pulse sẽ chỉ ghi lại ID của người dùng. Khi bảng điều khiển được hiển thị, Pulse mới bắt đầu gọi các field name và email từ model Authenticatable của bạn và hiển thị ảnh đại diện bằng dịch vụ web Gravatar.
Bạn có thể tùy chỉnh các field và ảnh đại diện bằng cách gọi phương thức Pulse::user trong class App\Providers\AppServiceProvider của ứng dụng.
Phương thức user sẽ chấp nhận một closure nhận vào model Authenticatable để hiển thị và sẽ trả về một mảng chứa các thông tin name, extra và avatar của người dùng:
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,
]);
// ...
}
[!NOTE] Bạn có thể hoàn toàn tùy chỉnh cách người dùng được ghi lại và lấy ra bằng cách implement contract
Laravel\Pulse\Contracts\ResolvesUsersvà liên kết nó trong service container của Laravel.
Card <livewire:pulse.servers /> sẽ hiển thị mức độ sử dụng tài nguyên của tất cả các server đang chạy lệnh pulse:check. Vui lòng tham khảo tài liệu liên quan đến servers recorder để biết thêm thông tin về báo cáo tài nguyên hệ thống.
Nếu bạn thay thế một server trong cơ sở hạ tầng của bạn, bạn có thể muốn không hiển thị những server không hoạt động trong bảng điều khiển Pulse sau một khoảng thời gian nhất định. Bạn có thể thực hiện điều này bằng cách sử dụng thuộc tính ignore-after, thuộc tính này chấp nhận số giây mà sau đó các server không hoạt động sẽ bị xóa ra khỏi bảng điều khiển Pulse. Ngoài ra, bạn có thể cung cấp một chuỗi định dạng thời gian, chẳng hạn như 1 hour hoặc 3 days and 1 hour:
<livewire:pulse.servers ignore-after="3 hours" />
Card <livewire:pulse.usage /> sẽ hiển thị 10 người dùng đưa ra request nhiều nhất tới ứng dụng của bạn, gửi job và tình trạng request chậm.
Nếu bạn muốn xem tất cả các số liệu sử dụng trên vào trong cùng một màn hình, bạn có thể đưa nhiều card vào với thuộc tính type khác nhau:
<livewire:pulse.usage type="requests" />
<livewire:pulse.usage type="slow_requests" />
<livewire:pulse.usage type="jobs" />
Để tìm hiểu cách tùy chỉnh cách Pulse lấy và hiển thị thông tin người dùng, hãy tham khảo tài liệu của chúng tôi về lấy thông tin người dùng.
[!NOTE] Nếu ứng dụng của bạn nhận được nhiều request hoặc gửi nhiều job, bạn có thể muốn bật chế độ lấy mẫu. Xem tài liệu user requests recorder, user jobs recorder và slow jobs recorder để biết thêm thông tin chi tiết.
Card <livewire:pulse.exceptions /> sẽ hiển thị tần suất và mức độ xảy ra gần đây của các exception trong ứng dụng của bạn. Mặc định, các exception sẽ được nhóm theo class exception và vị trí xảy ra. Xem tài liệu exceptions recorder để biết thêm thông tin chi tiết.
Card <livewire:pulse.queues /> sẽ hiển thị thông lượng của các queue trong ứng dụng của bạn, bao gồm số lượng job queued, đang được xử lý, đã được xử lý, đã được release và không thành công. Xem tài liệu queues recorder để biết thêm thông tin chi tiết.
Card <livewire:pulse.slow-requests /> sẽ hiển thị các request đến ứng dụng của bạn mà chạy quá thời gian đã cấu hình, mặc định là 1000ms. Xem tài liệu slow requests recorder để biết thêm thông tin chi tiết.
Card <livewire:pulse.slow-jobs /> sẽ hiển thị các queued job trong ứng dụng của bạn mà chạy quá thời gian đã cấu hình, mặc định là 1000ms. Xem tài liệu slow jobs recorder để biết thêm thông tin chi tiết.
Card <livewire:pulse.slow-queries /> sẽ hiển thị các truy vấn cơ sở dữ liệu trong ứng dụng của bạn mà chạy quá thời gian đã cấu hình, mặc định là 1000ms.
Mặc định, các truy vấn chậm sẽ được nhóm dựa trên truy vấn SQL (không có ràng buộc) và vị trí xảy ra truy vấn, nhưng bạn có thể chọn không ghi lại vị trí của truy vấn nếu bạn chỉ muốn nhóm theo truy vấn SQL.
Nếu bạn gặp phải các vấn đề liên quan đến hiệu suất hiển thị highlight cho các truy vấn SQL quá lớn, bạn có thể tắt tính năng highlight này bằng cách thêm thuộc tính without-highlighting:
<livewire:pulse.slow-queries without-highlighting />
Xem tài liệu slow queries recorder để biết thêm thông tin chi tiết.
Card <livewire:pulse.slow-outgoing-requests /> sẽ hiển thị các request gửi đi từ ứng dụng được thực hiện bằng HTTP client của Laravel mà chạy quá thời gian đã cấu hình, mặc định là 1000ms.
Mặc định, các mục sẽ được nhóm theo URL. Tuy nhiên, bạn có thể muốn chuẩn hóa hoặc nhóm các request gửi đi tương tự nhau bằng biểu thức chính quy. Xem tài liệu slow outgoing requests recorder để biết thêm thông tin chi tiết.
Card <livewire:pulse.cache /> sẽ hiển thị số liệu thống kê về cache hit và cache miss cho ứng dụng của bạn, cả trên global và cho từng khóa riêng lẻ.
Mặc định, các mục sẽ được nhóm theo khóa. Tuy nhiên, bạn có thể muốn chuẩn hóa hoặc nhóm các khóa tương tự nhau bằng biểu thức chính quy. Xem tài liệu cache interactions recorder để biết thêm thông tin chi tiết.
Hầu hết các Pulse recorder sẽ tự động ghi lại các mục dựa trên các event framework được Laravel gửi. Tuy nhiên, servers recorder và một số card khác của bên thứ ba thì bạn cần phải thường xuyên lấy thông tin. Để sử dụng các card này, bạn phải chạy daemon pulse:check trên tất cả các server ứng dụng của bạn:
php artisan pulse:check
[!NOTE] Để duy trì process
pulse:checkchạy liên tục ở chế độ background, bạn nên sử dụng một trình giám sát process như Supervisor để đảm bảo lệnh này sẽ không bị dừng.
Vì lệnh pulse:check là một process chạy liên tục, nên nếu process đó không được khởi động lại, thì nó sẽ không thấy được sự thay đổi code của bạn. Bạn nên khởi động lại lệnh một cách bình thường bằng cách gọi lệnh pulse:restart trong quá trình deploy ứng dụng:
php artisan pulse:restart
[!NOTE] Pulse sử dụng cache để lưu trữ tín hiệu khởi động lại, do đó bạn nên kiểm tra cache driver đã được cấu hình đúng cho ứng dụng của bạn trước khi sử dụng chức năng này.
Recorder sẽ chịu trách nhiệm ghi lại các mục từ ứng dụng của bạn rồi ghi vào cơ sở dữ liệu Pulse. Recorder sẽ được đăng ký và cấu hình trong phần recorders của file cấu hình Pulse.
Recorder CacheInteractions ghi lại thông tin về các lần cache hit và cache miss xảy ra trong ứng dụng của bạn để hiển thị trên card Cache.
Bạn có thể tùy ý điều chỉnh tỷ lệ lấy mẫu và bỏ qua các key patterns.
Bạn cũng có thể cấu hình cách nhóm để các khóa tương tự nhau được nhóm thành một mục duy nhất. Ví dụ: bạn có thể muốn xóa ID ra khỏi các khóa đã lưu nếu cùng loại thông tin. Các nhóm được cấu hình bằng cách sử dụng biểu thức chính quy để "tìm và thay thế" các phần của khóa. Một ví dụ đã được thêm trong file cấu hình sau:
Recorders\CacheInteractions::class => [
// ...
'groups' => [
// '/:\d+/' => ':*',
],
],
Pattern nào đầu tiên mà khớp thì sẽ được sử dụng. Nếu không có pattern nào khớp, thì khóa sẽ được giữ nguyên.
Recorder Exceptions sẽ ghi lại thông tin về các exception xảy ra trong ứng dụng của bạn để hiển thị trên card Exceptions.
Bạn có thể tùy ý điều chỉnh tỷ lệ lấy mẫu và các pattern exception bị bỏ qua. Bạn cũng có thể cấu hình việc ghi lại vị trí phát sinh exception. Vị trí đã ghi lại sẽ được hiển thị trên bảng điều khiển Pulse, giúp bạn theo dõi nguồn gốc của exception; tuy nhiên, nếu cùng một exception xảy ra ở nhiều vị trí, nó sẽ xuất hiện nhiều lần cho mỗi vị trí đó.
Recorder Queues sẽ ghi lại thông tin về queue trong ứng dụng của bạn để hiển thị trên Queues.
Bạn có thể tùy ý điều chỉnh tỷ lệ lấy mẫu và các jobs pattern sẽ bị bỏ qua.
Recorder SlowJobs sẽ ghi lại thông tin về các slow job xảy ra trong ứng dụng của bạn để hiển thị trên card Slow Jobs.
Bạn có thể tùy ý điều chỉnh ngưỡng mà job sẽ được coi là slow job, tỷ lệ lấy mẫu, và các jobs pattern sẽ bị bỏ qua.
Bạn có thể có một số job mà bạn mong muốn sẽ mất nhiều thời gian hơn so với những job khác. Trong những trường hợp đó, bạn có thể cấu hình ngưỡng cho từng loại job:
Recorders\SlowJobs::class => [
// ...
'threshold' => [
'#^App\\Jobs\\GenerateYearlyReports$#' => 5000,
'default' => env('PULSE_SLOW_JOBS_THRESHOLD', 1000),
],
],
If no regular expression patterns match the job's classname, then the 'default' value will be used.
Recorder SlowOutgoingRequests sẽ ghi lại thông tin về các request HTTP gửi đi được thực hiện bằng HTTP client của Laravel mà chạy quá thời gian đã cấu hình để hiển thị trên card Slow Outgoing Requests.
Bạn có thể tùy ý điều chỉnh ngưỡng mà request gửi đi sẽ bị coi là chậm, tỷ lệ lấy mẫu và các pattern URL sẽ bị bỏ qua.
Bạn có thể có một số request gửi đi mà bạn mong muốn sẽ mất nhiều thời gian nhiều hơn so với những loại khác. Trong những trường hợp đó, bạn có thể cấu hình ngưỡng theo từng loại request:
Recorders\SlowOutgoingRequests::class => [
// ...
'threshold' => [
'#backup.zip$#' => 5000,
'default' => env('PULSE_SLOW_OUTGOING_REQUESTS_THRESHOLD', 1000),
],
],
Nếu không có pattern nào khớp với URL của request, thì giá trị 'default' sẽ được sử dụng.
Bạn cũng có thể cấu hình nhóm của URL để các URL tương tự nhau được nhóm thành một mục duy nhất. Ví dụ: bạn có thể muốn xóa ID ra khỏi đường dẫn URL hoặc chỉ nhóm theo tên miền. Các nhóm được cấu hình bằng cách sử dụng biểu thức chính quy để "tìm và thay thế" các phần của URL. Một số ví dụ được thêm vào trong file cấu hình sau:
Recorders\SlowOutgoingRequests::class => [
// ...
'groups' => [
// '#^https://api\.github\.com/repos/.*$#' => 'api.github.com/repos/*',
// '#^https?://([^/]*).*$#' => '\1',
// '#/\d+#' => '/*',
],
],
Pattern nào đầu tiên mà khớp thì sẽ được sử dụng. Nếu không có pattern nào khớp, thì URL sẽ được giữ nguyên.
Recorder SlowQueries sẽ ghi lại mọi truy vấn cơ sở dữ liệu trong ứng dụng của bạn mà chạy quá thời gian đã cấu hình để hiển thị trên card Slow Queries.
Bạn có thể tùy chọn điều chỉnh ngưỡng mà truy vấn sẽ bị coi là chậm, tỷ lệ lấy mẫu và các pattern truy vấn sẽ bị bỏ qua. Bạn cũng có thể cấu hình việc có nên ghi lại vị trí truy vấn hay không. Vị trí đã ghi lại sẽ được hiển thị trên bảng điều khiển Pulse, giúp bạn theo dõi nguồn gốc của truy vấn; tuy nhiên, nếu cùng một truy vấn được thực hiện ở nhiều vị trí khác nhau, nó sẽ xuất hiện nhiều lần cho mỗi vị trí đó.
Bạn có thể có một số loại truy vấn mà bạn mong muốn sẽ mất nhiều thời gian hơn so với những truy vấn khác. Trong những trường hợp đó, bạn có thể cấu hình ngưỡng theo từng truy vấn:
Recorders\SlowQueries::class => [
// ...
'threshold' => [
'#^insert into `yearly_reports`#' => 5000,
'default' => env('PULSE_SLOW_QUERIES_THRESHOLD', 1000),
],
],
Nếu không có pattern nào khớp với SQL của truy vấn, thì giá trị 'default' sẽ được sử dụng.
Recorder Requests sẽ ghi lại thông tin về các request được gửi đến ứng dụng của bạn để hiển thị trên card Slow Requests và card Application Usage.
Bạn có thể tùy ý điều chỉnh ngưỡng mà route sẽ bị coi là bị chậm, tỷ lệ lấy mẫu và các path sẽ bị bỏ qua.
Bạn có thể có một số request mà bạn mong muốn chạy sẽ mất nhiều thời gian hơn so với những request khác. Trong những trường hợp đó, bạn có thể cấu hình ngưỡng cho từng loại request:
Recorders\SlowRequests::class => [
// ...
'threshold' => [
'#^/admin/#' => 5000,
'default' => env('PULSE_SLOW_REQUESTS_THRESHOLD', 1000),
],
],
Nếu không có pattern nào khớp với URL của request, thì giá trị 'default' sẽ được sử dụng.
Recorder Servers sẽ ghi lại mức độ sử dụng CPU, bộ nhớ và kho lưu trữ của các server chạy cho ứng dụng của bạn để hiển thị trên card Servers. Recorder này yêu cầu lệnh pulse:check phải được chạy trên mỗi server mà bạn muốn giám sát.
Mỗi server phải có một tên duy nhất. Mặc định, Pulse sẽ sử dụng giá trị được trả về bởi hàm gethostname của PHP. Nếu bạn muốn tùy chỉnh, bạn có thể set biến môi trường PULSE_SERVER_NAME:
PULSE_SERVER_NAME=load-balancer
File cấu hình Pulse cũng cho phép bạn tùy chỉnh các thư mục sẽ được giám sát.
Recorder UserJobs sẽ ghi lại thông tin về user đang gửi job trong ứng dụng của bạn để hiển thị trên card Application Usage.
Bạn có thể tùy ý điều chỉnh tỷ lệ lấy mẫu và các job pattern sẽ bị bỏ qua.
Recorder UserRequests sẽ ghi lại thông tin về user đã gửi request đối với ứng dụng của bạn để hiển thị trên card Application Usage.
Bạn có thể tùy ý điều chỉnh tỷ lệ lấy mẫu và các URL pattern sẽ bị bỏ qua.
Như chúng ta đã thấy, nhiều recorder cung cấp nhiều khả năng, thông qua cấu hình, và "bỏ qua" các mục dựa trên giá trị của chúng, chẳng hạn như URL của request. Tuy nhiên, thỉnh thoảng việc lọc các record dựa trên các yếu tố khác, chẳng hạn ví dụ như người dùng hiện tại đang được xác thực, có thể hữu ích. Để lọc các record này, bạn có thể truyền vào một closure vào phương thức filter của Pulse. Thông thường, phương thức filter nên được gọi trong phương thức boot của AppServiceProvider trong ứng dụng của bạn:
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 được thiết kế để tích hợp vào một ứng dụng hiện có mà không yêu cầu thêm bất kỳ cơ sở hạ tầng nào. Tuy nhiên, đối với các ứng dụng có hiệu suất lưu lượng truy cập cao, có một số cách để loại bỏ bất kỳ tác động nào mà Pulse có thể gây ra đối với hiệu suất của ứng dụng của bạn.
Đối với các ứng dụng có lưu lượng truy cập cao, bạn có thể muốn sử dụng kết nối cơ sở dữ liệu khác cho Pulse để tránh làm ảnh hưởng đến cơ sở dữ liệu ứng dụng của bạn.
Bạn có thể tùy chỉnh kết nối cơ sở dữ liệu được Pulse sử dụng bằng cách thiết lập biến môi trường PULSE_DB_CONNECTION.
PULSE_DB_CONNECTION=pulse
[!WARNING] Tích hợp Redis yêu cầu Redis 6.2 trở lên và
phpredishoặcpredislà Redis client driver phải được cấu hình sẵn trong ứng dụng.
Mặc định, Pulse sẽ lưu các mục trực tiếp vào configured database connection sau khi HTTP response được gửi về client hoặc một job đã được xử lý xong; tuy nhiên, bạn có thể sử dụng driver Redis của Pulse để gửi các mục đến stream Redis. Tính năng này có thể được kích hoạt bằng cách cấu hình biến môi trường PULSE_INGEST_DRIVER:
PULSE_INGEST_DRIVER=redis
Mặc định, Pulse sẽ sử dụng kết nối Redis mặc định của bạn, nhưng bạn có thể tùy chỉnh kết nối này thông qua biến môi trường PULSE_REDIS_CONNECTION:
PULSE_REDIS_CONNECTION=pulse
[!WARNING] Khi sử dụng driver Redis ingest, bản cài đặt Pulse của bạn phải luôn sử dụng một kết nối Redis khác, khác với kết nối Redis của queue, nếu có.
Khi sử dụng Redis, bạn có thể sẽ cần chạy lệnh pulse:work để theo dõi stream và di chuyển các mục từ Redis vào các bảng cơ sở dữ liệu của Pulse.
php artisan pulse:work
[!NOTE] Để duy trì process
pulse:workchạy liên tục ở background, bạn nên sử dụng trình giám sát process như Supervisor để đảm bảo process Pulse sẽ không bị ngừng chạy.
Vì lệnh pulse:work là một process chạy liên tục, nên nếu process đó không được khởi động lại, thì nó sẽ không thấy được sự thay đổi code của bạn. Bạn nên khởi động lại lệnh một cách bình thường bằng cách gọi lệnh pulse:restart trong quá trình deploy ứng dụng:
php artisan pulse:restart
[!NOTE] Pulse sử dụng cache để lưu trữ tín hiệu khởi động lại, do đó bạn nên kiểm tra cache driver đã được cấu hình đúng cho ứng dụng của bạn trước khi sử dụng chức năng này.
Mặc định, Pulse sẽ ghi lại mọi event liên quan xảy ra trong ứng dụng của bạn. Đối với những ứng dụng có lưu lượng truy cập cao, điều này có thể dẫn đến việc cần tổng hợp hàng triệu row cơ sở dữ liệu trong bảng điều khiển, đặc biệt là trong thời gian dài.
Thay vào đó, bạn có thể chọn bật "lấy mẫu" trên một số recorder dữ liệu Pulse. Ví dụ: set tỉ lệ lấy mẫu là 0.1 trên recorder User Requests thì sẽ đồng nghĩa với việc bạn chỉ ghi lại khoảng 10% các request đến ứng dụng của bạn. Trong bảng điều khiển, các giá trị sẽ được tính theo tỉ lệ trên và thêm tiền tố ~ để biểu thị rằng chúng là giá trị gần đúng.
Nhìn chung, bạn càng có nhiều mục cho một số liệu cụ thể thì bạn càng có thể set một tỉ lệ lấy mẫu thấp mà không làm giảm quá nhiều độ chính xác.
Pulse sẽ tự động cắt bớt các mục đã lưu khi chúng không nằm trong bảng điều khiển. Việc cắt bớt diễn ra khi thu thập dữ liệu bằng hệ thống ngẫu nhiên có thể được tùy chỉnh trong file cấu hình của Pulse.
Nếu xảy ra exception khi thu thập dữ liệu Pulse, chẳng hạn như không thể kết nối đến cơ sở dữ liệu, Pulse sẽ âm thầm ngừng hoạt động để tránh ảnh hưởng đến ứng dụng của bạn.
Nếu bạn muốn tùy chỉnh cách xử lý các exception này, bạn có thể cung cấp một closure cho phương thức 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 cho phép bạn tự xây dựng các card tùy chỉnh để hiển thị dữ liệu phù hợp với nhu cầu cụ thể của ứng dụng của bạn. Pulse sử dụng Livewire, vì vậy bạn có thể muốn xem lại tài liệu hướng dẫn trước khi xây dựng card tùy chỉnh đầu tiên của bạn.
Việc tạo một card tùy chỉnh trong Laravel Pulse sẽ bắt đầu bằng việc extend component Livewire Card và định nghĩa một view tương ứng:
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');
}
}
Khi sử dụng tính năng lazy loading của Livewire, component Card sẽ tự động cung cấp một biến cho các thuộc tính cols và rows được truyền cho component của bạn.
Khi viết view của card Pulse, bạn có thể tận dụng các component Blade của Pulse để có một giao diện nhất quán hơn:
<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>
Các biến $cols, $rows, $class và $expand nên được truyền vào các component Blade tương ứng để có thể tùy chỉnh layout card từ view bảng điều khiển. Bạn cũng có thể muốn thêm thuộc tính wire:poll.5s="" vào view để card tự động cập nhật.
Sau khi bạn đã định nghĩa xong component và template Livewire của bạn, thì card có thể được thêm vào view của bảng điều khiển:
<x-pulse>
...
<livewire:pulse.top-sellers cols="4" />
</x-pulse>
[!NOTE] Nếu card của bạn được có chứa trong một package, bạn sẽ cần phải đăng ký component với Livewire bằng phương thức
Livewire::component.
Nếu card của bạn cần thêm style css ngoài các class và component có trong Pulse, có một số tùy chọn để thêm CSS tùy chỉnh cho card của bạn.
Nếu card tùy chỉnh của bạn nằm trong source code của ứng dụng và bạn đang sử dụng tích hợp Vite của Laravel, bạn có thể cập nhật file vite.config.js để chứa thêm file CSS chuyên dụng cho card của bạn:
laravel({
input: [
'resources/css/pulse/top-sellers.css',
// ...
],
}),
Sau đó, bạn có thể sử dụng lệnh Blade @vite trong view bảng điều khiển của bạn, chỉ định file CSS cho card của bạn:
<x-pulse>
@vite('resources/css/pulse/top-sellers.css')
...
</x-pulse>
Đối với các trường hợp sử dụng khác, bao gồm các card Pulse có trong một package, bạn có thể hướng dẫn Pulse load các thêm các stylesheet bằng cách định nghĩa phương thức css trên component Livewire của bạn để trả về đường dẫn đến file CSS của bạn:
class TopSellers extends Card
{
// ...
protected function css()
{
return __DIR__.'/../../dist/top-sellers.css';
}
}
Khi card này đã được thêm vào bảng điều khiển, Pulse sẽ tự động đưa nội dung của file này vào trong tag <style> nên bạn sẽ không cần phải xuất file css đó ra lại thư mục public.
Khi sử dụng Tailwind CSS, bạn nên tạo ra một file CSS entrypoint. Ví dụ sau đây sẽ loại bỏ style cơ bản Preflight của Tailwind vì chúng đã có sẵn trong Pulse, đồng thời giới hạn phạm vi của Tailwind bằng CSS selector để tránh xung đột với các class Tailwind của Pulse:
@import "tailwindcss/theme.css";
@custom-variant dark (&:where(.dark, .dark *));
@source "./../../views/livewire/pulse/top-sellers.blade.php";
@theme {
/* ... */
}
#top-sellers {
@import "tailwindcss/utilities.css" source(none);
}
Bạn cũng sẽ cần phải thêm các thuộc tính id hoặc class vào trong view card của bạn để khớp với bộ CSS selector file entrypoint của bạn:
<x-pulse::card id="top-sellers" :cols="$cols" :rows="$rows" class="$class">
...
</x-pulse::card>
Card tùy chỉnh có thể được lấy ra và hiển thị dữ liệu từ bất kỳ đâu; tuy nhiên, bạn có thể muốn tận dụng hệ thống ghi và tổng hợp dữ liệu mạnh mẽ và hiệu quả của Pulse.
Pulse cho phép bạn ghi lại "các mục" bằng phương thức Pulse::record:
use Laravel\Pulse\Facades\Pulse;
Pulse::record('user_sale', $user->id, $sale->amount)
->sum()
->count();
Tham số đầu tiên được cung cấp cho phương thức record là type cho mục mà bạn đang muốn ghi vào, trong khi tham số thứ hai là key xác định cách dữ liệu tổng hợp sẽ được nhóm lại. Đối với hầu hết các phương thức tổng hợp, bạn cũng cần chỉ định thêm một value để tổng hợp. Trong ví dụ trên, giá trị được tổng hợp là $sale->amount. Sau đó, bạn có thể gọi một hoặc nhiều phương thức tổng hợp (chẳng hạn như sum) để Pulse có thể thu thập các giá trị đã tổng hợp trước đó vào một "bucket" để tính ra hiệu quả sau này.
Các phương thức tổng hợp có sẵn:
avgcountmaxminsum[!NOTE] Khi xây dựng card package ghi lại ID người dùng hiện tại đang được xác thực, bạn nên sử dụng phương thức
Pulse::resolveAuthenticatedUserId(), phương thức này sẽ gọi mọi tùy chỉnh user resolver được thực hiện cho ứng dụng.
Khi extend component Card Livewire của Pulse, bạn có thể sử dụng phương thức aggregate để lấy ra các dữ liệu tổng hợp cho các khoảng thời gian đang được xem trong bảng điều khiển:
class TopSellers extends Card
{
public function render()
{
return view('livewire.pulse.top-sellers', [
'topSellers' => $this->aggregate('user_sale', ['sum', 'count'])
]);
}
}
Phương thức aggregate sẽ trả về một collection các đối tượng stdClass của PHP. Mỗi đối tượng sẽ chứa thuộc tính key đã được ghi lại trước đó cùng với các khóa cho mỗi số liệu được yêu cầu:
@foreach ($topSellers as $seller)
{{ $seller->key }}
{{ $seller->sum }}
{{ $seller->count }}
@endforeach
Pulse chủ yếu sẽ lấy dữ liệu từ các bucket được tổng hợp trước đó; do đó, các bucket được chỉ định phải đã được thu thập trước bằng phương thức Pulse::record. Bucket tổng hợp trước đó thường sẽ nằm ngoài khoảng thời gian bạn yêu cầu, do đó Pulse sẽ tổng hợp các mục đã tổng hợp trước đó để lấp đầy khoảng trống đó và đưa ra giá trị chính xác cho toàn bộ khoảng thời gian, mà không cần phải tổng hợp toàn bộ khoảng thời gian trên mỗi request.
Bạn cũng có thể lấy ra tổng giá trị cho một loại nhất định bằng phương thức aggregateTotal. Ví dụ: phương thức sau sẽ lấy ra tổng doanh số của tất cả người dùng thay vì nhóm chúng theo người dùng.
$total = $this->aggregateTotal('user_sale', 'sum');
Khi làm việc với các tổng hợp ghi lại ID người dùng làm khóa, bạn có thể resolve ra các khóa cho bản ghi người dùng bằng phương thức 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,
])
]);
Phương thức find sẽ trả về một đối tượng chứa các khóa name, extra và avatar, mà bạn có thể truyền trực tiếp đến component Blade <x-pulse::user-card>:
<x-pulse::user-card :user="{{ $seller->user }}" :stats="{{ $seller->sum }}" />
Tác giả của package có thể muốn cung cấp các recorder class để cho phép người dùng cấu hình việc thu thập dữ liệu của mình.
Các recorder được đăng ký trong phần recorders của file cấu hình config/pulse.php của ứng dụng:
[
// ...
'recorders' => [
Acme\Recorders\Deployments::class => [
// ...
],
// ...
],
]
Recorder có thể lắng nghe các event bằng cách chỉ định thuộc tính $listen. Pulse sẽ tự động đăng ký trình nghe này và gọi phương thức record của recorder:
<?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(
// ...
);
}
}
entry