WatchTower, Observe API Calls in browser

WindSekirun (wind.seo)·2022년 4월 26일
0

이 글은 기존 운영했던 WordPress 블로그인 PyxisPub: Development Life (pyxispub.uzuki.live) 에서 가져온 글 입니다. 모든 글을 가져오지는 않으며, 작성 시점과 현재 시점에는 차이가 많이 존재합니다.

작성 시점: 2019-05-30

도입

adibfara/WatchTower(https://github.com/adibfara/WatchTower)는 브라우저 내 에서 OKHttp으로 인한 통신에 대한 요청 / 결과 데이터 및 헤더 등을 볼 수 있는 라이브러리로, 2019년 5월 24일에 첫 버전이 릴리즈된 라이브러리이다.

지금까지 OKHttp으로 인한 통신을 앱에서 검출하려면 주로 facebook/stetho(https://facebook.github.io/stetho/) 를 사용했으나, stetho의 기반은 Chrome developer tools에 작동한다는 점에서 이 WatchTower는 그러한 제약을 가지지 않고, 앱 내에서 NanoHTTPd를 사용하여 웹 서버를 열고 자료를 볼 수 있게 하는 것에 큰 차이점을 가진다.

또한 차후 확장하여 액티비티 내에서 볼 수 있게 하는 점도 가능하니, 기능은 Stetho에 비해 매우 빈약하지만 (Stetho가 네트워크 인터셉터 외에도 뷰 구조나 덤프 등을 제공하기 때문에) 네트워크 인터셉트 기능으로 한정하면 WatchTower가 더 이점을 가진다고 볼 수 있다.

당연하게도 Retrofit 또한 OKHttp가 기반이므로 Retrofit를 사용해도 위 기능을 전부 활용할 수 있다.

따라서 이 글에서는 기본적인 WatchTower의 사용법을 소개한다.

사용법

모듈의 gradle에 아래 종속성을 추가한다.

implementation 'com.snakyapps.watchtower:core:1.0.0'  
debugImplementation 'com.snakyapps.watchtower:interceptor-okhttp:1.0.0'  
releaseImplementation 'com.snakyapps.watchtower:interceptor-okhttp-no-op:1.0.0'

debugImplementation, releaseImplementation으로 나눠지는데 이는 디버그 빌드에서만 해당 행동을 할 수 있게 종속성 분야에서 강제하는 것이다. 따라서 별도로 BuildConfig.DEBUG로 판단할 필요가 없어진다.

1.0.0 문서에 따르면, 안드로이드 환경에서는 Service에서 WatchTower를 시작하는 것이 권장된다고 되어있어, Service 객체를 생성한다.

class WatchTowerService : Service() {  
  
    override fun onBind(intent: Intent?): IBinder? {  
        return null  
    }  
  
    override fun onCreate() {  
        super.onCreate()  
        val port = Config.confg.watchTowerPort  
        WatchTower.start(WebWatchTowerObserver(port = port))  
  
        Timber.d("WatchTower is started. URL: http://localhost:$port")  
    }  
  
    override fun onDestroy() {  
        super.onDestroy()  
        WatchTower.shutDown()  
    }  
}
<service  
            android:name=".module.watch.WatchTowerService"  
            android:enabled="true" />

위와 같이 작성하고 Manifest에 작성하였으면, 그 다음에는 OKHttp를 설정할 때에 Interceptor를 추가하면 된다.

현재 구축된 기반의 경우 Dagger의 Multibinding 기능을 이용하여 Set<Interceptor> - LoggingInterceptor 순서로 추가하게 되어 있으므로, LoggingInterceptor 뒤에 WatchTower 자체의 Interceptor를 추가한다.

@Provides  
fun provideClient(interceptors: Set<@JvmSuppressWildcards Interceptor>,  
                      @Named("loginterceptor") logsInterceptor: Interceptor): OkHttpClient {  
    val builder = OkHttpClient().newBuilder()  
    builder.readTimeout(Config.config.timeout.toLong(), TimeUnit.MILLISECONDS)  
    builder.connectTimeout(Config.config.connectTimeout.toLong(), TimeUnit.MILLISECONDS)  
    builder.retryOnConnectionFailure(Config.config.retryOnConnectionFailure)  
    if (interceptors.isNotEmpty()) {  
        interceptors.forEach {  
            builder.addInterceptor(it)  
        }  
    }  
  
    if (!Config.config.notUseLogInterceptor) {  
        builder.addInterceptor(logsInterceptor)  
    }  
  
    if (Config.config.useWatchTower) {  
        builder.addInterceptor(WatchTowerInterceptor())  
    }  
  
        return builder.build()  
}

마지막으로 Activity 에서 서비스를 시작하거나 중지하면 작동하게 된다.

이제, 앱을 빌드하게 되면 기기의 브라우저에서는 http://localhost:8085 를, PC에서는 http://기기의 로컬 주소:8085 를 입력하면 접속이 되고, OKHttp로 통해 통신이 진행될 경우 맨 위의 사진처럼 로그가 나오게 된다. 기기의 로컬 주소는 기기에서 https://www.whatismybrowser.com/detect/what-is-my-local-ip-address 에 접속하면 나온다.

마무리

간단한 사용법을 가지면서도, 편리한 사용법을 가져서 누구나 쉽게 적용할 수 있다는 포인트가 제일 강점이다. 구현하는 데에도 큰 시간이 들어가지 않으므로 적용해서 사용하면 큰 편리함을 얻을 수 있을 것 같다.

profile
Android Developer @kakaobank

0개의 댓글