[Observability 4/5] RUM·사용자 행동 분석·Session Replay 구분하기

심대용·2026년 9월 26일
post-thumbnail

이 글에서 다룰 주제

  • 사용자 경험의 시간: API가 빠른데 화면이 느린 이유
  • 세 가지 관찰 방법: RUM·행동 분석·Replay로 각각 무엇을 알 수 있을까?
  • 연결과 수집 범위: Session ID·Trace ID로 사건을 연결하고 필요한 정보만 남기기

주요 단어 · RUM · Web Vitals · Faro · Session Replay · Session ID · Trace ID

3편에서는 서버가 만든 관측 데이터가 저장소와 Grafana까지 도달하는 경로를 살펴봤다. 그런데 서버 트레이스가 짧아도 사용자는 검색 결과를 오래 기다릴 수 있다. 브라우저가 응답을 받은 뒤 해야 할 일이 남아 있기 때문이다.

이번 편의 목표는 서버 처리 시간과 화면 완료 시간을 구분하고, 조사할 질문에 맞는 브라우저 데이터를 고르는 것이다. 앞선 글의 가상 demo-api와 GET /search를 사용한다. 시간 범위도 2026-10-04 10:00~10:05 KST이며, 모든 수치와 세션은 설명용으로 만든 예제다.

브라우저의 검색 조작이 API와 저장소를 거쳐 돌아온 뒤 화면에 표시되는 전체 과정

그림 1. 작성자 제작 개념도. API 응답이 돌아오는 지점과 사용자가 결과를 보는 지점을 나눠 읽는다. 서버 관측은 브라우저 안의 모든 일을 대신 설명하지 않는다.

1. 사용자 경험의 시간: API 응답 이후에도 기다릴 수 있다

공통 예제에는 서버에서 100ms가 걸린 요청과 2000ms가 걸린 요청이 있었다. 이번에는 100ms짜리 빠른 요청 한 건을 브라우저 관점에서 확대한다. 앞선 편의 2000ms 트레이스와는 다른 요청이다.

다음처럼 일이 겹치지 않고 진행됐다고 가정하자.

검색 버튼 클릭              0ms
응답 데이터 수신 완료     200ms
검색 결과 표시 완료      1200ms

클릭 직후 요청이 시작됐고, 네트워크 등의 비용 100ms와 서버 처리 100ms를 합쳐 200ms에 응답을 받았다고 놓았다. 그 뒤 데이터 가공·화면 갱신·대기로 1000ms가 더 걸려 1200ms에 결과가 보인다. 실제 브라우저에는 병렬 작업과 여러 대기가 있으므로 일반적인 시간 분해 공식이 아니라 관측 범위를 이해하기 위한 가정이다.

서버 지표에 있는 100ms, 브라우저에서 관측한 요청 200ms, 클릭부터 결과 표시까지 1200ms는 모두 같은 질문에 대한 답이 아니다. 어떤 구간의 시작과 끝을 측정했는지부터 확인해야 한다.

전체 구조에서 응답 이후의 브라우저 데이터 처리와 화면 표시 구간을 강조한 그림

그림 2. 작성자 제작 강조판. 주황색은 API 응답 이후의 조사 영역이다. 긴 구간을 발견한 다음, 계산·렌더링·대기 중 무엇이 시간을 차지했는지 더 살펴본다.

이 예제에서 서버 최적화로 100ms를 절반으로 줄여도, 나머지 조건이 같다면 전체는 1200ms에서 1150ms로 줄어든다. 반대로 응답 이후의 1000ms를 조사하면 더 큰 개선 가능성을 찾을 수 있다. “프론트엔드가 원인”이라고 단정하는 대신 아직 설명하지 못한 시간이 어디에 있는지를 먼저 찾는 접근이다.

2. RUM: 실제 환경에서 느린 구간과 오류 찾기

RUM(Real User Monitoring)은 실제 사용자의 브라우저나 앱에서 발생한 성능·오류 데이터를 관찰하는 방식이다. 테스트를 위해 만든 조건과 달리 실제 기기·네트워크·이용 상황이 반영된다.

브라우저 RUM에서는 페이지 성능, JavaScript 오류, API 요청 시간 등을 수집할 수 있다. 모든 SDK가 같은 항목을 기본 수집하는 것은 아니므로 수집한 이벤트와 측정 범위를 먼저 확인한다. Grafana Faro는 이런 브라우저 계측에 사용하는 SDK의 한 예다. Faro Web SDK

2.1 Web Vitals가 알려주는 것

Web Vitals는 웹 사용자 경험의 주요 측면을 측정하는 지표다. 이 중 Core Web Vitals의 LCP·INP·CLS는 서로 다른 문제를 본다.

지표읽는 질문다른 것으로 오해하지 않기
LCP큰 주요 콘텐츠가 언제 표시됐나?모든 로딩의 완료 시간과 다름
INP조작 후 다음 화면 반응이 늦었나?비동기 검색 결과의 완료 시간과 다름
CLS화면 요소가 뜻밖에 이동했나?시간이 아닌 이동 점수

LCP는 로딩, INP는 상호작용 반응성, CLS는 시각적 안정성을 살펴본다. INP는 페이지의 상호작용들을 바탕으로 반응성을 평가하므로 특정 검색 한 번의 전체 대기 시간과 동일하게 읽으면 안 된다. Web Vitals 공식 설명

예를 들어 클릭 직후 로딩 표시를 잘 그렸어도 검색 결과가 늦을 수 있다. 다음 화면 반응이 빠르다는 것과 사용자가 원하는 결과까지 빨리 도달한다는 것은 서로 다른 조건이다. 이 경우에는 “검색을 시작한 시점”과 “결과를 표시한 시점”을 별도로 계측해야 한다.

2.2 “검색 완료”의 정의도 정해야 한다

가상 예제에서는 다음 두 이벤트가 필요하다고 정해 보자.

search_started
    → 동일 검색 작업의 시작
search_results_visible
    → 결과가 표시됐다고 정한 완료 지점

이 이름은 설명용 이벤트 이름이며 Faro에 자동으로 생기는 고정 이벤트가 아니다. 구현에서 같은 검색 작업을 묶을 식별자와 측정 시작·종료 조건을 정의해야 한다. 응답을 받은 직후의 시각을 results_visible로 기록하면 화면에 표시되기까지 남은 시간을 놓친다.

측정한 값은 기기나 브라우저별로 나눠 읽으면 도움이 된다. 다만 작은 표본에서 p95가 변했다고 모든 사용자 경험이 바뀌었다고 판단하지 않는다. 어떤 세션이 수집됐는지, 누락이나 샘플링이 있는지도 함께 본다. 1200ms라는 숫자에는 측정 구간과 대상 범위가 붙어야 의미가 생긴다.

3. 행동 분석과 Replay: 같은 사건에 서로 다른 질문하기

3.1 사용자 행동 분석은 “어디까지 진행했는가?”를 본다

사용자 행동 분석은 페이지 이동·기능 사용 이벤트로 이용 흐름을 이해하는 활동이다. 대표적으로 단계별 도달률과 이탈 지점을 살펴볼 수 있다.

가상 검색 화면의 흐름을 검색 시작 → 결과 표시 → 결과 선택으로 정하자. 설명을 위해 각 단계에 도달한 세션 수가 100→80→30이라고 가정하면, “시작한 세션 중 80%가 결과 표시 이벤트에 도달했다”라고 읽을 수 있다.

그렇다고 나머지 20%가 모두 성능 때문에 이탈했다고 말할 수는 없다. 페이지를 닫았을 수도 있고, 계측 이벤트가 누락됐을 수도 있다. 같은 세션에 검색이 여러 번 있으면 단순 이벤트 수의 비율은 해석이 더 달라진다. 여기서는 세션별 한 번의 검색만 집계한다는 조건을 붙였다.

또 결과 선택 30%가 낮은지 판단하려면 서비스의 목적이 필요하다. 결과 목록에서 원하는 정보를 바로 읽었다면 추가 클릭이 없어도 목적을 달성했을 수 있다. 행동 데이터는 사용자의 행동을 기록하지만 이유를 직접 기록하지는 않는다.

3.2 Session Replay는 “어떤 화면에서 무엇을 했는가?”를 본다

Session Replay는 수집한 화면 상태·변경·상호작용 기록을 이용해 사용자 활동을 재현하는 기능이다.

웹 리플레이는 DOM 상태와 변경 이벤트를 기록해 재구성하는 방식 등을 쓴다. 일반적인 화면 동영상과 같은 범위를 담는다고 가정하면 안 된다. 가려진 내용, 지원하지 않는 요소, 기록하지 않은 구간은 재현에 한계가 있다. rrweb의 기록·재생 방식

