Debug logging of RestTemplate/RestOperations on Spring Framework [Kotlin/Java]


This article shows debug logging of RestTemplate/RestOperations.

🐠 Set DEBUG to log level for RestTemplate

Set DEBUG to log level for RestTemplate with src/main/resources/application.yml.

logging:
level:
org.springframework.web.client.RestTemplate: DEBUG

😸 Add logging process to Request/Response

This is a sample code for adding logging process to Request/Response by ClientHttpRequestInterceptor.

Implement ClientHttpRequestInterceptor Interface

This is a sample code of implemented ClientHttpRequestInterceptor interface. Please create app/util/RestTemplateLoggingInterceptor.kt and add the following code.

import org.slf4j.LoggerFactory
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpRequest
import org.springframework.http.HttpStatus
import org.springframework.http.client.*
import org.springframework.lang.Nullable
import org.springframework.util.StreamUtils
import java.io.*
import java.io.ByteArrayInputStream
import java.io.IOException

class RestTemplateLoggingInterceptor : ClientHttpRequestInterceptor {
private val log = LoggerFactory.getLogger(HelpDeskController::class.java)

@Throws(IOException::class)
override fun intercept(request: HttpRequest, body: ByteArray, execution: ClientHttpRequestExecution): ClientHttpResponse {
// Show request object
log.info("RestTemplate Request: URI={}, Headers={}, Body={}",
request.uri,
request.headers,
String(body))

// Fetch response
val response = BufferingClientHttpResponseWrapper(execution.execute(request, body))

// load response object
val inputStringBuilder = StringBuilder()
val bufferedReader = BufferedReader(InputStreamReader(response.body, "UTF-8"))
var line: String? = bufferedReader.readLine()
while (line != null) {
inputStringBuilder.append(line)
inputStringBuilder.append('\n')
line = bufferedReader.readLine()
}

// Show response object
log.info("RestTemplate Response: StatusCode={} {}, Headers={}, Body={}",
response.statusCode,
response.statusText,
response.headers,
inputStringBuilder.toString()
)

return response
}

private class BufferingClientHttpResponseWrapper internal constructor(private val response: ClientHttpResponse) : ClientHttpResponse {
override fun getHeaders(): HttpHeaders {
return this.response.headers
}

override fun getStatusCode(): HttpStatus {
return this.response.statusCode
}

override fun getRawStatusCode(): Int {
return this.response.rawStatusCode
}

override fun close() {
this.response.close()
}

override fun getStatusText(): String {
return this.response.statusText
}

override fun getBody(): InputStream {
if (this.body == null) {
this.body = StreamUtils.copyToByteArray(this.response.body)
}

return ByteArrayInputStream(this.body)
}

@Nullable
private var body: ByteArray? = null
}
}

Load the above Interceptor

Load the Interceptor created earlier.

import app.util.RestTemplateLoggingInterceptor
import org.springframework.context.annotation.Configuration
import org.springframework.boot.web.client.RestTemplateBuilder
import org.springframework.context.annotation.Bean
import org.springframework.web.client.RestOperations

@Configuration
class RestOperationsConfig {
@Bean
fun restOperations(): RestOperations {
return RestTemplateBuilder().additionalInterceptors(RestTemplateLoggingInterceptor()).build()
}
}

Logging sample

After then you can see request/response information in your log.

level:INFO  RestTemplate Request: URI=https://example.com, Headers={Accept=[text/plain, application/json, application/*+json, */*], Content-Length=[0]}, Body=
level:INFO RestTemplate Response: StatusCode=200 OK, Headers={Accept-Ranges=[bytes], Cache-Control=[max-age=604800], Content-Type=[text/html], Date=[Wed, 09 May 2018 08:23:02 GMT], Expires=[Wed, 16 May 2018 08:23:02 GMT], Last-Modified=[Fri, 09 Aug 2013 23:54:35 GMT], Body=<!doctype html>\n<html>\n</html>\n

🗻 References

🖥 Recommended VPS Service

VULTR provides high performance cloud compute environment for you. Vultr has 15 data-centers strategically placed around the globe, you can use a VPS with 512 MB memory for just $ 2.5 / month ($ 0.004 / hour). In addition, Vultr is up to 4 times faster than the competition, so please check it => Check Benchmark Results!!