Master HTTP Request/Response Logging in Spring Boot 3 with Logbook

This guide introduces the Logbook library for Spring Boot 3, explains how to add the starter dependency, configure default logging, customize request filtering, log formatting, sink implementation, and client‑side interception, and provides complete code examples and configuration snippets.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Master HTTP Request/Response Logging in Spring Boot 3 with Logbook

1. Introduction

Logging HTTP request and response data is essential for system observability and debugging. Logbook is an extensible Java library that can capture full request/response traffic for both client and server sides, making it useful for audit, troubleshooting, and analysis.

2. Key Features

Logs HTTP request and response bodies (unauthenticated requests are partially logged).

Customizable log format, storage location, and trigger conditions.

Supports Servlet containers, Apache HttpClient, OkHttp, and can be integrated with other frameworks via a clean API.

Optional sensitive‑data masking.

Spring Boot auto‑configuration.

Compatibility with Scalyr platform.

Reasonable defaults.

3. Dependency

<dependency>
  <groupId>org.zalando</groupId>
  <artifactId>logbook-spring-boot-starter</artifactId>
  <version>3.12.3</version>
</dependency>

4. Default Auto‑Configuration

The starter automatically registers several beans, including a servlet filter, an optional second filter for unauthenticated requests (when Spring Security is present), header/parameter/body filters, an HTTP/JSON formatter, and a log writer.

5. Practical Examples

5.1 Basic Logging Configuration

Enable TRACE level for Logbook in application.yml (or application.properties) to activate request/response logging:

logging:
  level:
    '[org.zalando.logbook.Logbook]': TRACE

Example controller method:

@GetMapping("/query")
public ResponseEntity<?> query(String keyword) {
    return ResponseEntity.ok("查询: %s".formatted(keyword));
}

Console output shows the captured request and response (see image).

Console log output
Console log output

5.2 Custom Request Filtering

Define a bean named requestCondition that implements Predicate<HttpRequest> to exclude specific paths from logging:

@Component("requestCondition")
public class ApiPredicate implements Predicate<HttpRequest> {
    @Value("${pack.excludes.paths}")
    private Set<String> excludes;
    @Override
    public boolean test(HttpRequest t) {
        return !excludes.contains(t.getPath());
    }
}

Configuration example:

pack:
  excludes:
    paths: /api/query,/api/create

Requests matching those paths will no longer be logged.

5.3 Custom Log Formatter

Implement HttpLogFormatter to control the exact format of logged requests and responses:

@Component
public class PackHttpLogFormatter implements HttpLogFormatter {
    @Override
    public String format(Precorrelation precorrelation, HttpRequest request) throws IOException {
        String correlationId = precorrelation.getId();
        StringBuilder sb = new StringBuilder(request.getBodyAsString().length() + 2048);
        sb.append(" Request: ").append(correlationId).append('
');
        sb.append("Remote: ").append(request.getRemote()).append('
');
        sb.append(request.getMethod()).append(' ');
        RequestURI.reconstruct(request, sb);
        sb.append(' ').append(request.getProtocolVersion()).append('
');
        return sb.toString();
    }
    @Override
    public String format(Correlation correlation, HttpResponse response) throws IOException {
        String correlationId = correlation.getId();
        StringBuilder sb = new StringBuilder(response.getBodyAsString().length() + 2048);
        sb.append(" Response: ").append(correlationId).append('
');
        sb.append("Duration: ").append(correlation.getDuration().toMillis()).append(" ms
");
        sb.append(response.getProtocolVersion()).append(' ').append(response.getStatus());
        if (response.getReasonPhrase() != null) {
            sb.append(' ').append(response.getReasonPhrase());
        }
        sb.append('
');
        return sb.toString();
    }
}

Resulting log entries are shown in the accompanying screenshot.

Custom formatter output
Custom formatter output

5.4 Custom Sink

Implement Sink to write logs to a database, message queue, or any other destination:

@Component
public class PackLogSink implements Sink {
    @Override
    public void write(Precorrelation precorrelation, HttpRequest request) throws IOException {
        // optional handling for request‑only logging
    }
    @Override
    public void write(Correlation correlation, HttpRequest request, HttpResponse response) throws IOException {
        System.err.printf("写日志 - 请求路径: %s, 查询参数: %s%n响应结果:%s%n",
                request.getPath(), request.getQuery(), response.getBodyAsString());
    }
}

Sample console output:

写日志 - 请求路径: /api/query, 查询参数: keyword=spring
响应结果:查询: spring

5.5 Logging HTTP Client Calls

Register LogbookClientHttpRequestInterceptor with a RestClient bean to capture outbound HTTP calls:

@Bean
public RestClient restClient(RestClient.Builder builder, LogbookClientHttpRequestInterceptor interceptor) {
    return builder.baseUrl("http://localhost:8080")
            .requestInterceptors(i -> i.add(interceptor))
            .build();
}

Example remote‑call controller:

@GetMapping("/remote")
public ResponseEntity<?> remote() {
    String body = restClient.get()
            .uri("/enum/query?sex={0}", "female")
            .retrieve()
            .body(String.class);
    return ResponseEntity.ok(body);
}

Logbook logs the outgoing request and the received response (see image).

Client interceptor log
Client interceptor log

6. Additional Configuration

The starter also provides a rich set of optional properties for fine‑tuning log output, bean replacement, and integration with other logging platforms. The following images illustrate the default bean list and further configuration options.

Default bean list
Default bean list
backendJavalogginglogbookspring-bootSpring Boot StarterHTTP logging
Spring Full-Stack Practical Cases
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.