검색 결과가 안 보였다는 세션에서 Replay를 보면 “로딩 표시가 계속 남았는가?”, “오류 안내가 나타났는가?”, “결과가 화면 아래에 있어서 못 봤는가?”를 조사할 수 있다. 하지만 영상처럼 보이는 화면만으로 JavaScript 실행 시간이 왜 길었는지 확정할 수는 없다. RUM 오류나 성능 측정과 연결해야 한다.

세 관점을 같은 문제에 적용하면 역할이 분명해진다.

방법이 예제에서 묻는 것다음 조사
RUM결과 표시가 늦거나 오류가 났나?느린 구간·기기·오류 확인
행동 분석검색 후 어느 단계까지 갔나?조건별 완료율 비교
Replay당시 어떤 화면을 봤나?문제 장면과 계측 연결

기능 하나를 켰다고 이 세 종류의 데이터가 같은 범위로 모두 수집되는 것은 아니다. 어떤 질문에 답할지 먼저 정하면 불필요한 수집을 줄이면서도 부족한 증거를 찾기 쉽다.

4. Session ID와 Trace ID: 활동 구간과 요청 경로 연결하기

한 Session ID 아래 여러 검색 요청의 Trace ID가 연결되는 관계를 보여 주는 상세도

그림 3. 작성자 제작 상세도. Session ID는 사용자 활동 구간을, Trace ID는 계측된 작업 흐름을 묶는다. 그림의 S1·Trace A 등은 설명용 짧은 이름이며 실제 ID 형식이 아니다.

Session ID는 일정 규칙으로 묶은 활동 구간의 식별자다. Trace ID는 하나의 계측된 작업 흐름에 속하는 Span들을 연결하는 식별자다. 사용자가 한 세션에서 검색을 세 번 하면 그 요청에 서로 다른 Trace ID가 붙을 수 있다.

따라서 “이 세션에서 무슨 일이 있었나?”에는 Session ID가 유용하고, “두 번째 검색이 서버의 어느 구간에서 느렸나?”에는 그 검색의 Trace ID가 유용하다. Session ID를 모든 요청의 Trace ID로 재사용하면 개별 요청 흐름을 구분하기 어렵다.

브라우저에서 서버까지 하나의 트레이스로 연결하려면 추적 문맥 전파(Context propagation)가 필요하다. 브라우저가 추적 정보를 요청 헤더로 보내고 서버 계측이 이를 읽어 같은 흐름을 이어야 한다. W3C Trace Context의 traceparent는 이 정보를 전달하는 표준 헤더다. OpenTelemetry 문맥 전파

Faro에서는 별도 Web Tracing 계측을 활성화해야 하며, 교차 출처 API에는 헤더를 보낼 대상 URL 설정과 서버의 CORS 허용을 맞춰야 한다. 서버 계측이 문맥을 추출하지 않거나 중간에서 헤더를 제거하면 트레이스가 끊길 수 있다. SDK 설치만으로 모든 API가 자동 연결되는 것은 아니다. Faro의 트레이스 계측

한편 관측용 Session ID는 로그인 권한을 증명하는 인증 토큰이 아니다. 익명 활동에도 관측용 세션을 만들 수 있고, 세션이 언제 시작·종료되는지는 제품과 설정에 따라 달라진다. 로그인 토큰이나 세션 쿠키 원문을 관측 식별자 대신 기록해서는 안 된다.

5. Faro의 역할과 수집 범위: 무엇을 어디까지 준비할까?

Faro Web SDK는 브라우저에서 실행되어 계측 데이터를 전송한다. 웹페이지 파일을 제공하는 서버에서 브라우저의 상태를 대신 읽는 방식이 아니다. 전송 대상은 설정에 따라 Faro 수신기를 갖춘 Alloy, Grafana Cloud, 사용자 정의 수신기 등이 될 수 있다. Faro 공식 저장소

자체 수집 경로와 Grafana Cloud로 보내는 경로는 필요한 Alloy 컴포넌트가 다를 수 있으므로 목적지에 맞춰 선택한다. faro.receiver 하나를 모든 환경의 공통 설정으로 복사하지 않는다. Alloy 수집 컴포넌트 선택

