Spring RestTemplate - how to enable full debugging/logging of requests/responses? Spring RestTemplate - how to enable full debugging/logging of requests/responses? java java

Spring RestTemplate - how to enable full debugging/logging of requests/responses?


Just to complete the example with a full implementation of ClientHttpRequestInterceptor to trace request and response:

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.http.HttpRequest;import org.springframework.http.client.ClientHttpRequestExecution;import org.springframework.http.client.ClientHttpRequestInterceptor;import org.springframework.http.client.ClientHttpResponse;public class LoggingRequestInterceptor implements ClientHttpRequestInterceptor {    final static Logger log = LoggerFactory.getLogger(LoggingRequestInterceptor.class);    @Override    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {        traceRequest(request, body);        ClientHttpResponse response = execution.execute(request, body);        traceResponse(response);        return response;    }    private void traceRequest(HttpRequest request, byte[] body) throws IOException {        log.info("===========================request begin================================================");        log.debug("URI         : {}", request.getURI());        log.debug("Method      : {}", request.getMethod());        log.debug("Headers     : {}", request.getHeaders() );        log.debug("Request body: {}", new String(body, "UTF-8"));        log.info("==========================request end================================================");    }    private void traceResponse(ClientHttpResponse response) throws IOException {        StringBuilder inputStringBuilder = new StringBuilder();        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getBody(), "UTF-8"));        String line = bufferedReader.readLine();        while (line != null) {            inputStringBuilder.append(line);            inputStringBuilder.append('\n');            line = bufferedReader.readLine();        }        log.info("============================response begin==========================================");        log.debug("Status code  : {}", response.getStatusCode());        log.debug("Status text  : {}", response.getStatusText());        log.debug("Headers      : {}", response.getHeaders());        log.debug("Response body: {}", inputStringBuilder.toString());        log.info("=======================response end=================================================");    }}

Then instantiate RestTemplate using a BufferingClientHttpRequestFactory and the LoggingRequestInterceptor:

RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();interceptors.add(new LoggingRequestInterceptor());restTemplate.setInterceptors(interceptors);

The BufferingClientHttpRequestFactory is required as we want to use the response body both in the interceptor and for the initial calling code. The default implementation allows to read the response body only once.


in Spring Boot you can get the full request/response by setting this in properties (or other 12 factor method)

logging.level.org.apache.http=DEBUG

this outputs

-DEBUG .i.c.DefaultHttpClientConnectionOperator : Connecting to localhost/127.0.0.1:41827-DEBUG .i.c.DefaultHttpClientConnectionOperator : Connection established 127.0.0.1:39546<->127.0.0.1:41827-DEBUG o.a.http.impl.execchain.MainClientExec   : Executing request POST /v0/users HTTP/1.1-DEBUG o.a.http.impl.execchain.MainClientExec   : Target auth state: UNCHALLENGED-DEBUG o.a.http.impl.execchain.MainClientExec   : Proxy auth state: UNCHALLENGED-DEBUG org.apache.http.headers                  : http-outgoing-0 >> POST /v0/users HTTP/1.1-DEBUG org.apache.http.headers                  : http-outgoing-0 >> Content-Type: application/json;charset=UTF-8-DEBUG org.apache.http.headers                  : http-outgoing-0 >> Content-Length: 56-DEBUG org.apache.http.headers                  : http-outgoing-0 >> Host: localhost:41827-DEBUG org.apache.http.headers                  : http-outgoing-0 >> Connection: Keep-Alive-DEBUG org.apache.http.headers                  : http-outgoing-0 >> User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_102)-DEBUG org.apache.http.headers                  : http-outgoing-0 >> Accept-Encoding: gzip,deflate-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "POST /v0/users HTTP/1.1[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "Content-Type: application/json;charset=UTF-8[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "Content-Length: 56[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "Host: localhost:41827[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_102)[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "Accept-Encoding: gzip,deflate[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "{"id":null,"email":"xenoterracide@gmail.com","new":true}"

and response

-DEBUG .i.c.DefaultHttpClientConnectionOperator : Connecting to localhost/127.0.0.1:41827-DEBUG .i.c.DefaultHttpClientConnectionOperator : Connection established 127.0.0.1:39546<->127.0.0.1:41827-DEBUG o.a.http.impl.execchain.MainClientExec   : Executing request POST /v0/users HTTP/1.1-DEBUG o.a.http.impl.execchain.MainClientExec   : Target auth state: UNCHALLENGED-DEBUG o.a.http.impl.execchain.MainClientExec   : Proxy auth state: UNCHALLENGED-DEBUG org.apache.http.headers                  : http-outgoing-0 >> POST /v0/users HTTP/1.1-DEBUG org.apache.http.headers                  : http-outgoing-0 >> Content-Type: application/json;charset=UTF-8-DEBUG org.apache.http.headers                  : http-outgoing-0 >> Content-Length: 56-DEBUG org.apache.http.headers                  : http-outgoing-0 >> Host: localhost:41827-DEBUG org.apache.http.headers                  : http-outgoing-0 >> Connection: Keep-Alive-DEBUG org.apache.http.headers                  : http-outgoing-0 >> User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_102)-DEBUG org.apache.http.headers                  : http-outgoing-0 >> Accept-Encoding: gzip,deflate-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "POST /v0/users HTTP/1.1[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "Content-Type: application/json;charset=UTF-8[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "Content-Length: 56[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "Host: localhost:41827[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_102)[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "Accept-Encoding: gzip,deflate[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "[\r][\n]"-DEBUG org.apache.http.wire                     : http-outgoing-0 >> "{"id":null,"email":"xenoterracide@gmail.com","new":true}"

or just logging.level.org.apache.http.wire=DEBUG which seems to contain all of the relevant information


Extending @hstoerr answer with some code:


Create LoggingRequestInterceptor to log requests responses

public class LoggingRequestInterceptor implements ClientHttpRequestInterceptor {    private static final Logger log = LoggerFactory.getLogger(LoggingRequestInterceptor.class);    @Override    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {        ClientHttpResponse response = execution.execute(request, body);        log(request,body,response);        return response;    }    private void log(HttpRequest request, byte[] body, ClientHttpResponse response) throws IOException {        //do logging    }}

Setup RestTemplate

RestTemplate rt = new RestTemplate();//set interceptors/requestFactoryClientHttpRequestInterceptor ri = new LoggingRequestInterceptor();List<ClientHttpRequestInterceptor> ris = new ArrayList<ClientHttpRequestInterceptor>();ris.add(ri);rt.setInterceptors(ris);rt.setRequestFactory(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory());