본문 바로가기

Laravel Pulse

업데이트됨

번역일: 2026년 9월 17일

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

원문 수정
2026년 9월 17일
번역 갱신
2026년 9월 17일

Laravel Pulse

Pulse

설치

NOTE

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"

마지막으로 Pulse가 데이터를 저장할 테이블을 생성하기 위해 마이그레이션을 실행합니다.

php artisan migrate

Pulse의 기본 저장소 마이그레이션을 실행하고 나면, /pulse 대시보드 경로를 통해 Pulse 대시보드에 접속할 수 있습니다.

NOTE

애플리케이션의 기본 데이터베이스에 Pulse 데이터를 저장하고 싶지 않다면, 별도의 데이터베이스 연결을 지정할 수 있습니다.

설정

Pulse의 다양한 기능들은 환경 변수를 통해 설정할 수 있습니다. 사용 가능한 옵션을 확인하거나 새로운 레코더를 등록하거나 고급 옵션을 설정하려면, config/pulse.php 설정 파일을 배포하면 됩니다.

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

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"

마지막으로, Pulse 데이터를 저장할 테이블을 생성하기 위해 migrate 명령어를 실행합니다:

php artisan migrate

Pulse의 데이터베이스 마이그레이션 실행이 끝나면, /pulse 라우트를 통해 Pulse 대시보드에 접속할 수 있습니다.

NOTE

Pulse 데이터를 애플리케이션의 기본 데이터베이스가 아닌 별도의 데이터베이스에 저장하고 싶다면, 전용 데이터베이스 커넥션을 지정할 수 있습니다.

설정

Pulse의 설정 옵션 대부분은 환경 변수로 제어할 수 있습니다. 사용 가능한 옵션을 확인하거나, 새로운 레코더(recorder)를 등록하거나, 고급 옵션을 설정하려면 config/pulse.php 설정 파일을 퍼블리시하면 됩니다:

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

NOTE

참고로 "레코더(recorder)"는 Pulse가 애플리케이션에서 발생하는 데이터를 수집하는 방식을 정의하는 클래스입니다. 이 개념은 뒤에서 레코더 다루기 섹션에서 자세히 설명합니다.

Pulse

대시보드

인가(Authorization) 설정

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

NOTE

위 예시처럼 isAdmin 같은 관리자 판별 로직을 직접 구현해도 되고, 팀 단위 권한 시스템(예: spatie/laravel-permission 같은 패키지)과 연동해도 됩니다. 핵심은 프로덕션 환경에서 아무나 대시보드에 접근하지 못하도록 반드시 게이트를 재정의해야 한다는 점입니다.

대시보드 커스터마이징

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 />

사용자 정보 표시 방식

애플리케이션 사용량(Application Usage) 카드처럼 사용자 정보를 함께 보여주는 카드의 경우, Pulse는 실제로는 사용자의 ID만 기록합니다. 대시보드를 렌더링할 때 기본 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, ]); // ... }

NOTE

인증된 사용자 정보를 가져오고 캡처하는 방식 자체를 완전히 바꾸고 싶다면, Laravel\Pulse\Contracts\ResolvesUsers 계약(contract)을 구현한 뒤 이를 Laravel 서비스 컨테이너에 바인딩하면 됩니다.

카드 종류

서버(Servers)

<livewire:pulse.servers /> 카드는 pulse:check 명령어를 실행 중인 모든 서버의 시스템 리소스 사용량을 보여줍니다. 시스템 리소스가 어떻게 수집되는지는 서버 레코더 문서를 참고하세요.

인프라 구성 중 서버를 교체하는 경우, 일정 시간이 지나면 더 이상 활동하지 않는(비활성) 서버를 대시보드에서 자동으로 숨기고 싶을 수 있습니다. 이때는 ignore-after 속성을 사용하면 됩니다. 이 속성에는 비활성 서버를 제거할 때까지의 시간을 초 단위로 지정하거나, 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 레코더, 느린 Job 레코더 문서를 확인하세요.

예외(Exceptions)

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

큐(Queues)

<livewire:pulse.queues /> 카드는 애플리케이션 큐의 처리량을 보여줍니다. 여기에는 큐에 등록된 Job 수, 처리 중인 Job 수, 처리 완료된 Job 수, 재시도로 반환된 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 쿼리 하나만 기준으로 그룹화할 수도 있습니다.

