3

I can see that whenever I make a web svc call, I get the response in log. But I am finding it difficult to actually access that information in my code. For eg how do I find out the server request time and response time that I can see from the following log.

HTTP/1.1 200 OK
Connection: keep-alive
Content-Type: application/json;charset=UTF-8
Date: Tue, 21 Oct 2014 12:35:26 GMT
OkHttp-Received-Millis: 1413894922514
OkHttp-Response-Source: NETWORK 200
OkHttp-Selected-Protocol: http/1.1
OkHttp-Sent-Millis: 1413894921354
Server: Apache-Coyote/1.1
transfer-encoding: chunked
SoH
  • 2,180
  • 2
  • 24
  • 53

3 Answers3

4

Library and versions that I am using :

Retrofit version : 2.1.0

okhttp version : 3.3.1

logging-interceptor version : 3.3.1

This method only works within onResponse().

If you debug the onResponse(), you will see the sentRequestAtMillis & receivedResponseAtMillis in the rawResponse part as in the image below.

These are the parameters which hold the time in milliseconds when the request was made and when the response was received respectively.

enter image description here

The following example illustrates how to get the values in those parameters programmatically after response is received.

retrofitRequest.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> 
        // time when the request was made to server, which you get from ```sentRequestAtMillis```
        long requestTime = response.raw().sentRequestAtMillis();

        // time when the response was received, which you get from ```receivedResponseAtMillis```
        long responseTime = response.raw().receivedResponseAtMillis();

        //time taken to receive the response after the request was sent
        long apiTime =  responseTime - requestTime;
    }

    @Override public void onFailure(Call<ResponseBody> call, Throwable t) {

    }
});

Note that you may need to handle the code for any exceptions that may occur.

Pranav Karnik
  • 3,318
  • 3
  • 35
  • 47
  • Have you noticed that this approach is not consistent with the time reported from `HttpLoggingInterceptor`? AFAIS, it's giving about half of it. – Chisko Jan 19 '22 at 18:28
3

In Retrofit < 2.0, use the RestAdapter.setProfiler() to get metrics on your requests.

Warning - this will been removed in Retrofit 2.0 and will be replaced by a generalized interceptor system.

For example:

new RestAdapter.Builder()
    .setEndpoint("http://www.google.com")
    .setProfiler(new Profiler() {
        @Override
        public Object beforeCall() {
          return null;
        }

        @Override
        public void afterCall(RequestInformation requestInfo, long elapsedTime, int statusCode, Object beforeCallData) {
          Log.d("Retrofit Profiler", String.format("HTTP %d %s %s (%dms)",
              statusCode, requestInfo.getMethod(), requestInfo.getRelativePath(), elapsedTime));
        }
    })
    .create(MyService.class);

Here is some sample output:

D/Retrofit Profiler﹕ HTTP 200 GET /users/me (200ms)
Nelson Ramirez
  • 7,864
  • 7
  • 28
  • 34
Jacob Tabak
  • 8,044
  • 3
  • 24
  • 32
2

In your callback you have an access to Response object which has getHeaders() method, giving you a bunch of Headers.

As you can see, Header is just a name-value pair, so I think there won't be any problems to process them.

Smileek
  • 2,702
  • 23
  • 26
  • How to get Response in Synchronous retrofit calls? – SoH Oct 21 '14 at 15:30
  • @SoH, according to docs, "For access to the raw HTTP response use the Response type. `@GET("/users/list") Response userList();`" If you are interested in getting an object rather than just response, take a look at [how to extract it from the Response object](https://github.com/square/retrofit/blob/master/retrofit/src/main/java/retrofit/RestAdapter.java#L347]). – Smileek Oct 22 '14 at 07:20
  • Thanks Smileek. Your comment really helped alot. I just have one more question. For Retrofit with Return type how do I access the Response type, given that I have my custom object specified for return type. – SoH Oct 23 '14 at 09:04
  • @SoH, you should revert your point of view: put `Response` as a return type and then extract your object: [link](https://github.com/square/retrofit/blob/master/retrofit/src/main/java/retrofit/RestAdapter.java#L347]). You can't get `Response` from your object, but you can get your object from `Response`. – Smileek Oct 23 '14 at 10:16