Mixpanel은 Google Analytics와 비슷한 기능을 하는 도구로 웹과 모바일 애플리케이션에서 사용자 데이터를 로깅하고 사용 패턴을 추적하는 도구입니다.
매트릭 스튜디오와 협업하며 적용하게 되었고, 저희 회사는 특이하게 GA와 mixpanel을 한번에 적용할 수 있게 라이브러리화하는 과정을 거쳤고 mixpanel에 대한 설명과 라이브러리에 대한 설명을 동료분들께서 쉽게 이해하시도록 문서화한 김에 블로그에도 남기게 되었습니다.
mixpanel과 저희 라이브러리에 대한 설명보다 그 후에 나오는 제가 어떻게 협업을 했는지에 관한 부분이 다른 분들께는 더 도움되시리라고 생각합니다.
// mixpanel.identify : 유저의 아이디를 부여합니다.
mixpanel.identify("13793");
// mixpanel.people.set
var user_properties = {
"$email": "doojoon.yoon@gmail.com",
"$name": "윤두준",
"$phone": "+82-10-1234-1233",
"gender": "남성",
"birth_year": 1984,
"job": "엔지니어",
//....
};
mixpanel.people.set(user_properties);
// mixpanel.people.union
mixpanel.people.union('joined_workspace', '내 일터');
// mixpanel.people.increment
mixpanel.people.increment(
{ "total_payment_amount": 396000}
);
//decrement
mixpanel.people.increment(
{ "total_payment_amount": -396000}
);
// mixpanel.people.increment
mixpanel.people.track_charge(396000);
var event_name = 'program_page_viewed'
var params = {
"program_type" : '기업 프로그램'
}
// 파라미터가 없는 경우
mixpanel.track(event_name);
// 파라미터가 있는경우
mixpanel.track(event_name, params);
위의 이벤트들을 사용했고, 이 이벤트들을 기반으로 다른 로깅 시스템과 동시에 적용할 수 있도록 라이브러리화했습니다.
대단한 적용은 아니지만 라이브러리화라는 것이 결국 대단하지 않아도 우리가 편하게 사용할 수 있다는 것으로 의미가 있다는 걸 처음으로 깨닫게 되었던 작업이었습니다.
public한 작업물들은 아직 아니기때문에 몇 가지만 소개하도록 하겠습니다. 라이브러리 이름도 혹시나하여 그냥 Tracking이라고 지칭하겠습니다. (물론 이 이외에 라이브러리 자체가 작동하도록 하는 로직들이 있습니다. public한 작업물들이 아니기때문에 mixpanel과 관련된 정말 일부분만 작성했습니다.)
mixpanel.indentify에 해당하며 application의 최상단에서 한번 실행하게 됩니다. 넘겨주는 값은 unique한 값으로 유저를 식별할 수 있는 값입니다.
interface TrackingSetUserProps {
userId?: string;
username?: string;
email?: string;
}
setUser(props: TrackingSetUserProps): void {
if (typeof window === 'undefined') {
return;
}
this.mixpanel.identify(props.userId);
}
Example
ut.setUser({ userId: id })
mixpanel.people.set에 해당하며 application 최상단에서 user 정보가 변경(로그인, 내 정보 변경하기)될 때 실행되게 됩니다.
interface TrackingSetUserPropertiesProps {
params: Record<string, unknown>;
}
setUserProperties(props: TrackingSetUserPropertiesProps): void {
this.mixpanel.people.set(props.params);
}
Example
ut.setUserProperties({
params: {
$email: email,
$phone: profile.phone,
$name: profile.name,
gender: profile.gender,
// ...
},
});
mixpanel.track에 해당합니다.
interface TrackingEventProps {
action: string;
params: Record<string, unknown>;
}
event(props: TrackingEventProps): void {
this.mixpanel.track(props.action, props.params);
}
Example
ut.event({
action: 'workspace_page_viewed',
params: {
workspace_id: shorty_id,
workspace_name: name,
tab_name: getWorkspaceTabName(pathname),
},
});
dev tool의 network 탭에서 ?verbose로 시작하는 request를 확인합니다. payload의 data에서 내가 보낸 이벤트 이름과 properties가 제대로 찍히는지 확인합니다.
아래 예시는 저희 회사 작업물과 관련있는 예시라 workspace 같은 특정 단어가 사용되고 있지만 상황과 판단을 통해 개선이 이뤄져 나가는 방식은 동일하다고 생각하여 변경하지 않았습니다.
상황: 초반에는 user가 로그인했을 때, 기업(workspace) 페이지 사용여부와 관계없이 모든 워크스페이스 정보를 수집하고 있었음. 문제는 workspace 진입시에도 mixpanel.union으로 workspace 이름을 수집하기 때문에 중복이라고 파악
판단: 모든 워크스페이스 정보를 유저 로그인이나 회원가입 시에 받아오려면 추가적인 api 호출이 필요하기도 하고, 기업 사용자가 아닐 경우도 크기 때문에 workspace 정보들을 최상위단에서 user 정보와 함께 저장하는 것 자체가 people.set과 적합하지 않은 정보라고 판단하여 workspace 페이지를 입장했을 때 로깅하는게 어떤지 문의
문의 방법: 문의를 할 때는 더 나은 제시사항이 있을때 그것과 같이 전달할 것
결과: 메트릭쪽에서도 동의하여 해당 property를 제외하고 workspace 진입시 union을 통해서 받기로 함
사실 가장 자랑하고 싶었던 부분입니다. (부끄부끄;;;;)
작업시에 주어진 대로 단순히 로깅하는게 아니라 해당 페이지에 필요한 정보가 맞는지 아니라면 어디가 더 적합할지 적극적으로 소통하면서 작업했고 위와 같은 피드백을 받았습니다.
추가적으로 제 작업속도가 궁금해서 여쭈어보니 아래와 같은 피드백을 주셨습니다. (혼자서 작업했습니다 찡긋!ㅎㅎ)
이 작업을 통해서 개발자가 아닌 분과도 유연하게 일할 수 있다는 증명을 해낸 것 같아 정말 뿌듯했던 작업이었고 기억하고 싶어서 글로 남기게 되었습니다.