Open In App

How to Handle Logs and Tracing in Spring WebFlux?

Last Updated : 27 Jun, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

In modern microservices, effective logging and tracing are essential for monitoring, debugging, and maintaining the applications. Spring Webflux is a reactive web framework and it can provide the tools and techniques for handling the logs and tracing efficiently. This article will guide you through the process of setting up logging and tracing in the Spring WebFlux application.

Logging and tracing in the Spring WebFlux can involve capturing detailed information about the application execution flow and it can include the request and response data, errors, and performance metrics. This information can help the developers understand the behavior of the application and diagnose issues.

Spring WebFlux can leverage the project reactor for its reactive programming model and integrate with tools like Sleuth and Zipkin for distributed tracing and logging frameworks like Logback can be used to log events.

Implementation to handle logs and tracing in Spring WebFlux

  • To set up logging and tracing in a Spring WebFlux application, create a new Spring Reactive project with dependencies like Spring Web Reactive, Spring DevTools, and Lombok.
  • Configure application properties and create a logback-spring.xml file for logging. Implement a SampleService for processing and logging input, and a SampleController for handling requests.
  • Add necessary dependencies in pom.xml, including Spring Cloud Sleuth for tracing.
  • Run the application and test endpoints with Postman.

This setup ensures comprehensive logging and tracing for better application monitoring and debugging.

Step 1: Create the Spring Reactive Project

Create the new Spring Reactive project using spring Initializr and on creating the project, add the below dependencies into the project.

Dependencies:

  • Spring Web Reactive
  • Spring DevTools
  • Lombok

Once create the project then the file structure looks like the below image.

Folder Structure


Step 2: Configure Application Properties

Open the application.properties file add the below code for the logging and tracing of the Spring WebFlux project.

spring.application.name=logging-webflux
logging.level.org.springframework.web=INFO
logging.level.com.example=DEBUG
spring.sleuth.web.client.enabled=true
spring.sleuth.sampler.probability=1.0 

Step 3: Create the logback-spring.xml file

Create the new XML file for the logging configuration and it will save below location of the project.

Go to src > main > resources > logback-spring.xml and put the below code.

XML
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="STDOUT" />
    </root>

    <!-- Specific logger configuration -->
    <logger name="com.example" level="debug" additivity="false">
        <appender-ref ref="STDOUT" />
    </logger>
</configuration>


Step 4: Create the SampleService class

Java
package org.example.loggingwebflux;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;


@Service
public class SampleService {
    private static final Logger logger = LoggerFactory.getLogger(SampleService.class);

    public Mono<String> process(String input) {
        logger.debug("Received input: {}", input);
        // Simulate some processing logic
        return Mono.just(input.toUpperCase());
    }
}

Step 5: Create the SampleController class

Java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@RestController
public class SampleController {

    private final SampleService sampleService;

    @Autowired
    public SampleController(SampleService sampleService) {
        this.sampleService = sampleService;
    }

    /**
     * Endpoint to return a greeting to the user. Demonstrates the use of path variable
     * and asynchronous processing in Spring WebFlux.
     *
     * @param name the name of the person to greet
     * @return a Mono containing the greeting message
     */
    @GetMapping(value = "/greet/{name}", produces = MediaType.TEXT_PLAIN_VALUE)
    public Mono<String> greet(@PathVariable String name) {
        return sampleService.process(name)
                .map(processedName -> "Hello, " + processedName + "!");
    }
}

Step 6: Main Class

Java
package org.example.loggingwebflux;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class LoggingWebfluxApplication {

    public static void main(String[] args) {
        SpringApplication.run(LoggingWebfluxApplication.class, args);
    }

}


pom.xml:

XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>org.example</groupId>
    <artifactId>logging-webflux</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>logging-webflux</name>
    <description>logging-webflux</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>17</java.version>
    </properties>
    <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>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-sleuth -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
            <version>3.1.11</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <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>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>


Step 7: Run the application

Application Runs


Step 8: Testing the Endpoint

After running the application, now we will run the endpoint in Postman tool.

Endpoint Testing

By the following the steps outlined in this article, we can set up the comprehensive logging and tracing system that provides the valuable insights into the application behavior.


Next Article

Similar Reads