[안드로이드] App 로깅 전략 with Firebase Analytics [우아한테크코스 5기 AN_베르]

2023. 8. 6. 16:57· 우아한테크코스
목차
  1. 로깅 전략 의 필요성
  2. 로깅 전략

현재 프로젝트에 적용 중인 로깅 방식을 공유하려고 한다!

 

로깅 전략 의 필요성

로깅 전략은 어떤 로그를 어떤 방식으로 남길지, 로그를 얼마나 관리할 지 등이다. 

 

그럼 애플리케이션에 어떤 로깅 전략이 필요할까?

아래는 가장 중요하다고 생각하는 두 가지 이다. 

 

1. Error 로깅

  네트워크 통신하는 부분에서 왜 Failure 하는지, Exception 이 어디서 어떻게 발생하는지 Message 는 무엇인지 로깅하고 싶을 수 있다. 오류가 반복된다면 fix 가 필요할 것이다.

 

2. 비즈니스와 연결

사용자가 어떤 flow 로 앱을 이용하는지 어떤 화면에 오래 체류하는지 체크해서 비즈니스와 연결 지어 이용할 수 있다.

 

로깅의 범위나 방향은 앱마다 다르다. 즉, 어떤 로깅 전략을 세울 지 앱 바 앱 이고 팀 바 팀 이다.

프로젝트에 맞는 로깅 전략을 세우는 것이 중요하다.

 

참고 로깅 전략 tecoble 

https://tecoble.techcourse.co.kr/post/2020-07-30-use-logger/

 

로그 전략을 통해 메시지를 남기자

…

tecoble.techcourse.co.kr

 

이전에 Firebase 에 앱 등록을 마친 상태이다. 

 

앱 등록하기

https://firebase.google.com/docs/android/setup?hl=ko

 

Android 프로젝트에 Firebase 추가  |  Firebase for Android

Google I/O 2023에서 Firebase의 주요 소식을 확인하세요. 자세히 알아보기 의견 보내기 Android 프로젝트에 Firebase 추가 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세

firebase.google.com

 

앱 등록을 마치면 기본적인 Analytics 는 동작할 것이다.

앱에서 어떤 화면에 많이 접속하는지 사용자는 몇 명인지 어떤 이벤트가 발생 중인지 등 앱에 대한 분석을 확인할 수 있다.

 

로깅 전략

우리 팀에서는 다른 로그보다 네트워크 오류 로깅 전략을 수립했다.

ViewModelScope 내에서 Repository 로 부터 데이터를 요청할 때 결과가 Failure 이면 로깅 하도록 했다.

 

이벤트 로깅 기본 세팅을 참고하여 gradle 설정이 우선이다.

https://firebase.google.com/docs/analytics/events?platform=android&hl=ko 

 

이벤트 로깅  |  Google Analytics for Firebase

Google I/O 2023에서 Firebase의 주요 소식을 확인하세요. 자세히 알아보기 의견 보내기 이벤트 로깅 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. iOS+ Android 웹 Fl

firebase.google.com

 

  먼저 AnalyticsHelper interface 를 정의했다. 인터페이스를 정의한 이유는 Firebase 가 아닌 다른 것을 이용해서 로깅할 수 있도록 유연하게 만들면서 동시에 단위 테스트가 로깅되지 않게 하기 위함이다. 테스트 부분은 나중에 추가로 설명하겠다.

interface AnalyticsHelper {
    fun logEvent(event: AnalyticsEvent)
}

 

 

  그 다음으로 구현체를 만들었다. context 를 필요로 해서 Application 단에서 미리 create 할 수 있도록하고 instance 는 앱 생명주기 전체에서 사용가능하도록 했다.

class FirebaseAnalyticsHelper private constructor(context: Context) : AnalyticsHelper {

    private val firebaseAnalytics = FirebaseAnalytics.getInstance(context)

    // logging 함수
    override fun logEvent(event: AnalyticsEvent) {
        val params = Bundle().apply {
            event.extras.forEach {
                putString(it.key, it.value)
            }
        }
        firebaseAnalytics.logEvent(LOG_NAME, params)
    }

    companion object {
        private const val LOG_NAME = "festago_log"

        // 인스턴스를 저장된 가져옴
        private var _instance: FirebaseAnalyticsHelper? = null
        val instance: FirebaseAnalyticsHelper = _instance!!

        // 인스턴스 생성
        fun create(context: Context) {
            if (_instance == null) {
                _instance = FirebaseAnalyticsHelper(context)
            }
        }
    }
}

 

  Application onCreate 에서 다음과 같이 미리 초기화하고 사용한다. 앱 전역에서 사용하려면applicationContext 를 사용해서 초기화해야하는데 액티비티에서 최초 초기화하게 되면 액티비티 Context 를 넣을 수 있고 메모리 문제가 발생할 수 있기 때문이다. 또한 사용하는 곳에서 전부 context 를 넣어야한다면 context 가 없는 곳에서 로깅하지 못하는 문제도 있을 것이라 판단하였다.

 

