There are scenarios where you would want to log full request/response payloads in a Spring Boot application. This recipe shows you how to utilize logback to achieve the desired results.
Below is a sample POM
with required dependencies.
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<logback.version>1.2.3</logback.version>
</properties>
<dependencies>
<dependency>
<groupId>net.rakugakibox.spring.boot</groupId>
<artifactId>logback-access-spring-boot-starter</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
</dependencies>
Create a logback-access.xml
under src/main/resources
with the following configuration: You can change what all fields are displayed in access log. For a full list of available fields, please refer to logback documentation.
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>logging uri: %requestURL | status code: %statusCode | bytes: %bytesSent | elapsed time: %elapsedTime | request-log: %magenta(%requestContent) | response-log: %cyan(%responseContent)</pattern>
</encoder>
</appender>
<appender-ref ref="STDOUT"/>
</configuration>
Create a Servlet Filter that intercepts the requests:
import ch.qos.logback.access.servlet.TeeFilter;
@Configuration
public class FilterConfiguration {
@Autowired
@Bean
public FilterRegistrationBean requestResponseFilter() {
final FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
TeeFilter filter = new TeeFilter();
filterRegBean.setFilter(filter);
filterRegBean.setUrlPatterns("/rest/path");
filterRegBean.setName("Request Response Filter");
filterRegBean.setAsyncSupported(Boolean.TRUE);
return filterRegBean;
}
}
Once this is configured, every request/response payloads (not form POST) will be logged to your default appender.
There are potential impacts to application performance once this filter is activated since every request/response payload is copied to an in memory buffer and hence additional overheads to garbage collection and CPU. Also, you have to be careful about not logging sensitive data. So, there are configurations available to disable this filter by default.
Add this to your application.properties
to disable access logging by default:
logback.access.enabled=false
It would be nice to have the filter skip/obfuscate contents of the request/response based on a pattern. The default TeeFilter
can be extended to achieve this result.