Spring 5
WebClient
Logging
Java
HTTP Requests

how to log Spring 5 WebClient call

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Logging is an essential practice when working with web applications, as it helps track system behavior, detect anomalies, and diagnose issues. In the context of web applications using Spring Framework, especially with Spring 5's reactive WebClient, logging HTTP requests and responses can provide valuable insights. In this article, we delve into the mechanics of logging with WebClient, including setup, configuration, and best practices.

Overview of Spring WebClient

Spring WebClient is a non-blocking, reactive client that supports synchronous and asynchronous requests. It is part of Spring WebFlux and is designed to work with reactive streams, providing a modern approach to handling web requests compared to its predecessor, RestTemplate.

Configuring Logging in Spring WebClient

Effective logging in WebClient involves two main aspects: configuring logging for HTTP requests/responses and utilizing WebClient's exchange() method to log requests and responses gracefully.

Library Dependency

To access logging interceptors and utilities, ensure you have the necessary dependencies in your pom.xml if using Maven:

xml
1<dependency>
2    <groupId>org.springframework.boot</groupId>
3    <artifactId>spring-boot-starter-webflux</artifactId>
4</dependency>
5<dependency>
6    <groupId>org.springframework.boot</groupId>
7    <artifactId>spring-boot-starter-logging</artifactId>
8</dependency>

For Gradle-based projects, use:

groovy
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.boot:spring-boot-starter-logging'

Basic Logging Setup

Spring Boot uses SLF4J with Logback as the default logging framework. To enable logging of requests and responses:

  1. Log Configuration: Adjust your application.properties or application.yml to set the logging level. For comprehensive logs, set DEBUG level.
properties
   logging.level.org.springframework.web.reactive.function.client.WebClient=DEBUG
  1. Using Logback Configuration (logback.xml):
xml
   <configuration>
       <logger name="org.springframework.web.reactive.function.client" level="DEBUG"/>
   </configuration>

Intercepting Requests and Responses

To add custom logging, consider using filters and hooks available in WebClient:

java
1WebClient webClient = WebClient.builder()
2    .filter((clientRequest, next) -> {
3        logRequest(clientRequest);
4        return next.exchange(clientRequest)
5            .doOnNext(this::logResponse);
6    })
7    .build();
8
9private void logRequest(ClientRequest request) {
10    System.out.println("Request: " + request.method() + " " + request.url());
11    request.headers().forEach((name, values) -> {
12        values.forEach(value -> System.out.println(name + ": " + value));
13    });
14}
15
16private void logResponse(ClientResponse response) {
17    System.out.println("Response: " + response.statusCode());
18    response.headers().asHttpHeaders().forEach((name, values) -> {
19        values.forEach(value -> System.out.println(name + ": " + value));
20    });
21}

Handling Request/Response Bodies

To log request and response bodies, buffer the content. This can be memory-intensive for large payloads, so use cautiously:

java
1private void logResponseBody(Mono<ClientResponse> responseMono) {
2    responseMono.flatMap(response -> response.bodyToMono(String.class)
3        .doOnNext(body -> System.out.println("Response Body: " + body))
4    ).subscribe();
5}

Attach this to the response processing part of your filter implementation.

Best Practices for Logging WebClient Calls

  • Log at Appropriate Levels: Use DEBUG level for detailed logs and INFO for general request/response summaries. Avoid logging sensitive information at verbose levels in production.
  • Use Structured Logging: Employ JSON or key-value pairs to make logs searchable and structured.
  • Avoid Excessive Logging: Logging large payloads or excessive details can impact performance.
  • Leverage MDC (Mapped Diagnostic Context): Use MDC to associate requests with certain context information which is useful for correlation in distributed systems.
  • Filter Sensitive Information: Be cautious not to log sensitive information, like passwords or personal details.

Summary Table

ActionRecommendation
Log LevelsUse DEBUG for development; adjust as necessary for production
Intercept Requests/ResponsesUtilize .filter() on WebClient for custom logging
Log ConfigurationUse logback.xml or application.properties for configuring log levels and appenders
Log FormatConsider structured logging with JSON format
Body LoggingBuffer with caution; applicable for non-sensitive data or in-depth debugging
Sensitive InformationFilter out or mask sensitive data in logs

Conclusion

Logging in Spring 5 WebClient is a powerful tool to observe and diagnose runtime behavior. By carefully configuring, intercepting, and managing logs, developers can gain deep insights into their applications while maintaining performance and security. As always, remember to align your logging strategy with your application's operational requirements and data privacy policies.


Course illustration
Course illustration

All Rights Reserved.