이벤트는 일어난 일이 아니라 당신이 내린 결정이다

모든 제품은 일어난 일 자체는 무한히 쏟아냅니다. 클릭, 스크롤, 호버, 경로 변경. 이벤트란 그중에서 이름을 붙일 가치가 있다고 당신이 결정한 작은 부분집합입니다. 무언가 행동으로 옮길 근거를 주기 때문에 이름을 붙이는 것이며, 계측 구현이 아니라 바로 이 결정이 일의 본체입니다.

실무적 결론은, 트래킹 플랜이 엔지니어링 문서이기 전에 제품 문서라는 것입니다. 어떤 이벤트가 발생하든 말든 당신의 행동이 달라지지 않는다면, 그 이벤트는 아직 존재할 필요가 없습니다.

인터페이스가 아니라 결과를 기준으로 이름을 붙인다

clicked_blue_button은 디자인이 개편을 배포하는 순간 더 이상 참이 아닙니다. report_exported는 살아남습니다. 사용자가 무엇을 만졌는지가 아니라 무엇을 이뤘는지를 가리키기 때문입니다.

규칙을 하나 정하고 지키세요. 객체 먼저, 동작은 과거형, 소문자와 밑줄 — invite_sent, project_created, payment_failed. 어떤 규칙을 골랐는지보다 일관성이 더 중요합니다. 두 분기만 지나면 이벤트 목록을 검색 불가능하게 만드는 것은 흔들린 명명이기 때문입니다.

그대로 가져다 쓸 수 있는 명명 규칙

대부분의 팀은 규칙을 새로 만들 필요가 없습니다. 적어 두기만 하면 됩니다. 아래 규칙은 외우기 쉬울 만큼 짧고, 이벤트 목록을 검색 가능하게 유지할 만큼 엄격합니다.

규칙이렇게이렇게 하지 않기
객체 먼저, 그다음 동작invite_sentsent_invite
이미 일어난 일이므로 과거형project_createdcreate_project
소문자와 밑줄plan_upgradedPlanUpgraded, plan-upgraded
컨트롤이 아니라 결과에 이름 붙이기report_exportedexport_button_clicked
변형은 속성으로format: csv를 가진 report_exportedreport_exported_csv
이름과 값에 개인정보 넣지 않기plan: teamemail: ana@acme.com

이 규칙을 트래킹 플랜 맨 위에 두고, 코드를 스타일 가이드에 비춰 리뷰하듯 새 이벤트를 이 규칙에 비춰 리뷰하세요. 나쁜 이름의 비용은 누군가 그 이벤트를 검색했다가 찾지 못할 때마다 치르게 됩니다.

이벤트는 200개가 아니라 10~20개

흔한 실패는 나중에 쓸모 있을지 모른다는 논리로 전부 추적하는 것입니다. 그렇게 얻는 것은 아무도 헤아릴 수 없는 목록과, 거의 같은 뜻인 이벤트 세 개와, 무엇이 기준인지에 대한 합의의 부재입니다.

이미 정기 리뷰에서 던지는 질문 — 사람들이 설정을 끝내는가, 다시 오는가, 어디서 포기하는가 — 에서 출발해 그 질문에 답하는 것만 계측하세요. 한 화면에 들어오는 트래킹 플랜은 유지됩니다. 스프레드시트를 채우는 플랜은 유지되지 않습니다.

실전 예시: B2B SaaS 앱의 트래킹 플랜

팀 단위로 쓰는 전형적인 SaaS 제품이라면 이벤트 12개는 이런 모습입니다. 각각은 누군가 이미 주간 리뷰에서 던지는 질문에 답하기 때문에 존재합니다.

이벤트발생 시점주요 속성답하는 질문
signup_completed폼을 제출했을 때가 아니라 계정이 실제로 생성됐을 때source끝까지 가입을 마치는 사람은 어떤 채널에서 오는가?
workspace_created첫 워크스페이스가 저장될 때team_size가입자 중 설정 단계까지 가는 사람은 얼마나 되는가?
teammate_invited초대가 발송될 때role계정이 한 사람을 넘어 퍼지고 있는가?
invite_accepted초대받은 사람이 합류할 때role초대가 실제 팀원으로 이어지는가?
integration_connected연동이 성공할 때integration계속 남는 팀은 어떤 연동을 쓰는가?
project_created프로젝트가 저장될 때template핵심 객체가 애초에 만들어지고 있는가?
report_viewed리포트 렌더링이 끝났을 때report_type사람들은 무엇을 다시 보러 오는가?
report_exported파일이 생성될 때format결과물이 제품 밖으로 나가고 있는가?
plan_upgraded결제 시스템이 변경을 확정할 때from_plan, to_plan더 많이 결제하기 직전에 무슨 일이 일어나는가?
payment_failed결제 제공업체가 실패를 알릴 때reason비자발적 이탈은 얼마나 되는가?
subscription_cancelled해지가 실제로 적용될 때reason팀은 왜 떠나는가?
feedback_submitted피드백 폼이 전송될 때category사용자는 자기 말로 무엇을 요청하는가?

