Laravel Pulse

업데이트됨

번역일: 2026년 7월 2일

이 페이지는 원문이 업데이트되어 번역이 갱신되었습니다.

원문 수정
2026년 6월 20일
번역 갱신
2026년 7월 2일

Laravel Pulse

소개

Laravel Pulse는 애플리케이션의 성능과 사용 현황을 한눈에 파악할 수 있는 실시간 모니터링 도구입니다. Pulse를 사용하면 느린 Job이나 엔드포인트, 가장 활발한 사용자, 그 밖의 다양한 지표를 손쉽게 추적할 수 있습니다.

개별 이벤트에 대한 심층 디버깅이 필요하다면 Laravel Telescope를 함께 활용하세요.

설치

WARNING

Pulse의 기본 스토리지 드라이버는 MySQL, MariaDB, PostgreSQL 데이터베이스를 필요로 합니다. 다른 데이터베이스 엔진을 사용하는 경우 Pulse 데이터 전용으로 별도의 MySQL, MariaDB, 또는 PostgreSQL 데이터베이스를 준비해야 합니다.

Composer를 통해 Pulse를 설치합니다:

composer require laravel/pulse

설치 후 vendor:publish Artisan 명령으로 마이그레이션 파일과 설정 파일을 퍼블리시합니다:

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

이어서 마이그레이션을 실행해 Pulse 데이터를 저장할 테이블을 생성합니다:

php artisan migrate

마이그레이션이 완료되면 /pulse 경로에서 Pulse 대시보드에 접속할 수 있습니다.

설정

퍼블리시된 config/pulse.php 파일에서 Pulse의 동작 방식을 세부적으로 조정할 수 있습니다. 각 옵션에는 설명이 포함되어 있으니 꼼꼼히 살펴보시기 바랍니다.

대시보드

접근 권한

Pulse 대시보드는 /pulse 경로로 접근할 수 있습니다. 기본적으로 local 환경에서만 접근이 허용되므로, 운영 환경에서는 App\Providers\AppServiceProviderboot 메서드에서 Pulse::auth 게이트를 커스터마이징해 접근 권한을 설정해야 합니다:

