In the production environment, logging of request and response in a spring boot application is essential for understanding the request pattern. Spring Boot actuator allows you to trace the request and response using the endpoint url. The httptrace actuator endpoint’s URI only displays the last 100 requests. In this article, we’ll look at how to log and capture requests and responses in a spring boot application.
The Spring boot actuator http trace endpoint url will capture and store the request and response in memory. The in memory logs will rollover after 100 requests. The spring boot application collects the request and response and logs them in the logger using a custom HttpTraceRepository.
1. add dependency in pom.xml
The spring boot actuator has two dependents: spring-boot-starter-actuator and spring-boot-starter-web. The spring-boot-starter-actuator contains all of the actuator endpoints. The spring-boot-starter-web dependent exposes the endpoint url in the web browser. In the spring boot application, the spring boot actuator is used to capture the request and response.
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2. Spring Boot Actuator configuration
The spring boot actuator does not support the http trace from version 2.2. The HttpTraceRepository bean should be loaded explicitly in the spring boot application context. Create an InMemoryHttpTraceRepository object with the following code to create the HttpTraceRepository bean. After tracing the request and response, the add method will save them in memory. The class’s add method is overridden, and it logs the request and response while assigning in memory.
SpringActuatorConfiguration.java
package com.yawintutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.actuate.trace.http.HttpTrace;
import org.springframework.boot.actuate.trace.http.HttpTraceRepository;
import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
@Configuration
public class SpringActuatorConfiguration {
@Bean
public HttpTraceRepository httpTraceRepository() {
return new InMemoryHttpTraceRepository() {
ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
Logger logger = LoggerFactory.getLogger(InMemoryHttpTraceRepository.class);
@Override
public void add(HttpTrace trace) {
try {
logger.info(objectMapper.writeValueAsString(trace));
} catch (JsonProcessingException e) {
logger.error(e.getMessage(), e);
}
super.add(trace);
}
};
}
}
3. Sample Rest Controller class
The following example will show the sample rest controller class. The rest controller class will have a rest api /hello.
TestController.java
package com.yawintutor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String testHello() {
System.out.println("Executing testHello Method");
return "TEST OK";
}
}
4. Run the application
After starting the spring boot application, go to the rest api url in the browser. http://localhost:8080/hello. RestController will be called and executed. The spring boot actuator will capture the request and response of the rest api call and store them in memory. The custom InMemoryHttpTraceRepository class will store the request and response in the logger.
The request and response will be printed in the console window by the logger. The corresponding log will be printed in the console window when the url is called. The request and response information can be saved by redirecting the log to a log file.
2021-11-01 20:06:38.799[0;39m [32m INFO[0;39m [35m89896[0;39m [2m---[0;39m [2m[nio-8080-exec-1][0;39m [36mo.s.b.a.t.h.InMemoryHttpTraceRepository [0;39m [2m:[0;39m {"timestamp":1635777398.762307000,"principal":null,"session":null,"request":{"method":"GET","uri":"http://localhost:8080/hello","headers":{"accept-language":["en-us"],"host":["localhost:8080"],"upgrade-insecure-requests":["1"],"connection":["keep-alive"],"accept-encoding":["gzip, deflate"],"accept":["text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"],"user-agent":["Mozilla/5.0"]},"remoteAddress":null},"response":{"status":200,"headers":{"Keep-Alive":["timeout=60"],"Connection":["keep-alive"],"Content-Length":["7"],"Date":["Mon, 01 Nov 2021 14:36:38 GMT"],"Content-Type":["text/html;charset=UTF-8"]}},"timeTaken":26}