조용진의 개발 블로그
← 글 목록

결제 구간만 Session Replay를 수동 수집한 관측성 설계

DatadogSession ReplayRUM관측성

Datadog Session Replay를 결제 구간에서만 수동으로 시작·종료하고 입력값 마스킹과 화면 추적을 적용한 과정을 정리합니다.

결제 오류는 일반 화면 오류보다 재현이 어렵다. 사용자의 입력 순서, 결제 모듈 응답, 화면 전환이 짧은 시간에 이어지기 때문이다. 모든 세션을 항상 녹화하기보다 결제 구간에서만 Session Replay를 수동으로 시작하고 종료하는 방식을 적용했다.

전역 자동 녹화 대신 수동 시작을 선택했다

브라우저 RUM 설정은 Session Replay 샘플링을 허용하되 자동 시작을 끄도록 구성했다.

아래 코드 예시는 설명을 위해 식별자와 운영 설정값을 일반화했습니다.

datadogRum.init({
  sessionSampleRate: configuredSessionRate,
  sessionReplaySampleRate: configuredReplayRate,
  defaultPrivacyLevel: "mask-user-input",
  startSessionReplayRecordingManually: true,
});

이 설정만으로는 녹화가 시작되지 않는다. 결제 Hook이 실제 결제 흐름에 들어갈 때 startSessionReplayRecording()을 호출하고 finally에서 반드시 중지했다.

datadogRum.startSessionReplayRecording();
try { await performSensitiveFlow(); }
finally {
  datadogRum.stopSessionReplayRecording();
  await recordOutcome();
}

웹 결제 페이지처럼 컴포넌트 생명주기와 결제 구간이 같은 화면에서는 mount 시 시작하고 cleanup에서 종료했다. 핵심은 성공 경로뿐 아니라 실패·예외에서도 녹화가 닫히도록 finally나 Effect cleanup을 사용한 것이다.

입력 정보는 기본적으로 마스킹했다

결제 화면에는 전화번호와 금액 등 민감한 입력이 있을 수 있다. defaultPrivacyLevel: "mask-user-input"을 사용해 입력값을 기본 마스킹했다. 문제 재현을 위해 관측성을 높이더라도 실제 입력 내용을 그대로 수집하는 방식은 피했다.

RUM과 함께 브라우저 로그 수집도 초기화했지만, 오류를 자동으로 모두 전달하도록 설정하지 않고 필요한 로그를 명시적으로 남기는 쪽을 선택했다. 관측 범위를 넓히는 것과 수집량을 무제한으로 늘리는 것은 다른 문제다.

앱과 키오스크는 플랫폼에 맞는 SDK를 사용했다

같은 시기에 React Native 앱에는 Datadog Provider와 네비게이션 화면 추적을 연결했다. 앱 설정은 사용자 상호작용, XHR, 오류, native crash 보고 여부와 세션 샘플링 비율을 구분했다.

키오스크 웹 클라이언트에도 브라우저 RUM과 Logs를 초기화하고 API URL을 tracing 대상에 포함했다. 플랫폼마다 초기화 방식은 달랐지만 환경·서비스 이름을 함께 보내 조회 기준을 맞췄다.

flowchart LR
  A[결제 시작] --> B[Replay 수동 시작]
  B --> C[승인·저장 처리]
  C --> D[성공 또는 실패 로그]
  D --> E[Replay 종료]

결제 구간에서는 필요한 시점에만 Replay를 수집했고, 웹·앱·키오스크에는 각 실행 환경에 맞는 Datadog 초기화를 적용했다.

관측성의 목적은 많이 수집하는 것이 아니다. 문제가 발생하는 경계를 정확히 열고, 개인정보를 가린 채, 반드시 닫히는 생명주기를 만드는 것이 더 중요했다.