눈여겨볼 점이 두 가지 있습니다. 대부분은 클릭이 아니라 결과에서 발생합니다. 초대 버튼을 눌러도 초대는 실패할 수 있습니다. 그리고 결제 이벤트는 아예 브라우저에서 일어나지 않습니다. 결제 제공업체의 웹훅으로 들어오므로, 브라우저만 보는 분석 도구는 이를 절대 볼 수 없습니다. “업그레이드” 클릭을 매출로 취급하지만 않는다면 문제없습니다.

활성화(activation)는 보통 이 중 하나가 아니라 여러 이벤트의 조합입니다. 예를 들어 첫 주 안에 워크스페이스를 만들고 팀원을 초대한 경우입니다. 이 정의는 의도를 갖고 고르세요. 방법은 활성화 퍼널 벤치마크에서 다룹니다.

세부는 속성이, 동사는 이벤트가 담는다

변형마다 이벤트를 따로 만들고 싶은 충동을 참으세요. report_exported_csv, report_exported_pdf, report_exported_xlsx는 format 속성을 가진 하나의 이벤트 report_exported여야 합니다. 판단 기준은 단순합니다. 언젠가 숫자를 합쳐서 보고 싶을 것 같다면, 그것은 속성을 가진 하나의 이벤트입니다.

속성 값은 카디널리티를 낮게, 안정적으로 유지하세요. 원본 URL이나 자유 입력 문자열을 담은 속성은 그룹화할 수 없는 열이고, 그러면 데이터가 아니라 장식이 됩니다.

리포트를 조용히 망가뜨리는 이벤트 추적 실수

  • 결과가 아니라 클릭에서 발생시키기. “내보내기” 클릭은 내보내기가 아닙니다. 요청이 실패하면 이벤트는 이미 거짓말을 한 셈입니다. 결과 이벤트는 실제로 성공한 뒤에 보내세요.
  • 싱글 페이지 앱에서의 중복 발생. 다시 렌더링되는 컴포넌트나 두 번 마운트되는 라우트는 같은 이벤트를 두 번 보낼 수 있습니다. 수치를 믿기 전에 몇 개 세션을 직접 확인하세요.
  • 속성에 담긴 개인정보. 이메일, 이름, 쿼리 문자열에 토큰이 든 URL은 모든 리포트와 모든 내보내기에 남습니다. 대신 ID나 카테고리를 보내세요.
  • 동의 전에 추적하기. GDPR이 적용되는 곳에서는 방문자가 동의하기 전까지 분석이 시작되면 안 됩니다. 이것은 이벤트 하나하나가 아니라 설정 전체의 문제이므로, 동의할 때까지 추적을 보류하는 쿠키 동의 관리로 한 번에 해결하세요.
  • 이름은 그대로 두고 이벤트의 의미 바꾸기. project_created가 복제된 프로젝트까지 세기 시작하면, 변경 전후의 모든 차트가 어긋나고 아무도 이유를 알 수 없습니다. 새 의미에는 새 이름을 주거나, 둘을 구분하는 속성을 붙이세요.
  • 담당자 없는 이벤트. 플랜의 모든 이벤트에는 그것이 멈췄을 때 알아차릴 사람이 필요합니다. 담당자 없는 이벤트가 가장 먼저 망가지고, 가장 오래 신뢰받습니다.

자동 수집과 명시적 이벤트는 서로 다른 질문에 답한다

자동 수집은 계획을 요구하지 않고 화면 상호작용을 기록합니다. 초기에는 정말 유용합니다. 아직 떠올리지 못한 질문의 데이터가 이미 존재하고, 확인할 때마다 배포를 거칠 필요가 없어지기 때문입니다. 다만 당신의 도메인을 알지는 못합니다. 클릭 기록 어디에도 구독이 상위 플랜으로 변경되었다는 사실은 없습니다.

