I can't find relevant methods in the Retrofit API for logging complete request/response bodies. I was expecting some help in the Profiler (but it only offers meta-data about response). I tried setting the log level in the Builder, but this doesn't help me either :
RestAdapter adapter = (new RestAdapter.Builder()).
setEndpoint(baseUrl).
setRequestInterceptor(interceptor).
setProfiler(profiler).
setClient(client).
setExecutors(MyApplication.getWebServiceThreadPool()).
setLogLevel(LogLevel.FULL).
setLog(new RestAdapter.Log() {
@Override
public void log(String msg) {
Log.i(TAG, msg);
}
}).
build();
EDIT: This code is working now. I don't know why it wasn't working earlier. Possibly because I was using some older version of retrofit.
Retrofit 2.0 :
UPDATE: @by Marcus Pöhls
Logging In Retrofit 2
Retrofit 2 completely relies on OkHttp for any network operation. Since OkHttp is a peer dependency of Retrofit 2, you won’t need to add an additional dependency once Retrofit 2 is released as a stable release.
OkHttp 2.6.0 ships with a logging interceptor as an internal dependency and you can directly use it for your Retrofit client. Retrofit 2.0.0-beta2 still uses OkHttp 2.5.0. Future releases will bump the dependency to higher OkHttp versions. That’s why you need to manually import the logging interceptor. Add the following line to your gradle imports within your build.gradle file to fetch the logging interceptor dependency.
compile 'com.squareup.okhttp3:logging-interceptor:3.9.0'
You can also visit Square's GitHub page about this interceptor
Add Logging to Retrofit 2
While developing your app and for debugging purposes it’s nice to have a log feature integrated to show request and response information. Since logging isn’t integrated by default anymore in Retrofit 2, we need to add a logging interceptor for OkHttp. Luckily OkHttp already ships with this interceptor and you only need to activate it for your OkHttpClient.
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
// set your desired log level
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
// add your other interceptors …
// add logging as last interceptor
httpClient.addInterceptor(logging); // <-- this is the important line!
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
We recommend to add logging as the last interceptor, because this will also log the information which you added with previous interceptors to your request.
Log Levels
Logging too much information will blow up your Android monitor, that’s why OkHttp’s logging interceptor has four log levels: NONE, BASIC, HEADERS, BODY. We’ll walk you through each of the log levels and describe their output.
further information please visit : Retrofit 2 — Log Requests and Responses
OLD ANSWER:
no logging in Retrofit 2 anymore. The development team removed the logging feature. To be honest, the logging feature wasn’t that reliable anyway. Jake Wharton explicitly stated that the logged messages or objects are the assumed values and they couldn’t be proofed to be true. The actual request which arrives at the server may have a changed request body or something else.
Even though there is no integrated logging by default, you can leverage any Java logger and use it within a customized OkHttp interceptor.
further information about Retrofit 2 please refer : Retrofit — Getting Started and Create an Android Client
I hope this code will help you to logging .
you just need to add interceptor in your Build.Gradle
then make RetrofitClient
.
Add this line to your build.gradle
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
Make your Retrofit Client
public class RetrofitClient {
private Retrofit retrofit;
private static OkHttpClient.Builder httpClient =
new OkHttpClient.Builder();
private static RetrofitClient instance = null;
private static ApiServices service = null;
private static HttpLoggingInterceptor logging =
new HttpLoggingInterceptor();
private RetrofitClient(final Context context) {
httpClient.interceptors().add(new Interceptor() {
@Override
public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
Request originalRequest = chain.request();
Request.Builder builder = originalRequest.newBuilder().
method(originalRequest.method(), originalRequest.body());
okhttp3.Response response = chain.proceed(builder.build());
/*
Do what you want
*/
return response;
}
});
if (BuildConfig.DEBUG) {
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
// add logging as last interceptor
httpClient.addInterceptor(logging);
}
retrofit = new Retrofit.Builder().client(httpClient.build()).
baseUrl(Constants.BASE_URL).
addConverterFactory(GsonConverterFactory.create()).build();
service = retrofit.create(ApiServices.class);
}
public static RetrofitClient getInstance(Context context) {
if (instance == null) {
instance = new RetrofitClient(context);
}
return instance;
}
public ApiServices getApiService() {
return service;
}
}
RetrofitClient.getInstance(context).getApiService().yourRequestCall();
below code is working for both with header and without header to print log request & response. Note: Just comment .addHeader() line if are not using header.
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
//.addInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
.addNetworkInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder()
// .addHeader(Constant.Header, authToken)
.build();
return chain.proceed(request);
}
}).build();
final Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constant.baseUrl)
.client(client) // This line is important
.addConverterFactory(GsonConverterFactory.create())
.build();
ZoomX — Android Logger Interceptor is a great interceptor can help you to solve your problem.
There doesn't appear to be a way to do basic + body, but you can use FULL and filter the headers you don't want.
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(syncServer)
.setErrorHandler(err)
.setConverter(new GsonConverter(gson))
.setLogLevel(logLevel)
.setLog(new RestAdapter.Log() {
@Override
public void log(String msg) {
String[] blacklist = {"Access-Control", "Cache-Control", "Connection", "Content-Type", "Keep-Alive", "Pragma", "Server", "Vary", "X-Powered-By"};
for (String bString : blacklist) {
if (msg.startsWith(bString)) {
return;
}
}
Log.d("Retrofit", msg);
}
}).build();
It appears that when overriding the log, the body is prefixed with a tag similar to
[ 02-25 10:42:30.317 25645:26335 D/Retrofit ]
so it should be easy to log basic + body by adjusting the custom filter. I am using a blacklist, but a whitelist could also be used depending on your needs.
Update for Retrofit 2.0.0-beta3
Now you have to use okhttp3 with builder. Also the old interceptor will not work. This response is tailored for Android.
Here's a quick copy paste for you with the new stuff.
1. Modify your gradle file to
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
compile "com.squareup.retrofit2:converter-gson:2.0.0-beta3"
compile "com.squareup.retrofit2:adapter-rxjava:2.0.0-beta3"
compile 'com.squareup.okhttp3:logging-interceptor:3.0.1'
2. Check this sample code:
with the new imports. You can remove Rx if you don't use it, also remove what you don't use.
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.GsonConverterFactory;
import retrofit2.Retrofit;
import retrofit2.RxJavaCallAdapterFactory;
import retrofit2.http.GET;
import retrofit2.http.Query;
import rx.Observable;
public interface APIService {
String ENDPOINT = "http://api.openweathermap.org";
String API_KEY = "2de143494c0b2xxxx0e0";
@GET("/data/2.5/weather?appid=" + API_KEY) Observable<WeatherPojo> getWeatherForLatLon(@Query("lat") double lat, @Query("lng") double lng, @Query("units") String units);
class Factory {
public static APIService create(Context context) {
OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
builder.readTimeout(10, TimeUnit.SECONDS);
builder.connectTimeout(5, TimeUnit.SECONDS);
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
builder.addInterceptor(interceptor);
}
//Extra Headers
//builder.addNetworkInterceptor().add(chain -> {
// Request request = chain.request().newBuilder().addHeader("Authorization", authToken).build();
// return chain.proceed(request);
//});
builder.addInterceptor(new UnauthorisedInterceptor(context));
OkHttpClient client = builder.build();
Retrofit retrofit =
new Retrofit.Builder().baseUrl(APIService.ENDPOINT).client(client).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();
return retrofit.create(APIService.class);
}
}
}
Bonus
I know it's offtopic but I find it cool.
In case there's an http error code of unauthorized, here is an interceptor. I use eventbus for transmitting the event.
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import com.androidadvance.ultimateandroidtemplaterx.BaseApplication;
import com.androidadvance.ultimateandroidtemplaterx.events.AuthenticationErrorEvent;
import de.greenrobot.event.EventBus;
import java.io.IOException;
import javax.inject.Inject;
import okhttp3.Interceptor;
import okhttp3.Response;
public class UnauthorisedInterceptor implements Interceptor {
@Inject EventBus eventBus;
public UnauthorisedInterceptor(Context context) {
BaseApplication.get(context).getApplicationComponent().inject(this);
}
@Override public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
if (response.code() == 401) {
new Handler(Looper.getMainLooper()).post(() -> eventBus.post(new AuthenticationErrorEvent()));
}
return response;
}
}
code take from https://github.com/AndreiD/UltimateAndroidTemplateRx (my project).
This is not the best way to do it the better answers are above. This is just another way to check it by using Android Logs. Put them all in this helps to catch parsing errors.
call.enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call,
Response<JsonObject> response) {
// Catching Responses From Retrofit
Log.d("TAG", "onResponseisSuccessful: "+response.isSuccessful());
Log.d("TAG", "onResponsebody: "+response.body());
Log.d("TAG", "onResponseerrorBody: "+response.errorBody());
Log.d("TAG", "onResponsemessage: "+response.message());
Log.d("TAG", "onResponsecode: "+response.code());
Log.d("TAG", "onResponseheaders: "+response.headers());
Log.d("TAG", "onResponseraw: "+response.raw());
Log.d("TAG", "onResponsetoString: "+response.toString());
}
@Override
public void onFailure(Call<JsonObject> call,
Throwable t) {
Log.d("TAG", "onFailuregetLocalizedMessage: " +t.getLocalizedMessage());
Log.d("TAG", "onFailuregetMessage: " +t.getMessage());
Log.d("TAG", "onFailuretoString: " +t.toString());
Log.d("TAG", "onFailurefillInStackTrace: " +t.fillInStackTrace());
Log.d("TAG", "onFailuregetCause: " +t.getCause());
Log.d("TAG", "onFailuregetStackTrace: " + Arrays.toString(t.getStackTrace()));
Log.d("TAG", "getSuppressed: " + Arrays.toString(t.getSuppressed()));
}
});
If you are using Retrofit2 and okhttp3 then you need to know that Interceptor works by queue. So add loggingInterceptor at the end, after your other Interceptors:
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
if (BuildConfig.DEBUG)
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.addInterceptor(new CatalogInterceptor(context))
.addInterceptor(new OAuthInterceptor(context))
.authenticator(new BearerTokenAuthenticator(context))
.addInterceptor(loggingInterceptor)//at the end
.build();
For android studio before 3.0 (using android motinor)
https://futurestud.io/tutorials/retrofit-2-log-requests-and-responses
https://www.youtube.com/watch?v=vazLpzE5y9M
And for android studio from 3.0 and above (using android profiler as android monitor is replaced by android profiler)
https://futurestud.io/tutorials/retrofit-2-analyze-network-traffic-with-android-studio-profiler
Source: Stackoverflow.com