사용자가 검색하는 API 요청과 관측 데이터를 보내는 요청도 나눠야 한다. 검색 API가 정상인데 관측 수신기로의 전송만 실패할 수 있다. 반대로 관측 데이터가 도착해도 검색 기능은 느릴 수 있다. 따라서 수집 기능을 붙인 뒤에는 일부러 알려진 테스트 동작을 만들고 그 기록이 도착하는지 확인하는 과정이 필요하다.

5.1 Faro를 설치하면 Replay도 완성될까?

Grafana Cloud의 Session Replay 시작 문서 기준으로는 별도 조건이 있다. 2026-10-04 확인 시 public preview이며, Faro Web SDK 2.8.2 이상, Replay 계측 패키지와 ReplayInstrumentation, Cloud 스택의 기능 활성화가 필요하다. Canvas·WebGL은 현재 지원하지 않는다고 명시돼 있다. 이는 이 문서의 Cloud 구성 범위에 대한 설명이며, 모든 리플레이 제품의 공통 제한은 아니다. Session Replay quickstart

즉, 기본 Faro 데이터 전송과 Replay의 저장·검색·재생 기능은 구분해야 한다. 이 글은 SDK 설치 절차를 재현한 실습이 아니라 각 기능이 어디까지 책임지는지 설명한다.

5.2 필요한 정보만 남기는 예

가상 검색 장애를 조사하려면 오류 종류, 처리 시간, 검색 결과 수, 화면의 로딩 상태만으로도 시작할 수 있다. 검색어 원문이나 입력값 전체가 반드시 필요한 것은 아니다. 다음처럼 먼저 수집 계약을 작게 정한다.

목적남길 정보 예수집에서 제외할 정보 예
지연 비교시간·브라우저 종류·소요 ms검색어 원문
오류 연결오류 코드·Trace ID인증 토큰·쿠키
화면 문맥로딩·오류 안내 상태개인 입력값·본문

마스킹은 기록에서 내용을 가리거나 바꾸는 처리다. 앞서 확인한 Cloud Replay 문서는 기본 설정에서 입력값과 텍스트를 브라우저 쪽에서 마스킹한다고 설명한다. 다만 리플레이의 마스킹이 다른 로그·URL·커스텀 이벤트 필드까지 대신 정리해 준다고 가정하지 않는다. 실제 테스트 기록으로 어떤 값이 전송됐는지 확인해야 한다. Replay의 데이터 보호 범위

6. 적용 질문: 어떤 데이터를 더 볼까?

Q1. API는 100ms인데 검색 결과는 1200ms 뒤에 보인다. 서버 증설부터 해야 할까?

먼저 브라우저에서 요청 왕복과 응답 이후 시간을 나눈다. 이 예제에서는 응답 이후 1000ms가 남아 있으므로 해당 작업과 오류를 조사하는 것이 근거 있는 다음 단계다.

Q2. 결과 선택률이 낮으면 화면이 느렸다는 뜻일까?

그 사실만으로는 모른다. 느린 세션과 정상 세션을 같은 조건으로 비교하고, 오류·화면 문맥·계측 누락을 확인한다. 비교에서 차이가 보여도 원인을 확정하려면 추가 검증이 필요하다.

Q3. 한 Session ID에 Trace ID가 여러 개 있으면 이상한가?

자연스러운 관계다. 한 활동 구간에서 여러 요청이 발생하기 때문이다. 조사하려는 요청의 시각과 Trace ID를 골라 서버 쪽 흐름으로 이동한다.

다음 편은 관찰에서 시험으로 넘어간다. k6로 부하 조건을 만들고, 그 조건에서 API의 응답과 내부 동작이 어떻게 달라지는지 확인한다.


검증 범위 — 2026-10-04: 공식 문서에서 Web Vitals의 측정 관점, Faro의 브라우저 계측·추적 문맥 연결, Grafana Cloud Replay의 시작 조건과 제한을 확인했다. 특정 SDK 버전을 설치·실행하지 않았으며 실제 사용자·회사·프로젝트 데이터를 사용하지 않았다. 수치·이벤트·화면 흐름은 작성자 제작 학습 예제다.

이전 글: Grafana 생태계 지도: 수집부터 저장과 시각화까지

다음 글: k6와 알림으로 이해하는 성능 검증과 장애 대응

profile
어제보다 더 성장하는 나

0개의 댓글