안녕하세요. 스포카의 데이터 분석가 양현승(todd)입니다. 😄
키친보드 서비스(Android, iOS) 이벤트 로그를 새로 설계하게 된 과정을 공유하려고 합니다.
로그 설계의 필요성은 많이 느꼈지만, 경험이 없었기 때문에 어떻게 시작해야할지 막막하고 걱정이 앞섰습니다.
또한 이미 조직에 로그 체계가 있었기 때문에, 기존 로그 체계의 데이터를 새로운 체계로 이전하는 과정에서 데이터 무결성 및 기타 이슈들을 고려해야했습니다.
돌이켜보면, 동료들과 함께 패기와 열정으로 해낸 것 같습니다.
이 글이 이벤트 로그 체계를 새로 구축하거나, 개편할 계획이 있는 분들에게 도움이 되면 좋겠습니다.
예상 독자는 아래와 같습니다.
- 이벤트 로그 설계 경험이 없는 분
- 기존 로그 체계를 바꾸고 싶은 분
- 스포카의 이벤트 로그 체계가 궁금하신 분
목차
배경
스포카는 firebase를 활용하여 로그를 수집하고 있습니다.
이벤트 로그 설계 및 관리는 PO, PM분들께서 구글 시트에서 해주셨습니다.
기존 설계 문서는 스크린(화면)과 이벤트 로그를 시트로 나눠서 기록하고 있었습니다.
스크린 정리 시트는 아래와 같이 크게 3가지가 기록되어 있습니다.
- 스크린별 한글/영문명 (Camel case)
- 구현해야하는 대상 (웹/앱)
- 이벤트 저장 시점
이벤트 로그 정리 시트는 아래와 같이 크게 6가지로 구성되어 있습니다.
- 스크린 영문명 (Camel case)
- action에 대한 설명
- 이벤트명 (snake_case)
- 이벤트 형식
- 이벤트 파라미터 (snake_case)
- 수집 목적
기존 로그 체계와 문서는 잘 구축되었지만, 3가지 불편함이 있었습니다.
1. 부족한 데이터
“데이터 분석가님 이거 확인해 줄 수 있나요?
”
분석 요청이 들어오면 회사의 데이터 구조가 더 빨리 보입니다.
요청 사항을 시행하기 위해 로그 문서를 찾아보면 수집이 안된 경우가 많았습니다.
추가적으로 필요한 데이터는 크게 3가지 종류였습니다.
- 이벤트 버튼의 위치 (ex. 상/하단, 버튼 index 등)
- 서버에 저장된 테이블과 연동할 수 있는 id 값
- 누락된 이벤트 (ex. scroll, 특정 버튼 등)
보통 당장 쓰일 수 있는 데이터만 수집하고, 나머지 데이터는 사용 목적을 모르거나 저장 공간 낭비로 여겨지기 때문에 누락되는 것 같습니다.
유저의 모든 행동 데이터를 기록해 두면 이탈이 발생한 지점에서 어떤 행동을 했는지 자세하게 알 수 있습니다.
또한 각 스크린별 유저의 행동을 추적하면서, 생각하지 못한 인사이트를 얻을 수도 있습니다.
서버 테이블과 연동할 수 있는 id 값이 있다면, 이상 지점에서 발생한 유저들의 행동을 쉽게 확인할 수 있습니다.
“어떻게 하면 분석을 더 잘 할 수 있는 데이터를 모을 수 있을까요?
”
2. 분리된 문서
“xx 화면에서 xx 버튼 클릭하는 로그가 어디있나요?
”
특정 기능을 하는 이벤트가 어느 화면에 어떤 부분인지 알기 어려운 경우가 많았습니다.
로그 문서와 Figma가 독립적으로 관리되고 있었기 때문입니다.
신규 입사자와 같이 서비스에 익숙하지 않거나, Figma와 로그 문서에 익숙하지 않은 경우 헤매기 쉬울 것 같았습니다.
또한 잘 쓰지 않는 로그는 시간이 지나면 잊어버려서 다시 문서를 찾고 있었습니다.
이벤트 로그에 대한 질문이 있을 때마다, PO/PM과 PD가 시간을 할애해야 했다는 느낌이 들었습니다.
(너무 간단한 질문이라 조금 눈치도 보였습니다.. 😥)
로그 관련 질문 프로세스는 보통 아래와 같습니다.
“어떻게 하면 모두가 이해하기 쉽게 문서를 만들 수 있을까요?
”
3. 디버깅의 어려움
“OO개발자님! XX유저는 이 시간대에 서버에는 데이터가 있는데 왜 이벤트 로그가 없을까요?
”
사실 이벤트 로그는 생각보다 손실이 많이 발생합니다.
유저의 네트워크, 단말 문제 등 알 수 없는 요인이 있습니다.
그렇다고, “아 그냥 누락되었나 보다”라고 생각하고 넘어갈 수는 없습니다.
“OO개발자님! A이벤트는 B화면에서 발생해야 하는데 왜 C화면이라고 데이터가 저장되어 있나요?
”
또한 이벤트는 유저가 액션을 하는 타이밍 이슈에 따라 view 로그 데이터가 누락될 수 있습니다.
너무 빨리 버튼을 누르거나, 탭 전환을 하는 경우에는 view 로그를 남겨서 firebase에 보내기도 전에 다른 이벤트가 발생하기 때문입니다.
이벤트명을 보고 유추할 수 있지만, 다양한 스크린에서 공통적으로 쓰는 로그는 확인이 어려울 수 있습니다.
“어떻게 하면 특정 문제가 생겼을 때, 최대한 디버깅이 가능하도록 정보를 수집할 수 있을까요?
”
이벤트 로그 설계 과정
불편했던 3가지를 해결할 수 있는 방향을 찾기로 했습니다.
- 어떻게 하면 분석을 더 잘할 수 있는 데이터를 모을 수 있을까요?
- 어떻게 하면 모두가 이해하기 쉽게 문서를 만들 수 있을까요?
- 어떻게 하면 특정 문제가 생겼을 때, 최대한 디버깅이 가능하도록 정보를 수집할 수 있을까요?
스포카는 개발자(웹/앱)분들이 Firebase 로그를 보내면, GA4에서 데이터를 받아서 BigQuery로 전달하는 과정을 가집니다. Firebase 형식을 참고하고, 기본적으로 제공하는 정보를 고려해서 설계했습니다.
로그 설계 문서는 구글 시트를 활용했습니다. 구글 시트를 사용한 이유는 총 3가지입니다.
- 다른 팀과 쉽게 공유할 수 있으며,
- 동시 수정 및 코멘트 기능이 있고,
- 수식을 활용하여 자동화하기 좋기 때문입니다.
시트는 크게 5가지 형식으로 구분되어 있습니다.
- Screen: 모든 스크린 정보 저장
- Variable: 모든 변수 정보 및 데이터 타입 저장
- Screen별 Event: 특정 스크린에서 발생하는 이벤트 파라미터 정보 저장
- Event Total: 모든 이벤트 파라미터 정보 저장
- Update: 이벤트 로그 관련 작업에 대한 요청사항을 정리
설계를 하면서 도움이 많이 되었던 내용은 아래 “추천 자료”에 기재해 두었습니다.
각 형식별 자세한 설명을 하겠습니다.
Screen
Screen 시트는 app과 webview의 모든 스크린 정보를 모아두는 테이블입니다.
모든 스크린과 이벤트의 명칭은 snake case로 적었습니다.
각 구성 요소의 의미는 다음과 같습니다.
- use: 스크린 사용 여부
- screen_name: 스크린명
- service_name: 서비스 영문명 (ex. KITCHENBOARD-STORE)
- service_name_kr: 서비스 한글명 (ex. 키친보드 매장앱)
- function: 기능 영문명 (ex. CHAT)
- function_kr: 기능 한글명 (ex. 채팅)
- platform: webview / web / app(native) 구분
- firebase_screen_class: firebase용 스크린 영문명
- firebase_screen: firebase용 스크린 한글명
- sheet_name: “Screen별 Event” 시트명 및 링크
- action_plan: 해당 스크린의 이벤트 로그를 어떻게 활용할 것인지 간략하게 정리
- comment: 업데이트 날짜, 특이사항 기록
service_name, function과 screen_name은 이벤트 로그의 카테고리라고 생각하시면 될 것 같습니다.
service_name은 대분류, function은 중분류, screen_name은 소분류의 성격을 갖고 있습니다.
firebase_screen_class와 firebase_screen은 firebase를 사용하기 때문에 전달하는 값입니다.
firebase에 두 값을 보내면, view 이벤트가 발생했을 때 이전 스크린의 정보 값을 알 수 있습니다.
(firebase_previous_class, firebase_previous_screen)
각 스크린별 이벤트를 잡기 전에 해당 스크린을 어떻게 활용할 것인지 action_plan에 간략하게 정리하면, 활용 목적에 따라 어떤 이벤트 로그를 잡아야 하는지 명확해지고 히스토리로도 활용할 수 있습니다.
sheet_name은 “service_name / function / screen_name”으로 구성했으며,
“Screen별 Event” 연결 링크를 첨부하여 이동이 편리하게 설정했습니다.
Variable
Variable 시트는 모든 속성들의 정보를 저장하는 시트입니다.
구성 요소는 다음과 같습니다.
- category: 변수 카테고리
- variable: 변수명
- data_type: 변수 데이터 타입
- description: 변수 설명
- variable_size: 변수명 길이
- comment: 업데이트 날짜, 특이사항 기록
category는 이벤트의 용도를 그룹화해서 정보를 분리할 수 있습니다.
- action: 유저의 행동 (ex. view, click, scroll, search)
- user_properties: 유저의 정보 (ex. 고객 id, 고객명, 주소, 업종 등)
- object_section: 이벤트가 위치하고 있는 곳에 대한 정보 (ex. gnb, lnb, fnb 등)
- object_type: 이벤트의 유형 (ex. button, banner 등)
- object_id: 이벤트의 유형 id (ex. banner_id 등)
- object_name: 이벤트 명칭 (ex. next, close, back 등)
- object_position: 이벤트의 index (ex. 버튼이 세로로 4개가 있고, 첫 번째 버튼을 클릭한다면 0)
- event_properties: 각 이벤트별 보유하고 있는 정보 (ex. 주문서 id, 주문 수량, 결제액 등)
Firebase에서 기본적으로 제공하는 값은 문서에서 제외했습니다.
대표적인 데이터는 앱 인스턴스 ID(user_pseudo_id), 이벤트 실행 시간(event_timtestamp),
유저 처음 앱 실행 시간(user_first_touch_timestamp), 디바이스 정보(브랜드명, 모델명 등),
앱 정보(버전 등) 등이 있습니다.
firebase 정책 상, 변수의 길이는 24자 이하를 만족해야 로그가 쌓입니다. (Firebase 참고 문서)
variable_size의 길이가 넘지 않도록 주의해야 하기 때문에, 조건부 서식 같이 눈에 보이는 장치를 추가하는 것이 좋습니다.
Screen별 Event
세부적인 이벤트들은 Screen별 분리해서 정리했습니다.
Screen의 Figma 디자인과 이벤트를 관리하기 편하기 때문입니다.
왼쪽 상단에는 바로가기 기능을 만들었습니다.
- Home: Screen 시트로 이동
- Total: 모든 이벤트를 모아둔 시트(Event Total)로 이동
- Figma: 해당 화면의 Figma 시안 링크
중앙에는 Figma 시안을 추가했습니다.
시안을 Figma에 접속해서 따로 확인하면서 로그를 설계할 필요가 없어졌습니다.
하단에는 수집할 이벤트를 정리했습니다.
- use: 이벤트 사용 여부
- event_name: 이벤트명
- scenario: 유저 시나리오
- comment: 업데이트 날짜, 특이사항 기록
event_name은 아래와 같은 형식으로 구성됩니다.
“screen_name + __ + action + __ + object_name
”
event_name은 자세하게 하는 방법과 축약해서 공통적으로 사용하는 방법이 있습니다.
각각 장단점이 있지만, 이벤트명을 보면 어떤 기능을 하는지 직관적으로 이해하기 위해 위 방식을 사용했습니다.
단, view는 screen_view로 통일된 명칭을 사용합니다.
Firebase를 활용하면서 앱 개발자가 firebase_screen_class를 업데이트하면 자동적으로 찍히기 때문에, Firebase에서 제공하는 명칭을 이용했습니다.
Event Total
모든 스크린의 이벤트를 모아둔 시트입니다. 샘플은 아래와 같습니다.
Screen별 Event 시트의 구성요소와 별개로 2가지 요소가 추가되어있습니다.
- length_event_name: 이벤트명 길이
- count_event_keys: event_properties에 포함된 key 개수
Firebase는 이벤트명의 길이가 40자가 넘어가면 로그가 저장되지 않습니다.
따라서 이벤트명의 길이를 확인하는 과정이 별도로 필요합니다.
이 시트에서는 40자가 넘어가면 조건부 서식으로 행을 음영처리하여 작업자가 확인 가능하도록 세팅했습니다. (Firebase 참고 문서)
Update
체계가 구축된 이후, 변경/추가/삭제가 필요한 로그는 update 시트에서 논의합니다.
샘플은 아래와 같습니다.
구성 요소는 다음과 같습니다.
- done: 검증 완료 여부
- dev (iOS, Android): 개발용 버전 로그 검증 여부
- qa (iOS, Android): QA 버전 로그 검증 여부
- 요청자
- 작업자
- version (app/web)
- attribute: 추가/변경하는 속성 (ex. user_properties)
- variable / event_name: 변수 or 이벤트명
- purpose: 로그를 추가/변경/삭제하는 목적
- comment: 업데이트/요청 날짜, 특이사항 기록
요청자(ex. 데이터 분석가, PM)는 변경할 작업에 대한 설명과 목적을 적은 후,
작업자(ex. 프론트엔드, 앱 개발자)에게 공지를 합니다.
개발자가 편리하게 작업의 내용을 확인할 수 있게 “variable / event_name” 칼럼에 링크를 걸어두는 것이 좋습니다.
작업자가 개발을 완료한 경우, 개발/QA 버전별 검증을 진행합니다.
모든 검증이 완료한 경우, done에 체크를 함으로써 해당 이벤트 작업이 종료됩니다.
로그 검증
기존 로그 체계를 새롭게 개편했기 때문에, 과거의 로그가 누락되지 않았는지 확인했습니다.
또한 모든 로그 데이터가 잘 수집되는지 검증을 해야 했습니다.
만약 X개의 로그가 쌓였다면, 총 2X개의 로그를 검증해야 합니다. (iOS, Android)
QA팀에서 정말 많은 도움을 주셔서 해결할 수 있었지만, 이 과정을 최대한 자동화하고 싶었습니다.
“우리가 설계한 로그 스키마와 수집된 로그 데이터가 동일한지 체크할 수 있지 않을까?”
구글 시트에 정리한 스키마와 BigQuery에 저장된 결과물을 Redash를 활용하여 비교했습니다.
검증 방식은 2가지 프로세스를 진행됩니다.
- 플랫폼(iOS, Android) 별 이벤트 key 검토
→ 스키마와 다를 경우, 개발자에게 검토 요청 - 플랫폼(iOS, Android) 별 이벤트 value 검토
→ 올바른 데이터가 적재되었는지 데이터 분석가가 검토
위 방식을 통해 수많은 이벤트들을 더 편하게 검증할 수 있었고, 시간도 아낄 수 있었습니다.
개선 효과
작업을 시작하기 전에 느꼈던 불편함은 아래의 방법으로 해결했습니다.
- 어떻게 하면 분석을 더 잘할 수 있는 데이터를 모을 수 있을까요?
- 이벤트 버튼의 위치 (ex. object_section, object_position 등) 정보 저장
- 서버에 저장된 테이블과 연동할 수 있는 id 값 저장
- scroll, 누락된 이벤트 잡기
- 어떻게 하면 모두가 이해하기 쉽게 문서를 만들 수 있을까요?
- 스크린별 분리하여 구글 시트에 저장
- 스크린별 해당하는 Figma 시안 저장 및 연동
- 스크린별 유저 시나리오 저장
- 어떻게 하면 특정 문제가 생겼을 때, 최대한 디버깅이 가능하도록 정보를 수집할 수 있을까요?
- 직관적인 이벤트명 설정
- 스크린명 ↔ firebase_screen_class를 비교하여 어느 point에서 오류가 생기는지 확인
- Redash 검증 대시보드
추가적으로 문서를 생성할 때, 서비스의 확장성과 관리의 편리함도 고려했습니다.
하나의 문서로 이벤트 로그 설계를 관리할 수 있다는 점이 가장 좋았던 것 같습니다.
회고
스포카에는 프로젝트가 끝나면 회고를 하는 문화가 있습니다.
프로젝트에 참여한 구성원들과 모여서 4L 방식으로 진행했습니다.
많은 의견이 있었지만, 그중 기억에 남는 한 가지씩을 소개하겠습니다.
- Liked (좋았던 점)
- 참석자 V: 모두가 보기에 직관적인 앱 로그 시트, 드디어 숙원 사업 clear!!
- Learned (배운 점)
- 참석자 A: Firebase의 제한점과 한계점을 배울 수 있었음
- Lacked (아쉬웠던 점)
- 참석자 M: 작업 중 변경된 내용이 잘 공유되지 않아서 아쉬웠음
- Longed for (앞으로 바라는 점)
- 참석자 E: 로그 변경 건의 태스크화
회고를 통해 프로젝트에 대해 고생한 모두 함께 격려했고,
부족한 점과 해결 방안을 고민하면서 이벤트 로그 작업이 나아갈 방향을 찾게 되었습니다.
(Update 시트는 회고를 통해서 새로 생성할 수 있었습니다)
마무리
우여곡절이 정말 많았던 프로젝트였지만,
훌륭한 동료분들과 함께 즐겁게 할 수 있어서 제 인생에서 가장 행복한 프로젝트였습니다.
FE 개발자 한 분이 작업이 끝나고 이렇게 말씀해 주셨습니다.
저는 토드님이 생각하시는 것 이상으로 이벤트 로그 작업이 즐거웠어요
로그 체계를 구축하고 설계하는 과정은 처음이라 서툴고 두려웠지만
동료들과 함께한다면 어떤 일이든 해낼 수 있다는 생각을 하게 되었습니다.
앞으로도 좋은 콘텐츠가 있다면 공유하겠습니다.
긴 글 읽어주셔서 감사합니다 🙇🏻♂️
추천 자료
- 모두의 요금제 “임광빈”님의 Data-driven Product를 위한 분석 설계 : 지표, 로그, A/B test 강의
- 쏘카, 타다 출신 “변성윤”님의 PM을 위한 데이터 리터러시(프러덕트 데이터 분석) 강의와 블로그 자료
스포카에서는 “식자재 시장을 디지털화한다” 라는 슬로건 아래, 매장과 식자재 유통사에 도움되는 여러 솔루션들을 개발하고 있습니다.
더 나은 제품으로 세상을 바꾸는 성장의 과정에 동참 하실 분들은 채용 정보 페이지를 확인해주세요!