Steps To Implement Automatic MDC logs in Spring WebFlux

To Implement Automatic MDC logs in Spring WebFlux, here we created a Spring Boot project which is maven for this project we use below dependencies.

Project dependencies:

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>


Project Folder:


Step 1:

Once project is successfully created, then we created a Configuration file with name log4j2.xml in the resource folder. This file is used for define the log pattern and include MDC information. You can see this file in the above project folder image.

XML
<?xml version="1.0" encoding="UTF-8"?>

<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %c{1} - %msg %X{requestId}%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>


Step 2:

  • Once XML configuration file is created for MDC.
  • After that, we created a MDCFilter component class by using @Component annotation.
  • This class is extends to WebFilter.
  • After this, we created overrides filter method, this method can filter the request.
  • And this filter generates a unique requestId for each incoming request and sets it in the MDC.
Java
package com.app;

import org.apache.logging.log4j.ThreadContext;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

import java.util.UUID;

@Component
public class MDCFilter implements WebFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        String requestId = UUID.randomUUID().toString();
        ThreadContext.put("requestId", requestId);
        return chain.filter(exchange)
                    .doOnTerminate(ThreadContext::clearMap);
    }
}


Step 3:

Finally we created RestController class with name MDCController by using @RestController Spring annotation.

  • In this class we define the logger object by using Logger class which is available in the Log Manager.
  • This class takes out controller class input.
  • And, created a API endpoint with method name hello().
  • Simply this method return a String object by using Mono publisher.
Java
package com.app;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@RestController
public class MDCController {

    private static final Logger logger = LogManager.getLogger(MDCController.class);

    @GetMapping("/hello")
    public Mono<String> hello() {
        logger.info("Handling /hello request");
        return Mono.just("Welcome to w3wiki!");
    }
}


Step 4:

Once project development is completed with required logic, now run this project as Spring Boot App or we can run this project by using Maven commends also.

  • Here run this project as Spring Boot App.
  • This Project running on 8080 port number with Netty server by default.


Step 5:

Now test API endpoint. Here we use Post man tool for testing API endpoint.

http://localhost:8080/hello

Postman Output:


Step 6:

Now, observe console in the STS IDE, then you can observe logs in that console. We provide the logs for API endpoint. After testing the API we got below log. This log indicates that the API endpoint is executed successfully.

Output:




Automatic MDC logs in Spring WebFlux

MDC full form is Mapped Diagnostic Context. It is used to improve the application logging. This means the Mapped Diagnostic Context provides a way to enrich the log messages with more information about that could be unavailable in the scope where the logging functionality really needed. Using Mapped Diagnostic Context (MDC) in Spring WebFlux is particularly useful for adding contextual information to logs, making it easier to trace the flow of requests and correlate logs with specific requests or sessions.

In this article, we will explain how to create MDC logs in the Spring WebFlux along with a suitable example. And, here, we use logging frameworks like Log4j, Logback, SLF4J. These logging frameworks allow us to enrich log messages with additional contextual information.

Key Features of MDC:

  • Contextual Logging: MDC allows us to insert contextual information into our logs. This is particularly useful for tracking the flow of execution in applications.
  • Thread-Specific Context: Each thread has its copy of the context map, ensuring that the context data is specific to the thread that set it.
  • Automatic Inclusion in Logs: Once context information is added to MDC, it can be automatically included in log messages without modifying the log statements themselves.
  • Dynamic Data: We can dynamically add, remove, or update key-value pairs in the MDC, allowing us to change the context information as the application executes.
  • Log Pattern Configuration: MDC values can be included in log output by configuring the log pattern in our logging framework configuration.
  • Ease of Use: MDC APIs are simple and easy to use, typically involving basic operations to put, get, and remove context data.

Similar Reads

Steps To Implement Automatic MDC logs in Spring WebFlux

To Implement Automatic MDC logs in Spring WebFlux, here we created a Spring Boot project which is maven for this project we use below dependencies....