현실적인 구성은 둘 다 쓰는 것입니다. 탐색과 아직 던지지 않은 질문을 위한 자동 수집, 그리고 보고하고 목표를 세우는 수치를 위한, 잘 이름 붙인 소수의 명시적 도메인 이벤트.

이벤트를 나중에 정의하기

자동 수집은 질문을 “이걸 계측하는 걸 잊지 않았나?”에서 “수집된 데이터에서 찾을 수 있나?”로 바꿉니다. PulsePanda는 모든 클릭을 요소의 id, 클래스, 보이는 텍스트, 태그, 페이지 안의 위치와 함께 기록합니다. 그래서 이벤트를 나중에 이 정보로 정의할 수 있고, 그 정의는 정의하기 전에 수집된 클릭에도 적용됩니다. 목요일에 떠오른 질문에 월요일 데이터로 답할 수 있습니다.

이것을 믿을 수 있게 만드는 것은 마크업 안의 안정적인 기준점입니다. 클래스는 디자인 개편마다 바뀌고, 보이는 텍스트는 문구 수정과 번역마다 바뀝니다. 중요한 몇몇 컨트롤에 붙인 id는 누군가 바꾸기로 결정할 때만 바뀝니다.

<button id="export-report">Export</button>
<button id="invite-teammate">Invite</button>
<a id="upgrade-plan" href="/ko/billing">Upgrade</a>

#export-report 클릭으로 정의한 이벤트는 디자인 개편에도 살아남고, 버튼 안의 아이콘이나 라벨을 클릭해도 집계됩니다. 기록된 경로가 id를 가진 가장 가까운 요소까지 거슬러 올라가기 때문입니다.

정의된 이벤트도 여전히 클릭이며, 앞서 말한 한계도 그대로입니다. 누군가 시도했다는 것은 알려 주지만, 성공했다는 것은 알려 주지 않습니다. 결과를 보려면 성공 후에 도달하는 페이지가 더 정직한 신호인 경우가 많습니다. “/signup 도달” 다음에 “/onboarding 도달”이라는 퍼널 단계는 이벤트 하나 없이도 완료된 가입을 셉니다.

페이지 단계로 만든 PulsePanda 퍼널. 요금제 보기, 가입 시작, 온보딩 도달, 첫 프로젝트 생성으로 이어지는 방문자 수와 각 단계의 이탈을 보여 줍니다
도달한 페이지만으로 만든 퍼널입니다. 각 막대는 이전 페이지 다음에 그 페이지에 도달한 방문자이고, 막대 사이의 차이가 방문자가 떠난 지점입니다.

이벤트를 믿기 전에 확인하는 방법

  1. 직접 발생시키고 자신의 세션을 찾으세요. 이벤트는 한 번만, 모든 속성이 채워진 채로 나타나야 합니다.
  2. 기준이 되는 원천 데이터와 수치를 비교하세요. 데이터베이스에는 지난주 프로젝트 140개가 생성됐는데 분석 도구에는 95개라면, 누군가 그 위에 차트를 만들기 전에 차이를 찾으세요. 광고 차단기, 동의, 실패한 요청은 모두 브라우저 집계를 서버 집계보다 낮게 만듭니다. 차이는 뜻밖의 것이 아니라 일정해야 합니다.
  3. 이벤트가 발생한 세션 리플레이를 보세요. 숫자는 그것이 일어났다는 것을, 녹화는 그것이 당신이 생각한 시점에 일어났다는 것을 알려 줍니다.
  4. 퍼널에 넣어 보세요. 반드시 앞서야 하는 단계 없이 나타나는 이벤트는 잘못된 곳에서 발생하고 있습니다.

이번 주에 어디서 시작할까

제품에서 가장 중요한 다섯 순간을 적고, 위 규칙으로 이름을 붙이고, 그것만 계측하세요. 그리고 일주일 뒤에 각각이 기대한 시점에 발생하는지, 속성이 채워져 있는지 확인하세요. 아무도 지나지 않는 코드 경로에서 발생하는 이벤트는 이벤트가 없는 것보다 나쁩니다. 신뢰받을 것이기 때문입니다.

더 추가하기 전에 이미 보내고 있는 이벤트가 어떻게 동작하는지 보고 싶다면, PulsePanda의 이벤트 추적이 모든 이벤트와 그 볼륨, 속성을 한곳에 보여 주고, 같은 데이터를 그대로 퍼널과 경로로 흘려보냅니다.