Request Logging with Spring WebFlux Filters

Intercept incoming API requests before they reach your application to filter or modify data according to your applications needs.

In the world of reactive programming, Spring WebFlux offers a powerful framework for building non-blocking, asynchronous applications. One common requirement in web development is to log information about incoming requests, such as the URL and the request body. In this article, we’ll walk through the process of creating a Spring WebFlux Web Filter that captures and logs these details using the SLF4J logger.

Introduction to Spring WebFlux Web Filters

Web Filters in Spring WebFlux are components that intercept incoming HTTP requests and responses. They provide a way to perform pre-processing or post-processing tasks on requests before they reach the main handler or after the response has been generated. In this article, we’ll focus on creating a pre-processing filter to log information about incoming requests.

Setup

Before we begin, ensure you have a Spring WebFlux project set up. You can create a new Spring Boot project using Spring Initializr and selecting the “Reactive Web” dependency.

Creation

Let’s create a custom web filter that logs the URL and request body using SLF4J logger. Create a class named RequestLoggingFilter:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import reactor.core.publisher.Mono;
import reactor.core.publisher.SignalType;
import reactor.util.annotation.Nullable;

@Component
public class RequestLoggingFilter implements WebFilter {

    private static final Logger logger = LoggerFactory.getLogger(RequestLoggingFilter.class);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String url = request.getURI().toString();

        // Get and log the request body
        return DataBufferUtils.join(exchange.getRequest().getBody())
            .doOnNext(buffer -> {
                byte[] bytes = new byte[buffer.readableByteCount()];
                buffer.read(bytes);
                String body = new String(bytes, StandardCharsets.UTF_8);
                logger.info("Request URL: {}", url);
                logger.info("Request Body: {}", body);
            })
            .doOnCancel(() -> logger.debug("Request body logging cancelled"))
            .doFinally(this::logSignalType)
            .then(chain.filter(exchange));
    }

    private void logSignalType(@Nullable SignalType signalType) {
        logger.debug("Request logging signal: {}", signalType);
    }
}

Configuration

The @Component annotation indicates that RequestLoggingFilter is a Spring-managed bean. The WebFilter interface requires implementing the filter method, where we extract the URL and request body. We use SLF4J’s logger to log the information at different levels.

Testing

To test the filter, simply send a request to your application’s endpoints. You’ll see the URL and request body logged using the SLF4J logger.

Conclusion

Creating a Spring WebFlux Web Filter to log request details using the SLF4J logger is a valuable technique for debugging and monitoring incoming requests. By understanding the core concepts of Web Filters and leveraging the reactive nature of Spring WebFlux, you can enhance your application’s logging capabilities and gain insights into the data flowing through your system.