매우 긴 SQL 쿼리에 문법 강조(syntax highlighting)를 적용하는 과정에서 렌더링 성능 문제가 발생한다면, without-highlighting 속성을 추가해 강조 표시를 비활성화할 수 있습니다.

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

자세한 내용은 느린 쿼리 레코더 문서를 참고하세요.

느린 외부 요청(Slow Outgoing Requests)

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

기본적으로 각 항목은 전체 URL을 기준으로 그룹화됩니다. 하지만 비슷한 형태의 외부 요청들을 정규식으로 정규화하거나 하나로 묶어서 보고 싶을 수도 있습니다. 자세한 내용은 느린 외부 요청 레코더 문서를 참고하세요.

캐시(Cache)

<livewire:pulse.cache /> 카드는 애플리케이션의 캐시 히트/미스 통계를 전체 단위와 개별 키 단위로 보여줍니다.

기본적으로 각 항목은 캐시 키를 기준으로 그룹화됩니다. 하지만 비슷한 형태의 키들을 정규식으로 정규화하거나 하나로 묶어서 보고 싶을 수도 있습니다. 자세한 내용은 캐시 상호작용 레코더 문서를 참고하세요.

Pulse

데이터 수집하기

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

php artisan pulse:check

NOTE

pulse:check 프로세스가 백그라운드에서 계속 실행되도록 하려면 Supervisor와 같은 프로세스 모니터링 도구를 사용하여 명령이 중단되지 않도록 관리하는 것이 좋습니다.

pulse:check 명령은 장시간 실행되는 프로세스이기 때문에, 재시작하지 않으면 코드베이스 변경 사항을 인식하지 못합니다. 따라서 애플리케이션을 배포하는 과정에서 pulse:restart 명령을 호출하여 정상적으로 재시작하도록 해야 합니다.

php artisan pulse:restart

NOTE

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

레코더(Recorders)

레코더는 애플리케이션에서 발생하는 데이터를 수집하여 Pulse 데이터베이스에 기록하는 역할을 담당합니다. 레코더는 Pulse 설정 파일의 recorders 섹션에서 등록하고 설정할 수 있습니다.

캐시 상호작용 (Cache Interactions)

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

필요에 따라 샘플링 비율과 무시할 키 패턴을 조정할 수 있습니다.

또한 유사한 키를 하나의 항목으로 그룹화하도록 설정할 수도 있습니다. 예를 들어, 동일한 유형의 정보를 캐싱하는 키에서 고유 ID를 제거하고 싶을 수 있습니다. 그룹화는 키의 일부를 "찾아서 바꾸기" 하는 정규 표현식으로 설정합니다. 설정 파일에는 다음과 같은 예시가 포함되어 있습니다.

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

가장 먼저 일치하는 패턴이 사용됩니다. 일치하는 패턴이 없으면 키는 원래 형태 그대로 기록됩니다.

예외 (Exceptions)

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

필요에 따라 샘플링 비율과 무시할 예외 패턴을 조정할 수 있습니다. 또한 예외가 발생한 위치를 캡처할지 여부도 설정할 수 있습니다. 캡처된 위치는 Pulse 대시보드에 표시되어 예외의 원인을 추적하는 데 도움이 됩니다. 다만 동일한 예외가 여러 위치에서 발생하는 경우, 각각의 고유한 위치마다 별도의 항목으로 여러 번 나타나게 됩니다.

큐 (Queues)

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

필요에 따라 샘플링 비율과 무시할 Job 패턴을 조정할 수 있습니다.

느린 Job (Slow Jobs)

SlowJobs 레코더는 애플리케이션에서 발생하는 느린 Job에 대한 정보를 수집하여 Slow Jobs 카드에 표시합니다.

느린 작업 기준 시간(threshold), 샘플링 비율, 무시할 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 경로에서 고유 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 Requests와 Application Usage 카드에 표시합니다.

느린 라우트 기준 시간, 샘플링 비율, 무시할 경로(path)를 필요에 따라 조정할 수 있습니다.

특정 요청은 다른 요청보다 오래 걸리는 것이 당연할 수 있습니다. 이런 경우 요청별로 기준 시간을 다르게 설정할 수 있습니다.

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 설정 파일에서는 모니터링할 디렉터리도 원하는 대로 지정할 수 있습니다.

