동기 / Amplitude란?
대표적인 사용자 분석 도구입니다!
리텐션 파악에 용이하고, 유저 행동을 '이벤트'라는 이름의 로그로 찍을 수 있습니다.
그래서 유저가 어떤 기능을 어떤 경로로 이용하는지, 어디서 앱을 이탈하는지 등 세세한 추적이 가능해요.
아직 실사용자가 많은 앱은 아니지만, 미리 앰플리튜드를 심어두어야 유저가 모인 후에 원활하게 지표를 분석할 수 있어요!
그래서 제가 먼저 PD분께 제안하고, 이벤트를 설계해 구현해보았습니다.
이벤트 설계
1. 이벤트/프로퍼티 모두 snake_case 사용 (소문자, 언더바만 사용)
2. 닉네임 등 사용자가 직접 입력한 값을 프로퍼티로 보내는 경우, 대소문자 신경쓰지 않고 있는 그대로 전송
3. 이벤트명은 동사_명사 id값은 String으로 변환해 전송
제가 세운 규칙이고, 일반적으로도 snake_case를 사용한다고 해요.
저는 가능한 모든 기능을 이벤트로 만들었습니다.
screenName의 경우 모든 이벤트에 프로퍼티로 넣어주었어요.
공통 프로퍼티기 때문에 누락되거나 헷갈리지 않도록 properties와 별도의 열에 적어주었습니다.

앰플리튜드 프로젝트 세팅
앰플리튜드 프로젝트를 만드는 건 어렵지 않아요!
앰플리튜드 사이드에서 회원가입하고 생성합니다.
🍯프로젝트는 두 개 만들어줍시다!
개발/테스트 환경과 실제 유저 환경의 데이터가 섞이면 지표 분석에 어려움이 있을 수 있어요.
프로젝트 설정에서 prod/dev 두 개의 프로젝트를 만들어주었습니다.

🍯시간대를 변경해주세요!
앰플리튜드의 시간은 서버 시간을 기준으로 노출됩니다.
UTC 기준이어서 한국인이 보기에 어려움이 있어요.
프로젝트 설정에서 시간대를 UTC+09:00로 설정해주세요! (dev/prod 모두)

안드로이드 연동
먼저 의존성을 추가합니다.
// libs.versions.toml
[versions]
analytics = "1.+"
[libraries]
analytics = { group = "com.amplitude", name = "analytics-android", version.ref = "analytics" }
// build.gradle.kts (:app)
dependencies {
implementation(libs.analytics)
}
local.properties에 API 키를 추가합니다.
API 키는 프로젝트 설정에서 발급받을 수 있고, dev/prod 프로젝트 각각 발급됩니다.
// local.properties
amplitude.dev.key="실제 API 키"
amplitude.prod.key="실제 API 키"
buildConfig로 키를 읽을 수 있게 설정해줍니다. 여기서 dev/prod 키를 분기 처리 해줘야 해요!
// build.gradle.kts (:app)
buildTypes {
debug {
buildConfigField("String", "AMPLITUDE_KEY", properties["amplitude.dev.key"].toString())
}
release {
buildConfigField("String", "AMPLITUDE_KEY", properties["amplitude.prod.key"].toString())
}
}
저는 클린 아키텍쳐 + hilt를 적용 중이어서 앰플리튜드 객체를 관리하고 track 래핑 메소드를 제공하는 AnalyticsManager를 구현했습니다.
// core.analytics.AnalyticsManager.kt
@Singleton
class AnalyticsManager
@Inject
constructor(
@param:ApplicationContext private val context: Context,
) {
private val amplitude = Amplitude(
Configuration(
apiKey = BuildConfig.AMPLITUDE_KEY,
context = context,
autocapture = setOf(
AutocaptureOption.SESSIONS,
AutocaptureOption.APP_LIFECYCLES,
),
),
)
fun track(event: AnalyticsEvent) {
val props = event.properties?.toMutableMap() ?: mutableMapOf()
event.screenName?.let { props["screen_name"] = it }
amplitude.track(event.name, props)
}
}
이벤트명과 프로퍼티는 모두 String으로 정의하는데, 하드코딩하면 재사용성이 떨어지고 오타에 취약해집니다.
그래서 이벤트 규약을 AnalyticsEvent로 정의했습니다.
이때 스크린 네임 또한 상수로 처리했어요!
// core.analytics.AnalyticsEvent.kt
sealed class AnalyticsEvent(
val name: String,
val screenName: String? = null,
val properties: Map<String, Any?>? = null,
) {
data class Login(
val method: String,
val isProfileCompleted: Boolean,
) : AnalyticsEvent(
name = "login",
screenName = Screen.LOGIN,
properties = mapOf(
"method" to method.lowercase(),
"is_profile_completed" to isProfileCompleted,
),
)
...
private object Screen {
const val LOGIN = "login"
const val ONBOARDING = "onboarding"
...
}
이제 필요한 곳에서 AnalyticsManager를 통해 track을 호출하면 이벤트가 찍히게 돼요!
뷰모델에 AnalyticsManager를 주입해서 사용합니다.
// track 사용 예제 코드- 일부 코드 생략
@HiltViewModel
class LoginViewModel
@Inject
constructor(
private val socialLoginUseCase: SocialLoginUseCase,
// 👇🏻 여기 👇🏻
private val analyticsManager: AnalyticsManager,
) : BaseViewModel<LoginUiState, LoginSideEffect>(LoginUiState()) {
private fun socialLogin(type: SocialType) {
viewModelScope.launch {
socialLoginUseCase(
socialType = type,
token = token,
).onSuccess { isProfileComplete ->
// 👇🏻 여기 👇🏻
analyticsManager.track(
AnalyticsEvent.Login(
method = type.name,
isProfileCompleted = isProfileComplete,
),
)
결과
앰플리튜드 홈 > 라이브 이벤트에서 쉽게 확인할 수 있습니다.
이벤트명과 프로퍼티가 제가 설계한 대로 잘 찍히고 있고, 유저 위치, 기종, 앱 버전, IP도 확인 가능해요!
앰플리튜드 아이콘이 앞에 붙어 있는 이벤트는 자동으로 추적되는 이벤트로, 앱 시작/백그라운드 진입 등을 확인할 수 있어 이탈 위치를 파악하기 좋아요. (이를 위해 더더욱 screen_name 프로퍼티를 필수로 사용하시는 걸 추천드립니다!)

후기
어려울 줄 알았는데 생각보다 쉬워서 금방 해치웠네요!
유저 행동을 기반으로 서비스를 개선하는데 너무 유용한 도구이니 다들 도입하시는 걸 추천드려요😊
'Android' 카테고리의 다른 글
| [Kotlin] Scope Functions를 알아보자 (0) | 2026.05.07 |
|---|---|
| [Android Studio] 삼성 에뮬레이터를 만들어보자 (0) | 2026.02.27 |
| [Android][Jetpack Compose] 이미지를 불러와, 최적화하고, 서버에 전송해보자 (feat. presigned-url) (0) | 2026.02.08 |