정의
버튼 클릭·결제 시작·로그인 성공 같은 제품 의도를 분석 도구에 보낼 때, 화면 코드가 Google 태그 매니저(GTM)·PostHog 같은 벤더 SDK를 직접 부르지 않고, useTelemetry().track(...) 같은 하나의 API만 쓰게 하는 설계다.
파사드(facade) 는 복잡한 배관 앞에 둔 단순한 창구다. 팬아웃(fan-out) 은 한 번의 track 호출이 여러 싱크(sink) — 데이터를 받는 시스템 — 로 복제되는 것이다.
왜 필요한가
콜사이트마다 posthog.capture와 dataLayer.push를 섞으면 (1) 한쪽 싱크에만 이벤트가 가고, (2) 싱크 교체 시 앱 전체를 고쳐야 하며, (3) SDK 예외가 결제·로그인 흐름을 깨뜨릴 수 있다. 파사드는 소비처는 의도만 말하고, init·라우팅·마스킹은 Provider가 소유하게 한다.
동작 원리
TelemetryProvider가 싱크를 초기화하고 컨텍스트로 액션을 제공한다.track({ event, ...props })→ 1차 싱크(예: dataLayer) push → 규칙에 맞는 이벤트만 2차 싱크(예: PostHog)로 라우팅.identify(userId, traits)/reset()으로 로그인·로그아웃 경계를 맞춘다.- 싱크마다 독립 env 게이트(키가 없으면 해당 싱크만 no-op).
- 모든 싱크 호출은 try/catch best-effort — 분석 실패가 비즈니스 로직을 중단하지 않음.
실무 적용
- 신규 이벤트는 훅만 경유하도록 코드리뷰·린트(벤더 SDK import 금지 목록).
- autocapture를 끄고 명시적 track만 쓰면 노이즈·한도를 통제하기 쉽다.
- 세션 리플레이를 쓸 경우 입력·이미지 등 마스킹 기본값을 init에 둔다.
- export만 되고 소비처가 0인 헬퍼는 데드 경로 — 문서에 Non-goal로 적어 이식 시 되살리지 않는다.
트레이드오프
| 선택 | 장점 | 비용 |
|---|---|---|
| 단일 파사드 | 도달 일관성·교체 용이 | Provider 설계·테스트 필요 |
| 콜사이트 직접 SDK | 단기 빠름 | 드리프트·예외 전파 |
| best-effort 삼킴 | UX 보호 | 실패가 조용 — 대시보드 스모크 필요 |
사용하면 안 되는 경우
- 서버 감사 로그·결제 원장처럼 유실이 허용되지 않는 기록(클라이언트 분석 계층에 맡기지 말 것).
- 개인정보를 props에 실어 여러 싱크로 무분별 복제하는 경우(스키마·마스킹 먼저).
흔한 실수
capturePostHog와track을 혼용 → GTM 미도달.- 로그아웃에
reset을 빼 이전 유저 세션이 이어짐. - 테스트에서 분석 mock이 throw 하는데 try/catch가 없어 결제 테스트가 빨간불.
관련 개념
- react-context-render-granularity — Provider로 액션을 주입할 때 렌더 범위