Master HTTP Request/Response Logging in Spring Boot with Logbook
This guide explains how to integrate the Logbook library into Spring Boot applications to capture detailed HTTP request and response logs, covering dependency setup, configuration options, output formats, Logback file logging, custom sinks, and RestTemplate interception for comprehensive monitoring and debugging.
1. Introduction
Recording HTTP API request and response logs is essential for monitoring, debugging, and performance optimization. It helps developers trace API usage, including request sources, parameters, response status codes, and latency, enabling quick issue identification, user behavior analysis, and system performance evaluation.
This article introduces the powerful Logbook library, which provides complete request and response logging for various client and server technologies in Spring Boot.
2. Dependency Management
<code><properties>
<!-- Use version 2.16.0 for Spring Boot 2.x -->
<logbook.version>2.16.0</logbook.version>
<!-- Use version 3.9.0 for Spring Boot 3.x -->
<logbook.version>3.9.0</logbook.version>
</properties>
<dependency>
<groupId>org.zalando</groupId>
<artifactId>logbook-spring-boot-starter</artifactId>
<version>${logbook.version}</version>
</dependency></code>After adding the appropriate dependency, configure the logging level:
<code>logging:
level:
org.zalando.logbook.Logbook: TRACE</code>2.1 Basic Usage
With the TRACE level set, no additional configuration is required. Access any endpoint and detailed request/response information will appear in the console.
<code>@GetMapping("/query")
public Object query(String name, Integer id) {
return String.format("name = %s, id = %d", name, id);
}</code>Console output (example):
Similarly, a POST endpoint logs request and response details:
<code>@PostMapping("/save")
public Book save(@RequestBody Book book) {
return book;
}</code>2.2 Output Format Configuration
Logbook supports multiple output styles such as curl, JSON, and Splunk. Switch to JSON format with:
<code>logbook:
format:
style: json</code>2.3 Log Output Strategy
Control what is logged; for example, omit the request body:
<code>logbook:
strategy: without-body</code>2.4 Excluding URLs
Exclude specific URL patterns from logging:
<code>logbook:
exclude:
- /users/*
- /products/*</code>2.5 Integration with Logback
Redirect Logbook output to a file using Logback:
<code><appender name="RequestLogger" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/log_api_info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/log-api_info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>20MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<logger name="org.zalando.logbook" level="TRACE" additivity="false">
<appender-ref ref="RequestLogger"/>
</logger></code>2.6 Custom Core Logbook Bean
<code>@Bean
public Logbook logbook() {
Logbook logbook = Logbook.builder()
.condition(Conditions.exclude(Conditions.requestTo("/users/*")
.and(Conditions.contentType("application/json"))))
.sink(new DefaultSink(new DefaultHttpLogFormatter(), new DefaultHttpLogWriter()))
.build();
return logbook;
}</code>2.7 Custom Sink Implementation
Implement the Sink interface for advanced use cases such as persisting logs to a database:
<code>@Bean
Logbook logbook() {
Logbook logbook = Logbook.builder()
.condition(Conditions.exclude(Conditions.requestTo("/users/*")))
.sink(new Sink() {
public void write(Correlation correlation, HttpRequest request, HttpResponse response) throws IOException {
System.err.println("==============================");
System.err.println("request header:\t" + request.getHeaders());
System.err.println("request body:\t" + request.getBodyAsString());
System.err.println("response header:\t" + response.getHeaders());
System.err.println("response body:\t" + response.getBodyAsString());
System.err.println("==============================");
}
})
.build();
return logbook;
}</code>2.8 Integration with RestTemplate
Register Logbook's ClientHttpRequestInterceptor with a RestTemplate bean:
<code>@Bean
RestTemplate logbookRestTemplate(LogbookClientHttpRequestInterceptor interceptor) {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setInterceptors(Arrays.asList(interceptor));
return restTemplate;
}</code>Use the configured RestTemplate to make remote calls; the request and response will be logged automatically:
<code>@GetMapping("/remote")
public Object remote() {
return this.logbookRestTemplate.getForObject("http://localhost:8010/books/666", Map.class);
}</code>Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.