Logging in Retrofit 2

Learn to add logging support in Retrofit 2 using HttpLoggingInterceptor and OkHttpClient APIs.

In Retrofit 2, all network operations are performed via OkHttp library. OkHttp provides HttpLoggingInterceptor which logs HTTP request and response data.

An example to add HttpLoggingInterceptor to OkHttpClient.

1. Dependency

<dependency>
	<groupId>com.squareup.okhttp3</groupId>
	<artifactId>logging-interceptor</artifactId>
	<version>3.9.0</version>
</dependency>
implementation("com.squareup.okhttp3:logging-interceptor:3.9.0")

2. Create and add HttpLoggingInterceptor

we can create an instance of HttpLoggingInterceptor, set logging level and use okHttpClient.addInterceptor() method.

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(Level.BASIC);

OkHttpClient client = new OkHttpClient.Builder()
    .addInterceptor(logging)
    .build();

private static Retrofit.Builder builder
	    	= new Retrofit.Builder()
	    		.baseUrl("https://api.domain.com/")
	    		.addConverterFactory(GsonConverterFactory.create())
	    		.client(httpClient.build());

By default, it uses the default logger set and available with Logger.DEFAULT property which defaults logcat messages output appropriate for the current platform. To log to a custom location, pass a Logger instance to the constructor.

HttpLoggingInterceptor logging = new HttpLoggingInterceptor( new Logger() 
{
    @Override public void log(String message) 
    {
        Timber.tag("OkHttp").d(message);
    }
});

Always add logging as the last interceptor, because this will also log the information which was added with previous interceptors.

3. Logging level

By default, HttpLoggingInterceptor has 4 levels of logging:

  • BASIC – Logs request and response lines.
  • BODY – Logs request and response lines and their respective headers and bodies (if present). This is the only log level where we will get the response body data.
  • HEADERS – Logs request and response lines and their respective headers.
  • NONE – No logs. Use this log level for production environments to enhance the apps performance.

4. Exclude sensitive information

The logs generated by this interceptor when using the HEADERS or BODY levels have the potential to leak sensitive information such as “Authorization” or “Cookie” headers.

We can exclude headers that may contain sensitive information by calling redactHeader().

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(Level.BODY);

logging.redactHeader("Authorization");
logging.redactHeader("Cookie");

5. Turn off logging in production

In development, builds are generally created with BuildConfig.DEBUG to true which means it is a development build. In production builds, this variable is set to false.

We can use this variable for turning on and off logging, after detecting the current build config.

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

if (BuildConfig.DEBUG) {  
    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(Level.BODY);

    httpClient.addInterceptor(logging);
}

Retrofit retrofit = new Retrofit.Builder()  
   .baseUrl(API_BASE_URL)
   .addConverterFactory(GsonConverterFactory.create())
   .client(httpClient.build())
   .build();

6. Conclusion

Logging in android applications is useful mostly on development environment where we can use the level BODY to properly debug the application.

As soon as we move to production, it is recommended to turn off the logging, completely.

Happy Learning !!

Leave a Reply

0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial