Open In App

Monitoring and Logging for Reactive Applications

Last Updated : 03 Jul, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Reactive applications are designed to be responsive, resilient, elastic, and message-driven. Monitoring and logging are the crucial aspects of maintaining and troubleshooting these applications. They can provide insights into the application performance, help detect issues early, and ensure smooth operation. This article explores how to set up the monitoring and logging for the reactive applications using Spring Boot and related tools.

Monitoring Reactive Applications

Monitoring reactive applications can involve tracking the various performance metrics such as response times, error rates, throughput, and resource utilization. Tools like Spring Boot Actuator, Micrometer, and Prometheus are commonly used for monitoring reactive applications.

Key Points:

  • Spring Boot Actuator: The Spring Boot features that can provide the production-ready features like monitoring and metrics of the Spring Reactive application.
  • Micrometer: This is the application metrics and it supports the numerous monitoring systems of the application.
  • Prometheus: The open-source systems can monitoring and alerting the toolkit designed for the reliability and scalability.
  • Gafana: The open Source platform for the monitoring and observability and allowing the visualization of the metrics collected by the Prometheus.

Logging in Reactive Applications

Logging can be essential for the understanding application behavior, debugging and tracking the issues. Reactive applications, being the non-blocking and synchronous, require the logging approach that can handle the high throughput and concurrent operations efficiently. Tools like Logback, SLF4J and Elastic Stack (ELK) are often used for the logging in the reactive applications.

Key Points:

  • Logback: The logging framework for the Java applications and providing the fast and flexible logging capabilities of the reactive application.
  • SLF4J: It can defined as Simple Logging Facade for Java, It can be various frameworks and allowing the end user to plugin the desired logging framework at the deployment time.
  • Metrics: The quantitative measures that can be used to access the performance, behavior and overall health of the application.
  • Tracing: The practice of the collecting information about the execution path of the requests across the different components of the distributed system.
  • ELK Stack: The combination of the Elasticsearch, Logstash and Kibana used for the searching, analyzing and visualizing the log data.
  • Distributed Tracing: The method used to monitor and profile the microservices applications by the tracing requests as they propagate through the system.

Implementation of Monitoring and Logging for Reactive Applications

Step 1: Create the Spring Boot Project

Create a new Spring Boot Project using IntelliJ Idea and choose the following options:

  • Project Name: reactive-monitoring-logging
  • Language: Java
  • Type: Maven
  • Packaging: Jar

Refer the below image for better understanding to create the project.

Project Metadata


Step 2: Add the Dependencies

Add the following dependencies into the project.

Dependencies


Dependencies:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-tracing-bridge-brave</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-registry-prometheus</artifactId>
        <scope>runtime</scope>
    </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>


After creating the project, the file structure will look like the below image.

Folder Structure


Step 3: Configure Application Properties

Open the application.properties file and add the following configuration to enable all Actuator endpoints and configure Micrometer for Prometheus.

# Enable all Actuator endpoints
management.endpoints.web.exposure.include=*

# Configure Micrometer to use Prometheus
management.metrics.export.prometheus.enabled=true
management.metrics.export.prometheus.endpoint=/prometheus

# Application port
server.port=8080


Step 4: Create the logback-spring.xml file

Go to src > main > resources > logback-spring.xml and and create a logback-spring.xml.

XML
<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
    </root>
</configuration>


Step 5: Create GreetingService Class

Go to src > main > java > com.gfg.reactivemonitoringlogging > service > GreetingService and put the below code.

Java
package com.gfg.reactivemonitoringlogging.service;


import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

@Service
public class GreetingService {
    public Mono<String> getGreeting() {
        return Mono.just("Hello, Reactive World!");
    }
}

The GreetingService class is a Spring service that provides a reactive method getGreeting(), which returns a Mono containing the string "Hello, Reactive World!". This allows for non-blocking, asynchronous operations within reactive applications.

Step 6: Create the HelloController Class

Go to src > main > java > com.gfg.reactivemonitoringlogging > controller > HelloController and put the below code.

Java
package com.gfg.reactivemonitoringlogging.controller;


import com.gfg.reactivemonitoringlogging.service.GreetingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@RestController
public class HelloController {

    private final GreetingService greetingService;

    @Autowired
    public HelloController(GreetingService greetingService) {
        this.greetingService = greetingService;
    }

    @GetMapping("/hello")
    public Mono<String> sayHello() {
        return greetingService.getGreeting();
    }
}

The HelloController class is a REST controller in a Spring application that handles GET requests to the /hello endpoint. It uses dependency injection to inject an instance of GreetingService. The sayHello() method invokes getGreeting() from GreetingService, returning a reactive Mono<String> that asynchronously provides the greeting "Hello, Reactive World!". This ensures non-blocking, reactive handling of requests.

Step 7: Main Class

No changes are required in the main class

Java
package com.gfg.reactivemonitoringlogging;

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

@SpringBootApplication
public class ReactiveMonitoringLoggingApplication {

    public static void main(String[] args) {
        SpringApplication.run(ReactiveMonitoringLoggingApplication.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>com.gfg</groupId>
    <artifactId>reactive-monitoring-logging</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>reactive-monitoring-logging</name>
    <description>reactive-monitoring-logging</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-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-tracing-bridge-brave</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-prometheus</artifactId>
            <scope>runtime</scope>
        </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 8: Run the Application

Start the application on port 8080.

Application Running


Step 9: Testing the Endpoints

Health Endpoint:

http://localhost:8080/actuator/health

Output:

Health Endpoint


Metrics endpoint:

http://localhost:8080/actuator/prometheus

Output:

Metrics endpoint


Hello Endpoint:

http://localhost:8080/hello

Output:

Hello Endpoint

By the following this example project, we can set up the reactive application with monitoring and logging the capabilities using the Spring Boot, Micrometer, Prometheus and Logback of the Spring Application.



Next Article

Similar Reads