배포가 끝이 아니다. 배포 직후에 새로운 종류의 검증이 시작된다.
사용자가 마주하는 문제
배포 직후 한 시간 동안 별일 없어 보였습니다. 그런데 다음 날 고객지원팀에서 “결제가 안 된다는 문의가 어제 저녁부터 늘었다”는 보고가 옵니다. 따라가보니, 특정 브라우저의 특정 버전에서만 결제 모듈이 실패하고 있었습니다. CI 환경에선 그 조합이 없었습니다.
이런 일은 자주 일어납니다. 모든 테스트를 통과한 코드여도, 진짜 사용자가 마주하는 환경의 다양성을 다 담을 수는 없습니다. 운영 모니터링은 그 빈틈을 메우는 일입니다. 테스트가 코드 안에서 작동했다면, 모니터링은 코드 바깥의 진짜 세계에서 작동합니다.
무엇을 관찰하나
운영 모니터링은 세 갈래로 구성됩니다.
- 에러 추적 — 클라이언트와 서버에서 발생한 에러를 수집해 무엇이 깨지는지 파악
- 실사용 관찰(RUM) — 사용자가 실제로 어떤 흐름을 거치고 어디서 막히는지 측정
- 합성 모니터링 — 운영 환경에 주기적으로 핵심 시나리오를 자동 실행해 사용자보다 먼저 장애를 발견
이 셋은 서로를 보완합니다. 에러 추적은 “무엇이 깨졌는가”를, RUM은 “전체적으로 어떤 상태인가”를, 합성은 “지금 살아 있는가”를 알려줍니다.
에러 추적
에러 추적의 표준은 Sentry입니다. Datadog Error Tracking, Rollbar 같은 대안도 있습니다. 핵심 기능은 다음과 같습니다.
- 에러 수집 — 잡히지 않은 예외(uncaught exception)를 자동으로 수집
- 그룹화 — 같은 원인의 에러를 묶어, 한 이슈 = 하나의 그룹
- 컨텍스트 — 발생 시점의 사용자, 브라우저, URL, 직전 사용자 행동(breadcrumb)
- 소스맵 매핑 — 미니파이된 스택을 원본 코드로 복원
React 앱에 Sentry를 붙이는 예시입니다.
// src/sentry.ts
import * as Sentry from "@sentry/react";
Sentry.init({
dsn: import.meta.env.VITE_SENTRY_DSN,
environment: import.meta.env.MODE,
release: __APP_VERSION__, // 빌드 시 주입
tracesSampleRate: 0.1, // 트랜잭션 10% 샘플링
replaysSessionSampleRate: 0.01, // 세션 리플레이 1%
replaysOnErrorSampleRate: 1.0, // 에러 발생 세션은 100%
});
// React error boundary와 통합
const ErrorBoundary = Sentry.ErrorBoundary;
중요한 점 하나: 에러는 그 자체로 신호이지만, 모든 에러가 동등하지 않습니다. 사용자에게 보이는 결제 실패와 백그라운드 sync 재시도 에러는 무게가 다릅니다. 영향도(impact)를 기준으로 우선순위를 매기는 게 핵심입니다.
실사용 관찰 (RUM)
ep.07에서 본 web-vitals 데이터에 더해, 사용자가 어떤 경로로 흐르고 어디서 이탈하는지를 함께 봅니다.
- 세션 단위 흐름 — 한 사용자가 어떤 페이지들을 거쳤는가
- 퍼널 분석 — 가입 → 인증 → 결제 같은 흐름의 단계별 완주율
- 에러와 성능의 상관 — 느린 페이지에서 이탈이 더 많은가
- 세그먼트별 차이 — 모바일 vs 데스크탑, 지역별, OS별
도구는 Sentry(에러+RUM 통합), Datadog RUM, Vercel Analytics, PostHog 등이 있습니다. 보통 한 가지를 골라 거기에 통합하는 게 운영에 유리합니다.
개인정보 처리가 RUM의 어려운 부분입니다. 입력 필드의 값, URL 파라미터의 토큰, 사용자 식별자 같은 민감 정보가 의도치 않게 수집되지 않도록 마스킹 규칙을 명확히 둬야 합니다.
합성 모니터링
합성 모니터링은 운영 환경에 주기적으로 가상 사용자를 보내, 핵심 시나리오가 살아 있는지 확인합니다. ep.05의 E2E 테스트를 운영 환경에 정기 실행하는 형태와 가깝습니다.
- Checkly, Datadog Synthetic, Pingdom — 전용 서비스
- 자체 Playwright — 직접 워크플로우로 매 5분 주기 실행 후 알림
대표적인 시나리오는 다음과 같습니다.
- 홈페이지가 5초 이내에 200 응답을 주는가
- 로그인 흐름이 끝까지 진행되는가
- 결제 페이지가 정상 렌더링되는가
장점은 사용자보다 먼저 안다는 점입니다. 단점은 가상 사용자 트래픽이 어쩔 수 없이 비용으로 누적된다는 점, 그리고 인증·결제 같은 흐름은 별도 테스트 계정이 필요하다는 점입니다.
알림 - 신호와 소음의 균형
모니터링은 사람이 봐야 의미가 있고, 사람은 알림을 통해 봅니다. 그래서 알림 설계가 운영 모니터링의 절반입니다.
- 에러율 기반 — 새 에러가 100건 이상 또는 발생률이 기준의 N배 증가하면 알림
- 체감 영향 기반 — 영향받은 사용자 수가 기준 이상이면 알림
- 합성 실패 기반 — 핵심 시나리오가 3회 연속 실패하면 알림
알림이 너무 많으면 무시당하고, 너무 적으면 놓칩니다. 하루에 평균 1~2건이 적당하다는 경험칙이 있습니다. 그 이상이면 알림 규칙을 좁히고, 그 이하면 임계치가 너무 느슨한 것입니다.
도구와 예시
도구 선택의 기준은 단순합니다. 한 자리에서 같은 사람이 보는 것이 가장 중요합니다.
- 작은 팀, 통합 선호 → Sentry (에러 + RUM + 트레이스 한 곳에)
- 백엔드 인프라까지 함께 → Datadog (RUM + APM + 인프라 통합)
- 분석 중심 → PostHog (제품 분석 + 세션 리플레이)
처음 도입할 때는 한 가지 도구로 충분합니다. 시간이 지나면서 추가가 필요한 영역이 보일 때 늘려갑니다.
도입 체크리스트
- 에러 추적 도구 도입 (Sentry 무료 플랜부터)
- 빌드에 release 정보 주입 (어떤 버전에서 발생했는지 추적 가능하게)
- 소스맵 업로드 자동화 (스택이 사람에게 의미를 가지려면 필수)
- 알림 채널 결정 (Slack, 이메일, PagerDuty 등) 및 임계치 설정
- 합성 모니터링으로 핵심 흐름 2~3개 (홈, 로그인, 결제)
- 개인정보 마스킹 규칙 합의 및 적용
- 운영 알림을 보고 행동하는 사람·시간 합의 (만들고 안 보면 무의미)
흔한 함정
- 만들어두고 안 본다 — 가장 흔한 실패. Sentry는 켜져 있지만 아무도 안 들여다보는 상태. 매주 한 번이라도 보는 사람이 정해져 있어야 합니다.
- 알림 피로 — 알림이 너무 많아 점점 무시당하다가, 진짜 장애도 놓칩니다. 규칙을 좁히는 게 정답입니다.
- 개인정보 누출 — RUM이나 세션 리플레이가 의도치 않게 비밀번호, 토큰, 주민번호 같은 민감 정보를 수집할 수 있습니다. 마스킹 규칙은 도입 첫 단계에서 점검해야 합니다.
- 모든 에러를 같게 다룬다 —
console.log노이즈와 결제 실패가 같은 채널로 들어오면 신호가 묻힙니다. 영향도로 분류해야 합니다. - 합성만 보고 안심한다 — 합성은 “내가 만든 시나리오”만 봅니다. 사용자가 실제로 하는 것 중 시나리오에 없는 흐름은 못 잡습니다. RUM과 함께 봐야 합니다.
참고 자료
- Sentry. 공식 문서. https://docs.sentry.io
- Datadog. RUM and Session Replay. https://docs.datadoghq.com/real_user_monitoring/
- Checkly. 공식 문서. https://www.checklyhq.com/docs/
- Google SRE Book. “Monitoring Distributed Systems”. https://sre.google/sre-book/monitoring-distributed-systems/
다음 편 예고
여기까지가 시리즈 본편입니다. 마지막 편에서는 지금까지 다룬 모든 테스트를 한 자리에 모아, 우리 팀이 무엇부터 도입하고 어디까지 가져갈지를 결정하는 가이드를 다룹니다.