사용자별 Job (User Jobs)

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

필요에 따라 샘플링 비율과 무시할 Job 패턴을 조정할 수 있습니다.

사용자별 요청 (User Requests)

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

필요에 따라 샘플링 비율과 무시할 URL 패턴을 조정할 수 있습니다.

필터링

앞서 살펴본 것처럼, 많은 레코더는 설정을 통해 요청 URL과 같은 값을 기준으로 들어오는 데이터를 "무시"할 수 있는 기능을 제공합니다. 하지만 때로는 현재 인증된 사용자와 같이 다른 조건을 기준으로 데이터를 필터링해야 할 수도 있습니다. 이런 경우 Pulse의 filter 메서드에 클로저를 전달하여 데이터를 걸러낼 수 있습니다. 일반적으로 filter 메서드는 애플리케이션의 AppServiceProvider의 boot 메서드 안에서 호출합니다.

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

NOTE

filter 콜백 안에서는 인증(Auth) 및 세션 정보와 같은 애플리케이션 상태에 접근할 수 있지만, 데이터가 수집되는 시점(예: 요청이 끝나거나 Job이 처리된 이후)에 따라 해당 상태가 예상과 다를 수 있다는 점에 유의해야 합니다. 필터 로직은 가능한 한 단순하게 유지하는 것이 좋습니다.

성능 최적화

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이 처리된 후 설정된 데이터베이스 커넥션에 데이터를 직접 저장합니다. 하지만 Pulse의 Redis ingest 드라이버를 사용하면 데이터를 데이터베이스에 바로 쓰는 대신 Redis 스트림으로 전송할 수 있습니다. 이 기능은 PULSE_INGEST_DRIVER 환경 변수를 설정하여 활성화할 수 있습니다.

PULSE_INGEST_DRIVER=redis

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

PULSE_REDIS_CONNECTION=pulse

WARNING

Redis ingest 드라이버를 사용할 경우, Pulse는 큐에서 사용 중인 Redis 커넥션과는 반드시 다른 커넥션을 사용해야 합니다.

Redis ingest를 사용할 때는 pulse:work 명령어를 실행하여 Redis 스트림을 모니터링하고, 쌓인 데이터를 Pulse의 데이터베이스 테이블로 옮겨야 합니다.

php artisan pulse:work

NOTE

pulse:work 프로세스가 중단 없이 계속 실행되도록 하려면 Supervisor와 같은 프로세스 모니터링 도구를 사용하여 Pulse 워커가 항상 실행 중인 상태를 유지하도록 하는 것이 좋습니다.

pulse:work 명령어는 장시간 실행되는 프로세스이므로, 코드를 변경해도 재시작하기 전까지는 그 변경 사항이 반영되지 않습니다. 따라서 애플리케이션을 배포할 때 pulse:restart 명령어를 호출하여 워커를 정상적으로 재시작해 주어야 합니다.

php artisan pulse:restart

NOTE

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

샘플링

기본적으로 Pulse는 애플리케이션에서 발생하는 관련 이벤트를 빠짐없이 모두 기록합니다. 하지만 트래픽이 많은 애플리케이션이라면, 특히 조회 기간이 길어질수록 대시보드에서 수백만 건의 데이터베이스 행을 집계해야 하는 상황이 발생할 수 있습니다.

이런 경우, 일부 Pulse 레코더에서 "샘플링" 기능을 활성화하는 것을 고려해볼 수 있습니다. 예를 들어 사용자 요청(User Requests) 레코더의 샘플링 비율을 0.1로 설정하면, 애플리케이션에 들어오는 요청 중 약 10%만 기록하게 됩니다. 대시보드에서는 이렇게 기록된 값이 실제 비율에 맞춰 확대되어 표시되며, 근사치임을 나타내기 위해 값 앞에 ~ 기호가 붙습니다.

일반적으로 특정 지표에 대한 데이터 항목 수가 많을수록, 정확도를 크게 희생하지 않으면서도 샘플링 비율을 더 낮게 설정할 수 있습니다.

오래된 데이터 정리(Trimming)