use App\Models\User; use Illuminate\Support\Facades\Gate; use Laravel\Pulse\Facades\Pulse; /** * 애플리케이션 서비스를 부트스트랩합니다. */ public function boot(): void { Pulse::auth(function (Request $request) { // 대시보드에 접근할 수 있는 사용자 조건을 여기에 작성하세요. return $request->user()->isAdmin(); }); // ... }

auth 게이트가 접근을 거부하면 자동으로 403 응답이 반환되며, 로그인 페이지로 리다이렉트되지 않습니다.

커스터마이징

대시보드 레이아웃과 카드 구성은 대시보드 뷰를 퍼블리시해서 수정할 수 있습니다. 퍼블리시된 뷰 파일은 resources/views/vendor/pulse/dashboard.blade.php에 위치합니다:

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

대시보드는 Livewire로 구동되며, JavaScript를 다시 빌드하지 않고도 카드와 레이아웃을 자유롭게 변경할 수 있습니다.

이 파일에서 $component 변수는 Livewire의 <livewire:pulse.dashboard> 컴포넌트를 가리키며, cols, rows, grayscale 같은 옵션을 통해 레이아웃을 조정합니다:

<x-pulse> <livewire:pulse.servers cols="full" /> <livewire:pulse.usage cols="4" rows="2" /> <livewire:pulse.queues cols="4" /> <livewire:pulse.cache cols="4" /> <livewire:pulse.slow-requests cols="8" rows="2" /> <livewire:pulse.slow-queries cols="8" rows="2" /> <livewire:pulse.slow-outgoing-requests cols="8" rows="2" /> <livewire:pulse.slow-jobs cols="8" rows="2" /> </x-pulse>

사용자 조회

"Application Usage" 카드처럼 사용자 정보를 표시하는 카드의 경우, Pulse는 사용자 ID만 기록합니다. 대시보드를 렌더링할 때 Pulse는 기본 Authenticatable 모델에서 nameemail 필드를 조회해 Gravatar 웹 서비스를 통해 아바타를 표시합니다.

이 동작을 변경하려면 App\Providers\AppServiceProvider에서 Pulse::user 메서드로 콜백을 등록하세요:

use Laravel\Pulse\Facades\Pulse; /** * 애플리케이션 서비스를 부트스트랩합니다. */ public function boot(): void { Pulse::user(function ($user) { return [ 'name' => $user->name, 'extra' => $user->email, 'avatar' => $user->profile_photo_url, ]; }); // ... }

NOTE

인증된 사용자를 캡처하고 조회하는 방식은 Laravel\Pulse\Contracts\ResolvesUsers 계약(contract)을 구현하고 Laravel의 서비스 컨테이너에 바인딩하는 것으로 완전히 커스터마이징할 수 있습니다.

카드

서버 (Servers)

<livewire:pulse.servers /> 카드는 pulse:check 명령을 실행 중인 모든 서버의 시스템 리소스 사용량을 표시합니다. 시스템 리소스 리포팅에 대한 자세한 내용은 서버 레코더 문서를 참고하세요.

인프라에서 서버를 교체하는 경우, 일정 기간이 지나면 비활성 서버를 대시보드에서 더 이상 표시하지 않도록 숨길 수 있습니다. ignore-after prop을 사용하면 되며, 값은 비활성 서버를 숨길 시간(초)으로 지정합니다. 또는 1 hour, 3 days and 1 hour처럼 사람이 읽기 쉬운 상대적 시간 형식도 사용할 수 있습니다:

<livewire:pulse.servers ignore-after="3 hours" />

애플리케이션 사용량 (Application Usage)

<livewire:pulse.usage /> 카드는 애플리케이션에 요청을 보내거나, Job을 디스패치하거나, 응답 지연을 경험하는 상위 10명의 사용자를 보여줍니다.

모든 사용량 지표를 화면에 동시에 표시하려면 카드를 여러 번 포함하고 type 속성으로 구분하면 됩니다:

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

Pulse가 사용자 정보를 조회하고 표시하는 방법을 커스터마이징하는 방법은 사용자 조회 문서를 참고하세요.

NOTE

애플리케이션에 요청이 많거나 Job이 자주 디스패치되는 경우 샘플링을 활성화하는 것이 좋습니다. 자세한 내용은 사용자 요청 레코더, 사용자 Job 레코더 문서를 참고하세요.

예외 (Exceptions)

<livewire:pulse.exceptions /> 카드는 애플리케이션에서 발생하는 예외의 빈도와 최근 발생 시점을 보여줍니다. 기본적으로 예외는 예외 클래스와 발생 위치를 기준으로 그룹화됩니다. 자세한 내용은 예외 레코더 문서를 참고하세요.

큐 (Queues)

<livewire:pulse.queues /> 카드는 애플리케이션 큐의 처리량을 보여주며, 큐에 쌓인 Job 수, 처리 중인 Job 수, 완료된 Job 수, 해제(released)된 Job 수, 실패한 Job 수를 확인할 수 있습니다. 자세한 내용은 레코더 문서를 참고하세요.

느린 요청 (Slow Requests)

<livewire:pulse.slow-requests /> 카드는 설정된 임계값(기본값: 1,000ms)을 초과하는 애플리케이션 요청을 보여줍니다. 자세한 내용은 느린 요청 레코더 문서를 참고하세요.

느린 Job (Slow Jobs)

<livewire:pulse.slow-jobs /> 카드는 설정된 임계값(기본값: 1,000ms)을 초과하는 큐 Job을 보여줍니다. 자세한 내용은 느린 Job 레코더 문서를 참고하세요.

느린 쿼리 (Slow Queries)

<livewire:pulse.slow-queries /> 카드는 설정된 임계값(기본값: 1,000ms)을 초과하는 데이터베이스 쿼리를 보여줍니다.

기본적으로 느린 쿼리는 SQL 구문과 발생 위치를 기준으로 그룹화되지만, SQL 구문만으로 그룹화하고 싶다면 발생 위치 캡처를 비활성화할 수 있습니다. 자세한 내용은 느린 쿼리 레코더 문서를 참고하세요.

느린 외부 요청 (Slow Outgoing Requests)

<livewire:pulse.slow-outgoing-requests /> 카드는 Laravel의 HTTP 클라이언트를 통해 발생한 외부 HTTP 요청 중 설정된 임계값(기본값: 1,000ms)을 초과하는 것들을 보여줍니다.

기본적으로 요청은 전체 URL을 기준으로 그룹화됩니다. 필요에 따라 정규식을 사용해 유사한 URL을 정규화하거나 그룹화할 수 있습니다. 자세한 내용은 느린 외부 요청 레코더 문서를 참고하세요.

캐시 (Cache)

<livewire:pulse.cache /> 카드는 애플리케이션의 캐시 히트/미스 통계를 전체 및 개별 키 단위로 보여줍니다. 자세한 내용은 캐시 인터랙션 레코더 문서를 참고하세요.

데이터 수집

대부분의 Pulse 레코더는 Laravel이 발행하는 프레임워크 이벤트를 기반으로 자동으로 데이터를 수집합니다. 별도의 설정 없이도 바로 동작합니다. 서버 레코더를 사용한다면 각 서버에서 pulse:check 명령을 실행해야 합니다:

php artisan pulse:check

NOTE

운영 환경에서 pulse:check 프로세스를 항상 실행 상태로 유지하려면 Supervisor 같은 프로세스 모니터를 사용하세요.

pulse:check 명령은 장기 실행 프로세스이기 때문에, 재시작하지 않으면 코드 변경 사항을 반영하지 못합니다. 애플리케이션 배포 시 pulse:restart 명령으로 프로세스를 정상적으로 재시작할 수 있습니다:

php artisan pulse:restart

NOTE

Pulse는 재시작 신호를 저장하기 위해 캐시를 사용합니다. 이 기능을 사용하기 전에 캐시 드라이버가 올바르게 설정되어 있는지 확인하세요.

레코더

레코더는 애플리케이션에서 발생하는 데이터를 수집해 Pulse 데이터베이스에 기록하는 역할을 합니다. 어떤 레코더를 활성화할지는 config/pulse.phprecorders 섹션에서 설정합니다.

캐시 인터랙션 (Cache Interactions)

CacheInteractions 레코더는 애플리케이션의 캐시 히트와 미스 정보를 수집해 캐시 카드에 표시합니다.

샘플링 비율과 무시할 키 패턴을 설정할 수 있습니다.

또한 유사한 캐시 키를 하나의 항목으로 그룹화할 수 있습니다. 예를 들어 동일한 유형의 정보를 캐싱하는 키에서 고유 ID를 제거하고 싶을 때 유용합니다. 그룹은 PHP 정규식을 사용해 키의 일부를 *로 치환하는 방식으로 설정합니다. 설정 파일에 예시가 포함되어 있습니다:

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

처음 매칭되는 패턴이 사용됩니다. 아무 패턴도 매칭되지 않으면 키는 그대로 캡처됩니다.

예외 (Exceptions)

Exceptions 레코더는 애플리케이션에서 발생하는 보고 가능한 예외 정보를 수집해 예외 카드에 표시합니다.

샘플링 비율과 무시할 예외 패턴을 설정할 수 있습니다. 예외가 발생한 위치를 함께 캡처할지 여부도 설정 가능합니다. 캡처된 발생 위치는 Pulse 대시보드에 표시되어 예외 원인을 추적하는 데 도움을 줍니다. 단, 동일한 예외가 여러 곳에서 발생하면 각 위치마다 별도 항목으로 표시됩니다.

큐 (Queues)

Queues 레코더는 애플리케이션 큐의 정보를 수집해 카드에 표시합니다.

샘플링 비율과 무시할 Job 패턴을 설정할 수 있습니다.

느린 Job (Slow Jobs)

SlowJobs 레코더는 애플리케이션에서 임계값을 초과해 느리게 실행되는 큐 Job 정보를 수집해 느린 Job 카드에 표시합니다.

느린 Job 임계값, 샘플링 비율, 무시할 Job 패턴을 설정할 수 있습니다.

처리 시간이 특히 긴 특정 Job에 대해 임계값을 별도로 지정하고 싶을 수도 있습니다. 이런 경우 Job별 임계값을 설정할 수 있습니다:

Recorders\SlowJobs::class => [ // ... 'threshold' => [ '#^App\Jobs\GenerateReport$#' => 5000, 'default' => env('PULSE_SLOW_JOBS_THRESHOLD', 1000), ], ],

정규식 패턴이 Job 클래스명과 일치하지 않으면 'default' 값이 사용됩니다.

느린 외부 요청 (Slow Outgoing Requests)

SlowOutgoingRequests 레코더는 Laravel의 HTTP 클라이언트로 발생한 외부 HTTP 요청 중 임계값을 초과하는 것들을 수집해 느린 외부 요청 카드에 표시합니다.

느린 외부 요청 임계값, 샘플링 비율, 무시할 URL 패턴을 설정할 수 있습니다.

응답 시간이 특히 긴 특정 URL에 대해 임계값을 별도로 지정할 수도 있습니다:

Recorders\SlowOutgoingRequests::class => [ // ... 'threshold' => [ '#backup.example.com#' => 5000, 'default' => env('PULSE_SLOW_OUTGOING_REQUESTS_THRESHOLD', 1000), ], ],

정규식 패턴이 URL과 일치하지 않으면 'default' 값이 사용됩니다.

URL을 그룹화해 유사한 URL을 하나의 항목으로 묶을 수도 있습니다. 예를 들어, URL 경로에서 고유 ID를 제거하거나 도메인별로 그룹화할 수 있습니다. 그룹은 PHP 정규식을 사용해 URL의 일부를 *로 치환하는 방식으로 설정합니다. 설정 파일에 예시가 포함되어 있습니다:

Recorders\SlowOutgoingRequests::class => [ // ... 'groups' => [ // '#^https://api\.example\.com/\d+$#' => 'https://api.example.com/*', // '#^https://api\.example\.com/users/\d+/orders$#' => 'https://api.example.com/users/*/orders', // '#^https://api\.example\.com/.*$#' => 'https://api.example.com/*', ], ],

처음 매칭되는 패턴이 사용됩니다. 아무 패턴도 매칭되지 않으면 URL은 그대로 캡처됩니다.

느린 쿼리 (Slow Queries)

SlowQueries 레코더는 임계값을 초과하는 데이터베이스 쿼리를 수집해 느린 쿼리 카드에 표시합니다.

느린 쿼리 임계값, 샘플링 비율, 무시할 쿼리 패턴을 설정할 수 있으며, 쿼리 발생 위치 캡처 여부도 선택할 수 있습니다. 발생 위치를 캡처하면 같은 SQL이라도 호출 위치에 따라 별도 항목으로 표시되어 추적이 용이해집니다. 단, 위치 추적이 필요 없다면 비활성화해 동일한 쿼리를 하나의 항목으로 그룹화할 수 있습니다.

실행 시간이 특히 긴 특정 쿼리에 대해 임계값을 별도로 지정할 수도 있습니다:

Recorders\SlowQueries::class => [ // ... 'threshold' => [ '#^select \* from `users`$#i' => 2000, 'default' => env('PULSE_SLOW_QUERIES_THRESHOLD', 1000), ], ],

정규식 패턴이 SQL 구문과 일치하지 않으면 'default' 값이 사용됩니다.

느린 요청 (Slow Requests)

SlowRequests 레코더는 임계값을 초과하는 애플리케이션 요청을 수집해 느린 요청 카드에 표시합니다.

느린 요청 임계값, 샘플링 비율, 무시할 라우트 패턴을 설정할 수 있습니다.

응답 시간이 특히 긴 특정 URL에 대해 임계값을 별도로 지정할 수도 있습니다:

Recorders\SlowRequests::class => [ // ... 'threshold' => [ '#^/admin/#' => 5000, 'default' => env('PULSE_SLOW_REQUESTS_THRESHOLD', 1000), ], ],

정규식 패턴이 URL과 일치하지 않으면 'default' 값이 사용됩니다.

서버 (Servers)

Servers 레코더는 CPU, 메모리, 디스크 사용량을 수집해 서버 카드에 표시합니다. 이 레코더를 사용하려면 모니터링할 각 서버에서 pulse:check 명령을 실행해야 합니다.

각 리포팅 서버에는 고유한 이름이 있어야 합니다. 기본적으로 PHP의 gethostname() 함수 반환값이 사용됩니다. 이름을 직접 지정하려면 PULSE_SERVER_NAME 환경 변수를 설정하세요:

PULSE_SERVER_NAME=web-1

Pulse 설정 파일에서 모니터링할 디렉토리도 지정할 수 있습니다.

사용자 Job (User Jobs)

UserJobs 레코더는 애플리케이션에서 Job을 디스패치하는 사용자 정보를 수집해 애플리케이션 사용량 카드에 표시합니다.

샘플링 비율과 무시할 Job 패턴을 설정할 수 있습니다.

사용자 요청 (User Requests)

UserRequests 레코더는 애플리케이션에 요청을 보내는 사용자 정보를 수집해 애플리케이션 사용량 카드에 표시합니다.

샘플링 비율과 무시할 URL 패턴을 설정할 수 있습니다.

필터링

앞서 살펴본 것처럼, 각 레코더는 설정을 통해 특정 값(URL, Job 클래스명 등)을 기준으로 데이터를 무시할 수 있습니다. 그러나 때로는 현재 인증된 사용자를 기준으로 특정 요청을 제외하고 싶을 수 있습니다. 이런 경우 Pulse::filter 메서드에 콜백을 등록해 요청을 필터링할 수 있습니다.

filter 콜백의 반환값이 false이면 해당 항목은 기록되지 않습니다. 아래 예시처럼 AppServiceProviderboot 메서드에 등록하면 됩니다:

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 데이터가 애플리케이션 데이터베이스에 영향을 주지 않습니다.

config/pulse.php에서 storage.database.connection 옵션으로 Pulse가 사용할 데이터베이스 연결을 지정할 수 있습니다. 또는 PULSE_DB_CONNECTION 환경 변수로 설정할 수도 있습니다:

PULSE_DB_CONNECTION=pulse

Redis 인제스트

WARNING

Redis 인제스트를 사용하려면 Redis 6.2 이상과 phpredis 또는 predis가 애플리케이션의 Redis 클라이언트 드라이버로 설정되어 있어야 합니다.

기본적으로 Pulse는 HTTP 응답이 클라이언트에 전송되거나 Job이 처리된 후 수집된 데이터를 직접 설정된 데이터베이스 연결에 저장합니다. 그러나 Pulse의 Redis 인제스트 드라이버를 사용하면 수집된 데이터를 Redis 스트림으로 먼저 전송할 수 있습니다. 이 경우 pulse:work Artisan 명령이 Redis 스트림에서 데이터를 읽어 Pulse 데이터베이스 테이블에 저장합니다.

Redis 인제스트를 활성화하려면 PULSE_INGEST_DRIVER 환경 변수를 설정하세요:

PULSE_INGEST_DRIVER=redis

기본값이 아닌 별도의 Redis 연결을 사용하려면 PULSE_REDIS_CONNECTION 환경 변수를 설정합니다:

PULSE_REDIS_CONNECTION=pulse

Redis 인제스트를 활성화한 후 pulse:work 명령을 실행해 데이터 처리를 시작합니다:

php artisan pulse:work

NOTE

pulse:work 프로세스를 운영 환경에서 항상 실행 상태로 유지하려면 Supervisor 같은 프로세스 모니터를 사용하세요.

pulse:work 역시 장기 실행 프로세스이므로, 재시작하지 않으면 코드 변경 사항을 반영하지 못합니다. 배포 시 pulse:restart 명령으로 정상적으로 재시작하세요:

php artisan pulse:restart

NOTE

Pulse는 재시작 신호를 저장하기 위해 캐시를 사용합니다. 이 기능을 사용하기 전에 캐시 드라이버가 올바르게 설정되어 있는지 확인하세요.

샘플링

기본적으로 Pulse는 애플리케이션에서 발생하는 모든 관련 이벤트를 빠짐없이 캡처합니다. 트래픽이 많은 애플리케이션에서는 대시보드에서 수백만 개의 데이터 행을 집계해야 할 수 있으며, 특히 기간이 긴 경우 더욱 부담이 됩니다.

이런 경우 특정 Pulse 데이터 레코더에 샘플링을 적용할 수 있습니다. 예를 들어, 사용자 요청 레코더의 샘플 비율을 0.1로 설정하면 전체 요청의 약 10%만 기록합니다. 대시보드에서는 샘플링된 데이터를 기반으로 수치를 근사치로 스케일업해 표시하며, 앞에 ~ 기호가 붙어 근삿값임을 나타냅니다.

일반적으로 특정 지표에 대한 항목이 충분히 많을수록 샘플링 비율을 낮춰도 정확도에 큰 영향을 주지 않습니다.

데이터 정리

Pulse는 대시보드 표시 범위를 벗어난 오래된 데이터를 자동으로 정리합니다. 정리는 데이터를 인제스트할 때 복권 방식(lottery system)으로 수행되며, 이 동작은 Pulse 설정 파일에서 조정할 수 있습니다.

Pulse 예외 처리

데이터베이스 연결 불가 등의 이유로 Pulse 데이터 수집 과정에서 예외가 발생하더라도, Pulse는 애플리케이션에 영향을 주지 않도록 조용히 처리합니다.

이러한 예외가 어떻게 처리되는지 직접 제어하고 싶다면 handleExceptionsUsing 메서드에 콜백을 등록하세요:

use Laravel\Pulse\Facades\Pulse; use Illuminate\Support\Facades\Log; Pulse::handleExceptionsUsing(function ($e) { Log::debug('Pulse에서 예외가 발생했습니다', [ 'message' => $e->getMessage(), 'stack' => $e->getTraceAsString(), ]); });

커스텀 카드

Pulse에서는 애플리케이션의 특정 요구사항에 맞는 데이터를 표시하는 커스텀 카드를 직접 만들 수 있습니다. Pulse는 Livewire를 기반으로 동작하므로, 첫 번째 커스텀 카드를 만들기 전에 Livewire 문서를 먼저 살펴보는 것이 좋습니다.

카드 컴포넌트

Laravel Pulse에서 커스텀 카드를 만들려면 먼저 기본 Card Livewire 컴포넌트를 확장하고, 해당 뷰를 정의해야 합니다.

스타일링

카드에 Pulse에 포함된 클래스 및 컴포넌트 이외의 추가적인 스타일이 필요하다면, 카드용 CSS를 별도로 포함하는 몇 가지 방법이 있습니다.

데이터 수집 및 집계

커스텀 카드는 어디서든 데이터를 가져와 표시할 수 있습니다. 하지만 Pulse의 강력하고 효율적인 데이터 기록 및 집계 시스템을 활용하고 싶을 수도 있습니다.

Laravel Pulse

소개

Laravel Pulse는 애플리케이션의 성능과 사용 현황을 한눈에 파악할 수 있는 모니터링 도구입니다. 느린 Job이나 엔드포인트 같은 병목 지점을 추적하거나, 가장 활발하게 활동하는 사용자를 찾는 등 다양한 용도로 활용할 수 있습니다.

개별 이벤트에 대한 심층적인 디버깅이 필요하다면 Laravel Telescope를 함께 살펴보세요.

Laravel Pulse

설치

WARNING

Pulse의 기본 스토리지 구현은 현재 MySQL, MariaDB, 또는 PostgreSQL 데이터베이스만 지원합니다. 다른 데이터베이스 엔진을 사용 중이라면, Pulse 데이터를 저장할 별도의 MySQL, MariaDB, 또는 PostgreSQL 데이터베이스가 필요합니다.

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 대시보드에 접근할 수 있습니다.

NOTE

Pulse 데이터를 애플리케이션의 기본 데이터베이스가 아닌 별도의 데이터베이스에 저장하고 싶다면, 전용 데이터베이스 연결 설정을 참고하세요.

설정

Pulse의 많은 설정 옵션은 환경 변수로 제어할 수 있습니다. 사용 가능한 옵션 확인, 새로운 레코더 등록, 고급 옵션 설정 등이 필요하다면 config/pulse.php 설정 파일을 퍼블리시하세요:

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

Laravel Pulse

대시보드

접근 권한 설정

Pulse 대시보드는 /pulse 라우트를 통해 접근할 수 있습니다. 기본적으로 local 환경에서만 접근이 허용되므로, 운영 환경에서는 'viewPulse' 인증 게이트를 별도로 정의해야 합니다. app/Providers/AppServiceProvider.php 파일에 다음과 같이 추가하세요.

use App\Models\User; use Illuminate\Support\Facades\Gate; /** * 애플리케이션 서비스를 부트스트랩합니다. */ public function boot(): void { Gate::define('viewPulse', function (User $user) { return $user->isAdmin(); }); // ... }

대시보드 커스터마이징

대시보드의 카드 구성과 레이아웃은 뷰 파일을 퍼블리시하여 자유롭게 수정할 수 있습니다. 아래 명령을 실행하면 resources/views/vendor/pulse/dashboard.blade.php 경로에 파일이 생성됩니다.

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

대시보드는 Livewire로 구동되며, JavaScript 에셋을 별도로 빌드하지 않아도 카드 배치와 레이아웃을 수정할 수 있습니다.

퍼블리시된 파일에서 <x-pulse> 컴포넌트가 대시보드 전체를 렌더링합니다. 기본적으로 12컬럼 그리드 레이아웃을 사용하며, 화면 전체 너비로 확장하려면 full-width prop을 추가하세요.

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

컬럼 수를 변경하고 싶다면 cols prop으로 조정할 수 있습니다.

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

각 카드는 colsrows prop으로 크기와 위치를 개별 조정할 수 있습니다.

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

대부분의 카드는 expand prop을 지원하며, 이를 사용하면 스크롤 없이 카드 내용 전체를 펼쳐서 볼 수 있습니다.

<livewire:pulse.slow-queries expand />

사용자 정보 조회

Application Usage 카드처럼 사용자 정보를 표시하는 카드들은 내부적으로 사용자 ID만 기록합니다. 대시보드를 렌더링할 때 Pulse는 기본 Authenticatable 모델에서 nameemail 필드를 조회하고, Gravatar 서비스를 통해 아바타를 표시합니다.

표시할 필드나 아바타를 직접 지정하려면 App\Providers\AppServiceProviderboot 메서드에서 Pulse::user 메서드를 호출하세요.

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, ]); // ... }

NOTE

인증된 사용자를 캡처하고 조회하는 방식을 완전히 교체하고 싶다면, Laravel\Pulse\Contracts\ResolvesUsers 계약(Contract)을 구현한 클래스를 만들어 Laravel 서비스 컨테이너에 바인딩하면 됩니다.

카드 종류

Servers

<livewire:pulse.servers />

pulse:check 명령이 실행 중인 모든 서버의 시스템 리소스 사용량을 표시합니다. 자세한 내용은 servers 레코더 문서를 참고하세요.

서버를 교체했을 때 이전 서버가 대시보드에 계속 표시되는 것을 원하지 않는다면, ignore-after prop으로 비활성 서버를 숨길 시간을 지정할 수 있습니다. 초 단위 숫자 또는 1 hour, 3 days and 1 hour 같은 상대적 시간 문자열 모두 사용 가능합니다.

<livewire:pulse.servers ignore-after="3 hours" />

Application Usage

<livewire:pulse.usage />

요청 횟수, 느린 요청, Job 디스패치 기준으로 상위 10명의 사용자를 보여줍니다.

세 가지 지표를 동시에 확인하려면 type 속성을 다르게 지정하여 카드를 여러 번 배치하면 됩니다.

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

사용자 정보 표시 방식을 변경하는 방법은 사용자 정보 조회 섹션을 참고하세요.

NOTE

요청이 매우 많거나 Job을 대량으로 디스패치하는 애플리케이션이라면 샘플링 활성화를 고려하세요. user requests 레코더, user jobs 레코더, slow jobs 레코더 문서에서 자세한 내용을 확인할 수 있습니다.

Exceptions

<livewire:pulse.exceptions />

애플리케이션에서 발생하는 예외의 빈도와 최근 발생 시점을 보여줍니다. 기본적으로 예외 클래스와 발생 위치를 기준으로 그룹화됩니다. 자세한 내용은 exceptions 레코더 문서를 참고하세요.

Queues

<livewire:pulse.queues />

큐에 등록됨(queued), 처리 중(processing), 처리 완료(processed), 재시도(released), 실패(failed) 상태별 Job 수를 포함한 큐 처리량을 보여줍니다. 자세한 내용은 queues 레코더 문서를 참고하세요.

Slow Requests

<livewire:pulse.slow-requests />

설정된 임계값(기본값 1,000ms)을 초과하는 요청을 표시합니다. 자세한 내용은 slow requests 레코더 문서를 참고하세요.

Slow Jobs

<livewire:pulse.slow-jobs />

설정된 임계값(기본값 1,000ms)을 초과하여 처리된 큐 Job을 표시합니다. 자세한 내용은 slow jobs 레코더 문서를 참고하세요.

Slow Queries

<livewire:pulse.slow-queries />

설정된 임계값(기본값 1,000ms)을 초과하는 데이터베이스 쿼리를 표시합니다.

기본적으로 바인딩 값을 제외한 SQL 쿼리 문자열과 발생 위치를 기준으로 그룹화됩니다. 위치 정보를 기록하지 않고 SQL 쿼리만으로 그룹화하는 것도 가능합니다.

SQL 쿼리가 매우 길어서 구문 강조(syntax highlighting) 렌더링에 성능 문제가 생긴다면 without-highlighting prop으로 강조 기능을 끌 수 있습니다.

<livewire:pulse.slow-queries without-highlighting />

자세한 내용은 slow queries 레코더 문서를 참고하세요.

Slow Outgoing Requests

<livewire:pulse.slow-outgoing-requests />

Laravel HTTP 클라이언트를 통해 보낸 외부 요청 중 설정된 임계값(기본값 1,000ms)을 초과하는 항목을 표시합니다.

기본적으로 전체 URL을 기준으로 그룹화됩니다. 정규 표현식을 활용해 유사한 URL을 정규화하거나 묶어서 표시하는 방법은 slow outgoing requests 레코더 문서를 참고하세요.

Cache

<livewire:pulse.cache />

애플리케이션 전체 및 개별 캐시 키별 히트(hit)·미스(miss) 통계를 보여줍니다.

기본적으로 캐시 키를 기준으로 그룹화됩니다. 정규 표현식으로 유사한 키를 정규화하거나 묶는 방법은 cache interactions 레코더 문서를 참고하세요.

Laravel Pulse — 항목 수집

항목 수집

대부분의 Pulse 레코더는 Laravel이 디스패치하는 프레임워크 이벤트를 기반으로 자동으로 항목을 수집합니다. 그러나 서버 레코더와 일부 서드파티 카드는 주기적으로 정보를 직접 폴링해야 합니다. 이러한 카드를 사용하려면 각 애플리케이션 서버에서 pulse:check 데몬을 실행해야 합니다.

php artisan pulse:check

NOTE

pulse:check 프로세스를 백그라운드에서 지속적으로 실행하려면 Supervisor와 같은 프로세스 모니터를 사용해 명령이 중단되지 않도록 관리하세요.

pulse:check는 장기 실행 프로세스이므로, 코드베이스가 변경되어도 재시작하지 않으면 변경 사항을 반영하지 못합니다. 배포 과정에서 pulse:restart 명령을 호출해 안전하게 재시작하세요.

php artisan pulse:restart

NOTE

Pulse는 재시작 신호를 저장하기 위해 캐시를 사용합니다. 이 기능을 사용하기 전에 캐시 드라이버가 올바르게 설정되어 있는지 확인하세요.

레코더

레코더는 애플리케이션에서 발생하는 항목을 수집해 Pulse 데이터베이스에 기록하는 역할을 합니다. 레코더는 Pulse 설정 파일recorders 섹션에서 등록하고 설정합니다.

Cache Interactions

CacheInteractions 레코더는 애플리케이션에서 발생하는 캐시 히트(hit)와 미스(miss) 정보를 수집해 Cache 카드에 표시합니다.

샘플링 비율과 무시할 키 패턴을 선택적으로 조정할 수 있습니다.

또한 동일한 유형의 정보를 캐싱하는 유사한 키들을 하나의 항목으로 묶는 키 그룹핑을 설정할 수 있습니다. 예를 들어 캐시 키에 포함된 고유 ID를 제거해 같은 종류의 키로 통합할 수 있습니다. 그룹은 정규식을 사용해 키의 일부를 "찾아 바꾸는" 방식으로 설정합니다.

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

패턴은 첫 번째로 일치하는 것이 사용됩니다. 일치하는 패턴이 없으면 키가 원래 값 그대로 기록됩니다.

Exceptions

Exceptions 레코더는 애플리케이션에서 발생하는 보고 가능한(reportable) 예외 정보를 수집해 Exceptions 카드에 표시합니다.

샘플링 비율과 무시할 예외 패턴을 조정할 수 있으며, 예외가 발생한 위치(location)를 함께 수집할지 여부도 설정할 수 있습니다. 수집된 위치는 Pulse 대시보드에 표시되어 예외 발생 지점을 추적하는 데 도움이 됩니다. 단, 동일한 예외가 여러 위치에서 발생하면 각 고유 위치마다 별도의 항목으로 표시됩니다.

Queues

Queues 레코더는 애플리케이션의 큐 정보를 수집해 Queues 카드에 표시합니다.

샘플링 비율과 무시할 Job 패턴을 선택적으로 조정할 수 있습니다.

Slow Jobs

SlowJobs 레코더는 애플리케이션에서 느리게 실행되는 Job 정보를 수집해 Slow Jobs 카드에 표시합니다.

느린 Job 임계값, 샘플링 비율, 무시할 Job 패턴을 조정할 수 있습니다.

일부 Job은 구조상 다른 Job보다 실행 시간이 길 수 있습니다. 이런 경우 Job별 임계값을 개별 설정할 수 있습니다.

Recorders\SlowJobs::class => [ // ... 'threshold' => [ '#^App\\Jobs\\GenerateYearlyReports$#' => 5000, 'default' => env('PULSE_SLOW_JOBS_THRESHOLD', 1000), ], ],

Job 클래스명과 일치하는 정규식 패턴이 없으면 'default' 값이 사용됩니다.

Slow Outgoing Requests

SlowOutgoingRequests 레코더는 Laravel의 HTTP 클라이언트를 통해 발생하는 외부 HTTP 요청 중 설정된 임계값을 초과한 요청 정보를 수집해 Slow Outgoing Requests 카드에 표시합니다.

느린 외부 요청 임계값, 샘플링 비율, 무시할 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이 원래 값 그대로 기록됩니다.

Slow Queries

SlowQueries 레코더는 설정된 임계값을 초과하는 데이터베이스 쿼리를 수집해 Slow Queries 카드에 표시합니다.

느린 쿼리 임계값, 샘플링 비율, 무시할 쿼리 패턴을 조정할 수 있으며, 쿼리가 실행된 위치를 함께 수집할지 여부도 설정할 수 있습니다. 수집된 위치는 Pulse 대시보드에 표시되어 쿼리 발생 지점을 추적하는 데 도움이 됩니다. 단, 동일한 쿼리가 여러 위치에서 실행되면 각 고유 위치마다 별도의 항목으로 표시됩니다.

특정 쿼리는 구조상 더 오래 걸릴 수 있습니다. 이런 경우 쿼리별 임계값을 개별 설정할 수 있습니다.

Recorders\SlowQueries::class => [ // ... 'threshold' => [ '#^insert into `yearly_reports`#' => 5000, 'default' => env('PULSE_SLOW_QUERIES_THRESHOLD', 1000), ], ],

쿼리 SQL과 일치하는 정규식 패턴이 없으면 'default' 값이 사용됩니다.

Slow Requests

Requests 레코더는 애플리케이션으로 들어오는 요청 정보를 수집해 Slow RequestsApplication Usage 카드에 표시합니다.

느린 라우트 임계값, 샘플링 비율, 무시할 경로를 선택적으로 조정할 수 있습니다.

특정 요청은 구조상 더 오래 걸릴 수 있습니다. 이런 경우 요청별 임계값을 개별 설정할 수 있습니다.

Recorders\SlowRequests::class => [ // ... 'threshold' => [ '#^/admin/#' => 5000, 'default' => env('PULSE_SLOW_REQUESTS_THRESHOLD', 1000), ], ],

요청 URL과 일치하는 정규식 패턴이 없으면 'default' 값이 사용됩니다.

Servers

Servers 레코더는 애플리케이션을 구동하는 서버의 CPU, 메모리, 스토리지 사용량을 수집해 Servers 카드에 표시합니다. 이 레코더를 사용하려면 모니터링하고자 하는 모든 서버에서 pulse:check 명령이 실행 중이어야 합니다.

각 서버는 고유한 이름을 가져야 합니다. 기본값으로 Pulse는 PHP의 gethostname 함수가 반환하는 값을 사용합니다. 이름을 직접 지정하려면 PULSE_SERVER_NAME 환경 변수를 설정하세요.

PULSE_SERVER_NAME=load-balancer

Pulse 설정 파일에서 모니터링할 디렉터리도 별도로 지정할 수 있습니다.

User Jobs

UserJobs 레코더는 애플리케이션에서 Job을 디스패치한 사용자 정보를 수집해 Application Usage 카드에 표시합니다.

샘플링 비율과 무시할 Job 패턴을 선택적으로 조정할 수 있습니다.

User Requests

UserRequests 레코더는 애플리케이션에 요청을 보낸 사용자 정보를 수집해 Application Usage 카드에 표시합니다.

샘플링 비율과 무시할 URL 패턴을 선택적으로 조정할 수 있습니다.

필터링

앞서 살펴본 것처럼 많은 레코더는 설정을 통해 요청 URL 등 항목의 값을 기준으로 특정 항목을 무시할 수 있습니다. 그런데 때로는 현재 인증된 사용자처럼 다른 조건을 기준으로 항목을 필터링해야 할 수도 있습니다. 이런 경우 Pulse의 filter 메서드에 클로저를 전달하면 됩니다. 일반적으로 filter 메서드는 애플리케이션의 AppServiceProviderboot 메서드 안에서 호출합니다.

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(); }); // ... }

클로저가 true를 반환하면 해당 항목이 기록되고, false를 반환하면 기록에서 제외됩니다. 위 예시에서는 관리자가 아닌 사용자의 항목만 기록합니다.

Laravel Pulse

성능 최적화

Pulse는 별도의 인프라 없이 기존 애플리케이션에 바로 도입할 수 있도록 설계되었습니다. 다만 트래픽이 많은 애플리케이션에서는 Pulse가 전체 성능에 미치는 영향을 최소화하기 위해 아래 방법들을 활용할 수 있습니다.

별도 데이터베이스 연결 사용

트래픽이 높은 환경에서는 Pulse 전용 데이터베이스 연결을 분리해 두면 애플리케이션의 주 데이터베이스에 부하가 가지 않습니다.

PULSE_DB_CONNECTION 환경 변수를 설정하면 Pulse가 사용할 데이터베이스 연결을 지정할 수 있습니다.

PULSE_DB_CONNECTION=pulse

Redis Ingest

WARNING

Redis Ingest를 사용하려면 Redis 6.2 이상이 필요하며, Redis 클라이언트 드라이버로 phpredis 또는 predis가 설정되어 있어야 합니다.

기본적으로 Pulse는 HTTP 응답이 클라이언트에 전송되거나 Job 처리가 완료된 후, 수집된 항목을 설정된 데이터베이스 연결에 직접 저장합니다. 그러나 Redis ingest 드라이버를 사용하면 항목을 먼저 Redis 스트림으로 전송할 수 있습니다. 쓰기 부하를 분산시키고 싶을 때 유용한 방법입니다.

PULSE_INGEST_DRIVER 환경 변수를 다음과 같이 설정하면 활성화됩니다.

PULSE_INGEST_DRIVER=redis

Pulse는 기본적으로 애플리케이션의 기본 Redis 연결을 사용하지만, PULSE_REDIS_CONNECTION 환경 변수로 별도 연결을 지정할 수도 있습니다.

PULSE_REDIS_CONNECTION=pulse

WARNING

Redis ingest 드라이버를 사용할 때는, 애플리케이션에서 Redis 기반 큐를 함께 사용하고 있다면 반드시 Pulse 전용 Redis 연결을 큐와 분리해서 사용해야 합니다.

Redis ingest를 사용하는 경우, pulse:work 명령어를 실행해 Redis 스트림을 모니터링하고 항목을 Pulse 데이터베이스 테이블로 이동시켜야 합니다.

php artisan pulse:work

NOTE

pulse:work 프로세스를 백그라운드에서 지속적으로 실행하려면 Supervisor 같은 프로세스 관리 도구를 사용해 워커가 중단되지 않도록 관리하세요.

pulse:work는 장시간 실행되는 프로세스이므로, 코드베이스가 변경되어도 재시작하기 전까지는 변경 사항을 반영하지 않습니다. 애플리케이션 배포 시 pulse:restart 명령어를 호출해 워커를 안전하게 재시작하세요.

php artisan pulse:restart

NOTE

Pulse는 재시작 신호를 저장하기 위해 캐시를 사용합니다. 이 기능을 사용하기 전에 캐시 드라이버가 올바르게 설정되어 있는지 확인하세요.

샘플링

기본적으로 Pulse는 애플리케이션에서 발생하는 모든 관련 이벤트를 수집합니다. 트래픽이 많은 애플리케이션에서는 특히 긴 기간의 데이터를 집계할 때 수백만 건의 데이터베이스 행이 생성될 수 있습니다.

이럴 때는 특정 Pulse 데이터 레코더에 "샘플링"을 적용할 수 있습니다. 예를 들어 사용자 요청 레코더의 샘플 비율을 0.1로 설정하면 전체 요청의 약 10%만 기록합니다. 대시보드에서는 이 값을 역산해 표시하며, 근삿값임을 나타내는 ~ 접두사가 붙습니다.

일반적으로 특정 지표의 데이터 양이 많을수록 정확도 손실 없이 샘플 비율을 더 낮게 설정할 수 있습니다.

데이터 정리 (Trimming)

Pulse는 대시보드 조회 기간을 벗어난 항목을 자동으로 정리합니다. 데이터 수집 시 복권(lottery) 방식으로 정리가 실행되며, 이 동작은 Pulse 설정 파일에서 조정할 수 있습니다.

Pulse 예외 처리

Pulse 데이터를 수집하는 도중 예외가 발생하더라도(예: 저장소 데이터베이스에 연결할 수 없는 경우), Pulse는 애플리케이션에 영향을 주지 않기 위해 자동으로 실패를 무시합니다.

예외 처리 방식을 직접 정의하려면 handleExceptionsUsing 메서드에 클로저를 전달하면 됩니다.

use Laravel\Pulse\Facades\Pulse; use Illuminate\Support\Facades\Log; Pulse::handleExceptionsUsing(function ($e) { Log::debug('Pulse에서 예외가 발생했습니다.', [ 'message' => $e->getMessage(), 'stack' => $e->getTraceAsString(), ]); });

커스텀 카드

Pulse는 애플리케이션의 고유한 요구사항에 맞는 데이터를 표시하는 커스텀 카드를 직접 만들 수 있도록 지원합니다. Pulse는 내부적으로 Livewire를 사용하므로, 커스텀 카드를 만들기 전에 Livewire 공식 문서를 먼저 살펴보는 것을 권장합니다.

카드 컴포넌트

커스텀 카드는 기본 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의 지연 로딩(lazy loading) 기능을 사용하면, Card 컴포넌트가 컴포넌트에 전달된 colsrows 속성을 자동으로 반영한 플레이스홀더를 제공합니다.

카드의 뷰를 작성할 때는 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="" 속성을 추가하면 카드가 5초마다 자동으로 갱신됩니다.

Livewire 컴포넌트와 템플릿을 정의했다면, 대시보드 뷰에 카드를 추가할 수 있습니다:

<x-pulse> ... <livewire:pulse.top-sellers cols="4" /> </x-pulse>

NOTE

카드를 패키지로 배포하는 경우, 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 파일 직접 지정

패키지 안에 카드가 포함된 경우처럼 Vite를 사용하기 어려운 상황에서는, Livewire 컴포넌트에 css 메서드를 정의하여 Pulse가 해당 스타일시트를 자동으로 불러오도록 할 수 있습니다:

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

이 카드가 대시보드에 포함되면, Pulse는 해당 파일의 내용을 <style> 태그 안에 자동으로 삽입합니다. 따라서 CSS 파일을 public 디렉터리에 별도로 퍼블리시할 필요가 없습니다.

Tailwind CSS

Tailwind CSS를 사용할 경우, 카드 전용 CSS 엔트리포인트를 별도로 만드는 것이 좋습니다. 아래 예시는 Pulse가 이미 포함하고 있는 Tailwind의 Preflight 기본 스타일을 제외하고, CSS 셀렉터로 범위를 좁혀 Pulse의 Tailwind 클래스와 충돌하지 않도록 구성한 예입니다:

@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); }

카드 뷰에서도 CSS 셀렉터와 매칭되는 id 또는 class 속성을 추가해야 합니다:

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

데이터 수집과 집계

커스텀 카드는 어디서든 데이터를 가져와 표시할 수 있지만, Pulse가 제공하는 효율적인 데이터 기록·집계 시스템을 활용하면 성능과 일관성 면에서 더 유리합니다.

엔트리 기록

Pulse::record 메서드를 사용해 "엔트리"를 기록할 수 있습니다:

use Laravel\Pulse\Facades\Pulse; Pulse::record('user_sale', $user->id, $sale->amount) ->sum() ->count();
  • 첫 번째 인수: 엔트리의 type (데이터 종류를 구분하는 식별자)
  • 두 번째 인수: key (집계 데이터를 그룹화하는 기준)
  • 세 번째 인수: 집계할 value

위 예시에서는 $sale->amount를 값으로 기록하고, sum()count()를 함께 호출합니다. Pulse는 이 값들을 "버킷"에 미리 집계해두어 나중에 빠르게 조회할 수 있도록 합니다.

사용 가능한 집계 메서드는 다음과 같습니다:

  • avg
  • count
  • max
  • min
  • sum

NOTE

현재 인증된 사용자 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는 기본적으로 미리 집계된 버킷에서 데이터를 가져옵니다. 따라서 aggregate 메서드에서 요청하는 집계 유형은 반드시 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 { /** * 수신할 이벤트 목록 * * @var array<int, class-string> */ public array $listen = [ Deployment::class, ]; /** * 배포 이벤트를 기록합니다. */ public function record(Deployment $event): void { $config = Config::get('pulse.recorders.'.static::class); Pulse::record( // ... ); } }

이 문서는 Laravel 공식 문서(MIT)를 한국 개발자를 위해 번역·재구성한 것입니다.

번역일: 2026년 7월 2일