HttpLoggingInterceptor is an Interceptor that lets you log all the API requests made by your app as well as the responses returned by the server.
To add HttpLoggingInterceptor to your project, first open the app module build.gradle. In the dependencies block, add the following line of code:
implementation “com.squareup.okhttp3:logging-interceptor:4.9.0”`
This line adds the dependency for HttpLoggingInterceptor which is shipped as a separate library compared to OkHttp. Click ‘Sync Now’ and wait for the dependency to sync.
Next, you head over to the file named OkHttpProvider.kt inside the network package. Here, there is a function named getOkHttpClient:
fun getOkHttpClient(): OkHttpClient {
return if (okHttpClient == null) {
val okHttpClient = OkHttpClient.Builder()
.readTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
.connectTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
.build()
OkHttpProvider.okHttpClient = okHttpClient
okHttpClient
} else {
okHttpClient!!
}
}
This function creates an instance of OkHttpClient, configures it with read and connection timeouts, and finally returns the instance.
Before creating the OkHttpClient instance, create an instance of HttpLoggingInterceptor by adding the following line of code:
val loggingInterceptor = HttpLoggingInterceptor()
You then have to specify the extent of logging required.
You can choose among four different levels: 1. NONE 2. BASIC 3. HEADERS 4. BODY. NONE is the default logging level.
The BASIC logging level logs only bare minimum information such as the request URL, request type, response code, etc.
The HEADERS logging level logs all the information covered by the BASIC level and also the headers of the request and the response.
The BODY logging level logs all the information covered by the HEADERS level and also the body of the request and the response. Let’s see some of the logging levels in action!
Back in the getOkHttpClient() function, set the logging level to BASIC by adding the following line of code:
loggingInterceptor.level = HttpLoggingInterceptor.Level.BASIC
In this line, you set the logging level to BASIC by assigning the enum value HttpLoggingInterceptor.Level.BASIC to the level attribute of the HttpLoggingInterceptor instance.
Once the HttpLoggingInterceptor instance is configured, add it to the OkHttpClient instance as follows:
val okHttpClient = OkHttpClient.Builder()
.readTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
.connectTimeout(REQUEST_TIMEOUT, TimeUnit.SECONDS)
.addInterceptor(loggingInterceptor)
.build()
Build and run the app. Once the app is running, open the Logcat tab inside Android Studio. You will see logs of the API request as well as the response.
Close the Logcat tab and switch over to the emulator. Click on any of the movies. You will notice that the app shows an error state. Luckily, you are already logging the responses to all your API calls.
Open the Logcat tab and check the response logs. You will notice that the response has a status code of 401 which indicates an Unauthenticated Request. But this data is insufficient to correctly debug the issue.
Close the Logcat tab and go back to OkHttpProvider. Change the logging level to BODY as follows:
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
This will log the headers as well as the body of all the responses. If you instead used HEADERS, it would log just the headers. Build and run the app.
Click on any of the movies again. Switching to the Logcat tab, you can now see more details about the response. The response body states that an invalid API key was sent in the request. You have found the cause of the error.
Close the Logcat tab and open the file named MovieApi in the network package. You will notice that you are sending an API key as a query parameter for the getPopularMovies method and not the getMovieDetailsmethod.
Fix this by adding the parameter for the getMovieDetails method too:
@GET("/3/movie/{id}")
fun getMovieDetails(@Path("id") id: Long, @Query("api_key") api_key: String = BuildConfig.THE_MOVIE_DB_API_TOKEN): Call<MovieDetailsModel>
If now you click on any of the movies, you will see that the details page works correctly now. You have successfully integrated HttpLoggingInterceptor in your app and used it to debug an issue with your API calls.