Pulse는 대시보드에 표시되는 기간을 벗어난 데이터를 자동으로 정리(trim)합니다. 이 정리 작업은 데이터를 수집(ingest)하는 시점에 일종의 추첨(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는 애플리케이션에 특화된 데이터를 표시할 수 있도록 커스텀 카드를 직접 만들 수 있는 기능을 제공합니다. Pulse는 내부적으로 Livewire를 사용하므로, 첫 커스텀 카드를 만들기 전에 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의 지연 로딩(lazy loading) 기능을 사용하면, Card 컴포넌트가 컴포넌트에 전달된 cols, rows 속성에 맞춰 자동으로 플레이스홀더를 표시해줍니다.

카드에 대응하는 뷰를 작성할 때는, 대시보드 전체와 일관된 디자인을 유지할 수 있도록 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>

NOTE

만약 카드를 패키지 형태로 배포한다면, Livewire::component 메서드를 사용해 해당 컴포넌트를 Livewire에 등록해주어야 합니다.

스타일링

Pulse에 기본 포함된 클래스와 컴포넌트만으로는 원하는 디자인을 표현하기 어렵다면, 카드에 커스텀 CSS를 추가하는 몇 가지 방법을 사용할 수 있습니다.

Laravel Vite 통합 사용하기

커스텀 카드가 애플리케이션 코드베이스 안에 위치하고 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 카드처럼 Vite 통합을 사용하기 어려운 경우에는, Livewire 컴포넌트에 css 메서드를 정의해서 CSS 파일의 경로를 반환하도록 하면 Pulse가 해당 스타일시트를 불러오도록 만들 수 있습니다.

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

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

Tailwind CSS 사용하기

Tailwind CSS를 사용한다면 전용 CSS 엔트리 포인트를 별도로 만드는 것이 좋습니다. 아래 예시는 Pulse가 이미 포함하고 있는 Tailwind의 Preflight 기본 스타일을 제외하고, CSS 선택자로 Tailwind의 범위를 한정하여 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는 Pulse::record 메서드를 통해 "엔트리(entry)"를 기록할 수 있게 해줍니다.

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

record 메서드의 첫 번째 인자는 기록할 엔트리의 type이며, 두 번째 인자는 집계된 데이터를 그룹화할 기준이 되는 key입니다. 대부분의 집계 메서드는 집계할 대상인 value도 함께 지정해야 합니다. 위 예시에서는 $sale->amount가 집계 대상 값입니다. 그런 다음 sum과 같은 집계 메서드를 하나 이상 호출하면, Pulse가 이후 빠르게 조회할 수 있도록 값을 미리 집계된 "버킷(bucket)" 단위로 저장해줍니다.

사용할 수 있는 집계 메서드는 다음과 같습니다.

  • 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는 기본적으로 미리 집계해둔 버킷 데이터를 조회하기 때문에, 조회하려는 집계 항목은 반드시 Pulse::record 메서드로 사전에 기록되어 있어야 합니다. 가장 오래된 버킷은 일반적으로 조회 기간의 경계에 걸쳐 있는 경우가 많은데, 이때 Pulse는 매 요청마다 전체 기간을 다시 집계하지 않고도 정확한 값을 제공할 수 있도록, 해당 구간의 가장 오래된 엔트리들만 추가로 집계해서 빈틈을 채워줍니다.

특정 타입에 대한 전체 합산 값을 조회하고 싶다면 aggregateTotal 메서드를 사용하면 됩니다. 예를 들어 아래 코드는 사용자별로 그룹화하지 않고 전체 판매액의 합계를 가져옵니다.

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

사용자 정보 표시하기

사용자 ID를 key로 기록한 집계 데이터를 다룰 때는, Pulse::resolveUsers 메서드를 사용해서 key 값을 실제 사용자 레코드로 변환할 수 있습니다.

$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 }}" />

커스텀 레코더

패키지를 만드는 개발자라면, 사용자가 데이터 수집 방식을 직접 설정할 수 있도록 레코더(recorder) 클래스를 제공하고 싶을 수 있습니다.

레코더는 애플리케이션의 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, ]; /** * 배포(deployment) 정보를 기록합니다. */ public function record(Deployment $event): void { $config = Config::get('pulse.recorders.'.static::class); Pulse::record( // ... ); } }

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

번역일: 2026년 9월 17일