Live is streaming live. Watch now.

Logging Requests and Responses in Spring Boot Applications

Marc Zottner

Logging is essential for monitoring and troubleshooting running applications. This guide explains how to utilize logback to collect full request/response payloads in a Spring Boot application.

Getting Started

To begin, you create a Maven Project Object Model to enable logback. A Project Object Model or POM is an XML file that contains information about the project and configuration details. Below is a sample specifying the 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.7.1</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>   	 

Next create a logback-access.xml under src/main/resources.You can change the fields displayed in an access log. For a full list of available fields refer to the 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>

Capturing Request/Response

It is often useful to capture both the client’s request and the server’s response when diagnosing bugs. The TeeFilter servlet filter accomplishes this.

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 payload is logged to your default appender.

Enabling or Disabling Logging

There are potential impacts to application performance when this filter is activated. Every request/response payload is copied to an in-memory buffer, creating additional garbage collection and CPU overhead. To reduce overhead or to avoid logging sensitive data, add the following to your application.properties to disable access logging by default:

logback.access.enabled=false

Keep Learning

You can find out more by reading the Spring Boot documentation on logging or the full logback manual.

Logging has three elements: collection, indexing, and visualization. This guide explains the first element, collection. For indexing and visualization, there’s a wide ecosystem of open-source technologies that can be used. For example, the “EFK stack” (Elasticsearch, Fluentd, and Kibana) is popular for solving this problem.

Two open-source tools that help with logging and visualization are Prometheus and Grafana. Prometheus excels at gathering metrics from a wide array of sources, while Grafana is the go-to tool for visualizing complex time-series data. The following guides explain how to use these tools in Kubernetes environments:

Spring Boot also provides health checks for application monitoring in addition to logging. Learn how to enable health checks using Spring Boot Actuator.