ExampleApplication: Application() {
	override fun onCreate() {
        super.onCreate()
        FirebaseAnalyticsHelper.create(applicationContext)
    }
}

 

이제 ViewModel 을 생성할 때 인자로 함께 추가한다.

 private val vm: ExampleViewModel by viewModels {
        ExampleViewModelFactory(
            ExampleDefaultRepository(...),
            FirebaseAnalyticsHelper.instance,
        )
    }

 

그 다음 viewModelScope 내부 Result 가 failure 일 때 로깅하였다.

 fun loadExamples() {
        viewModelScope.launch {
            ticketRepository.loadExamples()
                .onSuccess { it ->
                    ...
                }.onFailure { 
		   ...
                    analyticsHelper.logNetworkFailure("load_Examples", it.message.toString())
                }
        }
    }

아래와 같이 네트워크 에러 로깅을 확장함수로  만들어 사용한다.

fun AnalyticsHelper.logNetworkFailure(key: String, value: String) {
    logEvent(
        AnalyticsEvent(
            type = "Network Failure Type",
            extras = listOf(AnalyticsEvent.Param(key, value)),
        ),
    )
}

 

그럼 이제 앱을 실행하고 log 를 확인할 수 있는데

 

  로깅하고 5분정도 지나면 Realtime Analytics 에서 확인할 수 있다. 실시간이 아닌 정보들은 Analytics Dashboard 혹은 Events 에서 확인할 수 있다. 또한 Debug 기기를 등록하면 DebugView 에서도 확인 가능하다.

 

테스트는 어떻게 변화했을까?

 

class ExampleViewModelTest {
    private lateinit var vm: ExampleViewModel
    private lateinit var exampleRepository: ExampleRepository
    private lateinit var analyticsHelper: AnalyticsHelper
    
    ...
    
    @OptIn(ExperimentalCoroutinesApi::class)
    @Before
    fun setUp() {
        Dispatchers.setMain(UnconfinedTestDispatcher())
        ticketRepository = mockk()
        analyticsHelper = mockk(relaxed = true)
        vm = TicketListViewModel(ticketRepository, analyticsHelper)
    }
    
    ...

 

  mockk 라이브러리를 사용해서 외부에서 주입하는 로그를 목 객체로 만들어줬다. relaxed 를 true 로 만들어 따로 행동을 지정하지 않아도 알아서 작동하도록 하였다! 이렇게 되면 context 를 넣어 초기화할 필요도 없어지고 테스트가 Firebase 에 로깅되지도 않는다.

 

추후에 오류처리 방식이 변하거나(CallAdapter 등) 추가 로깅 방식이 생길 예정이고 위 코드는 리팩터링 가능성이 있다!

저작자표시 (새창열림)

'우아한테크코스' 카테고리의 다른 글

내가 꿈꾸는 프로그래머로서의 삶  (0) 2023.10.08
자동 DI 라이브러리 만들기 : [우아한테크코스 5기 AN_베르]  (0) 2023.10.02
Kotlin coroutine 강의로 이해하기 - 2 : [우아한테크코스 5기 AN_베르]  (0) 2023.07.30
Kotlin coroutine 강의로 이해하기 - 1 : [우아한테크코스 5기 AN_베르]  (0) 2023.07.16
[안드로이드] MVP 패턴을 MVVM 패턴으로 리팩터링하기  (0) 2023.07.09
  1. 로깅 전략 의 필요성
  2. 로깅 전략
'우아한테크코스' 카테고리의 다른 글
  • 내가 꿈꾸는 프로그래머로서의 삶
  • 자동 DI 라이브러리 만들기 : [우아한테크코스 5기 AN_베르]
  • Kotlin coroutine 강의로 이해하기 - 2 : [우아한테크코스 5기 AN_베르]
  • Kotlin coroutine 강의로 이해하기 - 1 : [우아한테크코스 5기 AN_베르]
베르_최성훈
베르_최성훈
베르_최성훈
베르의 안드로이드
베르_최성훈
전체
오늘
어제
  • 분류 전체보기 (57)
    • 우아한테크코스 (15)
    • Android (19)
    • kotlin (2)
    • 회고 (5)
    • Bug Fix (2)
    • 알고리즘 (6)
    • 기타 (1)
    • Jetpack Compose (6)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • flow
  • 우아한테크코스
  • 우테코
  • 페스타고
  • 회고
  • Kotlin
  • ViewModel
  • Android
  • PRESENTER
  • SharedFlow
  • FRAGMENT
  • MVP
  • MVVM
  • 생명주기
  • 안드로이드
  • Test
  • Lifecycle
  • 프래그먼트
  • coroutine
  • 코틀린

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
베르_최성훈
[안드로이드] App 로깅 전략 with Firebase Analytics [우아한테크코스 5기 AN_베르]
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.