Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana

In this article, we are going to cover Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana.

Prerequisites:

  • AWS Account with Ubuntu 24.04 LTS EC2 Instance.
  • Basic understanding of Java, Maven, Spring Boot, OpenTelemetry, Prometheus, and Grafana.

Step #1:Install Essential Software (Java and Maven)

Update System Packages:

sudo apt update
sudo apt upgrade -y
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 1

Install Java Development Kit (JDK 17):

sudo apt install openjdk-17-jdk -y
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 2

After installation, verify Java:

java -version
javac -version
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 3

Output would be like:

openjdk version "17.0.15" 2025-04-15
OpenJDK Runtime Environment (build 17.0.15+6-Ubuntu-0ubuntu124.04)
OpenJDK 64-Bit Server VM (build 17.0.15+6-Ubuntu-0ubuntu124.04, mixed mode, sharing)
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 4

Install Apache Maven:

sudo apt install maven -y
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 5

Verify Maven installation:

mvn -v
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 6

You should see output similar to this:

Apache Maven 3.8.7 (b89d5959fc9c8535bc84a1ddf69ab5e2432a7860)
Maven home: /usr/share/maven
Java version: 17.0.10, vendor: Private Build, runtime: /usr/lib/jvm/java-17-openjdk-amd64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "6.5.0-1018-aws", arch: "amd64", family: "unix"
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 7

Step #2:Create the Project Directory and pom.xml file

Now we will create the main directory for your Spring Boot project and then create its essential pom.xml file

Create the Root Project Directory:

mkdir ~/my-otel-app
cd ~/my-otel-app
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 8

Create a pom.xml file:

This file is the Project Object Model (POM) for Maven. It defines your project’s structure, dependencies (libraries your app needs), and how it should be built.

nano pom.xml
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 9

Run the following command:

nano pom.xml
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 10

An open editor will open paste the following content inside it:

<?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.2.7</version> <relativePath/> </parent>
    <groupId>com.example</groupId>
    <artifactId>my-otel-app</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>my-otel-app</name>
    <description>Demo project for OpenTelemetry Spring Boot</description>

    <properties>
        <java.version>17</java.version>
    </properties>

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

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

        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
            <version>2.5.0</version> </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 11

Save the file by pressing Ctrl+x; it will ask, “Save modified buffer? (Y/N/C)”. Type Y (for Yes). nano will confirm the file name just press the Enter key.

Step #3:Create Java Source Directory and Main Application Class

Now we will create Java Source Directory Structure and Main Application Class. So first we will create Java Source Directory Structure which is created using the following command:

mkdir -p src/main/java/com/example/myotelapp
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 12

Create MyOtelAppApplication.java:

This is the main class that Spring Boot uses to start your application. Use nano to create and edit this file inside the newly created directory structure.

nano src/main/java/com/example/myotelapp/MyOtelAppApplication.java
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 13

An open editor will open paste the following content inside it:

package com.example.myotelapp;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import jakarta.annotation.PostConstruct; // Make sure to use jakarta for Spring Boot 3+

@SpringBootApplication
public class MyOtelAppApplication {

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

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

    @PostConstruct
    public void logApplicationStartup() {
        logger.info("MyOtelAppApplication has started successfully!");
        logger.debug("This is a debug log message during startup.");
    }
}
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 14

Save the file by pressing Ctrl+x; it will ask, “Save modified buffer? (Y/N/C)”. Type Y (for Yes). nano will confirm the file name just press the Enter key.

Step #4:Create the REST Controller Class with Error Handling

This step involves creating the Spring Boot REST controller that will handle incoming web requests. This controller will include multiple endpoints.

Create MyController.java file:

You will create this file in the same directory as your main application class (MyOtelAppApplication.java). Ensure you are still in your ~/my-otel-app directory.

nano src/main/java/com/example/myotelapp/MyController.java
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 15

An open editor will open paste the following content inside it:

package com.example.myotelapp;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

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

    @GetMapping("/hello")
    public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
        logger.info("Received request for /hello with name: {}", name);
        String message = String.format("Hello, %s! From MyOtelApp.", name);
        logger.debug("Sending response: {}", message);
        return message;
    }

    @GetMapping("/greeting")
    public String greeting() {
        logger.info("Received request for /greeting.");
        try {
            Thread.sleep(100); // Simulate some work
            logger.debug("Simulated work completed for /greeting.");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            logger.error("Greeting interrupted", e);
        }
        return "Greetings from OpenTelemetry-enabled App!";
    }

    @GetMapping("/calculate")
    public ResponseEntity<String> calculate(@RequestParam int dividend, @RequestParam int divisor) {
        logger.info("Received request for /calculate with dividend: {} and divisor: {}", dividend, divisor);
        try {
            if (divisor == 0) {
                logger.error("Attempted division by zero! Dividend: {}", dividend);
                throw new IllegalArgumentException("Divisor cannot be zero.");
            }
            int result = dividend / divisor;
            String message = String.format("Result of %d / %d = %d", dividend, divisor, result);
            logger.info("Calculation successful: {}", message);
            return ResponseEntity.ok(message); // Returns 200 OK
        } catch (IllegalArgumentException e) {
            logger.error("Calculation failed due to invalid argument: {}", e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error: " + e.getMessage()); // Returns 500 Internal Server Error
        } catch (Exception e) {
            logger.error("An unexpected error occurred during calculation: {}", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An unexpected error occurred."); // Returns 500 Internal Server Error
        }
    }
}
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 16

Save the file by pressing Ctrl+x; it will ask, “Save modified buffer? (Y/N/C)”. Type Y (for Yes). nano will confirm the file name just press the Enter key.

Verify the file structure by using the following command:

ls -R
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 17

Output should be like this:

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 18

Step #5:Build the Spring Boot Application and Download the OpenTelemetry Java Agent

Build the Spring Boot Application:

Ensure you are in the root of your project directory (~/my-otel-app) before running this command. This command tells Maven to clean up any previous build artifacts, download any necessary dependencies and then compile your Java code and package it.

cd ~/my-otel-app # Ensure you are in the correct directory
mvn clean package -DskipTests
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 19

Output should be like this:

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 20

Now download the OpenTelemetry Java Agent by running the following command:

wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.17.1/opentelemetry-javaagent.jar
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 21

Verify the download by running the following command:

ls
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 22

It should look like this:

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 23

Step #6:Run the Application with OpenTelemetry Logging Exporter

In this step we will execute the Spring Boot application along with the OpenTelemetry Java Agent.

Execute the Spring Boot Application with the Java Agent by executing the following command:

java -Dotel.traces.exporter=logging \
     -Dotel.metrics.exporter=logging \
     -Dotel.logs.exporter=logging \
     -Dotel.exporter.otlp.traces.endpoint=none \
     -Dotel.exporter.otlp.metrics.endpoint=none \
     -Dotel.exporter.otlp.logs.endpoint=none \
     -javaagent:./opentelemetry-javaagent.jar \
     -jar target/my-otel-app-0.0.1-SNAPSHOT.jar
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 24

If you see the output like the following, then the task is done:

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 25

If you see like the following, then don’t worry it is part of the task only.

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 26

Step #7:Interact with Your Spring Boot Application and Observe Telemetry (including Errors)

In this part, we will interact with the application’s web endpoints from the browser using Swagger UI. We will specifically trigger both successful (200 OK) and error (500 Internal Server Error) responses. As we do, the OpenTelemetry agent will automatically capture traces and enrich the application logs, and all of this telemetry will be printed directly to the same terminal where the Spring Boot app is running.

Access Swagger UI:

Open a web browser on the system. Navigate to the Swagger UI provided by the Spring Boot application.

http://<YOUR_EC2_PUBLIC_IP>:8080/swagger-ui.html
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 27

Here the IP address is different, you have to replace it with your IP address. You will see the interface like the below:

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 28

Make API Calls and Observe Responses in Swagger UI:

Once the Swagger UI loads in your browser, you will see a list of your application’s API endpoints. You just need to test those endpoints.

For e.g: Test the /calculate endpoint for a 200 OK (successful calculation) by entering the values. You will see the following output:

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 29

Observe Telemetry in the EC2 Terminal:

Immediately switch back to your terminal where your Spring Boot application is still running. As you make these API calls in your browser, new telemetry data (traces, logs) will stream into the console output. You will be able to see the output like the below:

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 30

The following output you will be able to see if any error will be occured:

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 31
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 32

Step #8:Setting up Prometheus to collect metrics from your Spring Boot application through the OpenTelemetry Java Agent.

Stop your running Spring Boot Application by pressing the key Ctrl+C. This step is important because we need to change how the OpenTelemetry agent starts with your application.

Modify and restart Spring Boot Application with Prometheus Exporter by entering the following command:

java -javaagent:./opentelemetry-javaagent.jar \
     -Dotel.traces.exporter=logging \
     -Dotel.metrics.exporter=prometheus \
     -Dotel.exporter.prometheus.port=9464 \
     -Dotel.logs.exporter=logging \
     -jar target/my-otel-app-0.0.1-SNAPSHOT.jar
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 33

Install Prometheus on EC2:

Open the new terminal or make the duplicate of the tab. Go to the home directory by entering the following command:

cd ~
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 34

Now we need to download the Prometheus server software. Open your web browser and go to the official Prometheus download page: https://prometheus.io/download/

Look for the linux-amd64 version. It will be a file ending with .tar.gz. Copy its link address and paste it in the terminal, but make sure to add “wget” before the link.

wget https://github.com/prometheus/prometheus/releases/download/v3.5.0/prometheus-3.5.0.linux-amd64.tar.gz
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 35

After the download finishes, you need to extract the contents of the downloaded file. In your terminal, type this command and press Enter:

tar -xvf prometheus-3.5.0.linux-amd64.tar.gz
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 36

Change into the Prometheus directory by executing the following command:

cd prometheus-3.5.0.linux-amd64/
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 37

Run the following command:

nano prometheus.yml
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 38

An open editor will open paste the following content inside it:

# ... (there will be other lines above this) ...

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  # --- START OF NEW JOB FOR YOUR SPRING BOOT APP VIA OTEL AGENT ---
  - job_name: 'my-otel-app'
    metrics_path: /metrics # This is the standard path where OTel agent exposes Prometheus metrics
    static_configs:
      - targets: ['localhost:9464'] # This is the port for the OpenTelemetry agent's Prometheus exporter
  # --- END OF NEW JOB ---
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 39

You’ll see a section like this. Don’t change the existing job_name entry. Instead, carefully add a new job below it, exactly as shown.

Save the file by pressing Ctrl+x; it will ask, “Save modified buffer? (Y/N/C)”. Type Y (for Yes). nano will confirm the file name just press the Enter key.

Step #9: Start the Prometheus Server

Start the Prometheus Server by executing the following command in your current terminal:

./prometheus --config.file=prometheus.yml
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 40

You should look something like the below:

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 41

Now open the new tab in your browser and access Prometheus UI and verify metrics.

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 42

You will see the interface like below:

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 43

Go to the target health option and see the state is up (it should be in green colour) or not.

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 44

Execute the query in the expression box.

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 45

You can make some changes in the swagger and can again check the difference.

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 46

Step #10: Adding Grafana

Install Grafana on EC2 by running the following command.

sudo apt-get install -y apt-transport-https software-properties-common wget
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 47

Add the Grafana GPG key.

sudo wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 48

Add the Grafana repository to your APT sources. This tells your system where to find Grafana packages.

echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 49

Update your APT package list by executing the following command:

sudo apt-get update
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 50

Install Grafana by executing the following command:

sudo apt-get install grafana -y
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 51

You should see the output like below:

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 52

Reload the systemd daemon:

sudo systemctl daemon-reload
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 53

Enable Grafana to start automatically on boot:

sudo systemctl enable grafana-server
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 54

Step 11#:Start the Grafana service

Start the Grafana service by executing the following command.

sudo systemctl start grafana-server
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 55

Check the Grafana service status by executing the following command.

sudo systemctl status grafana-server
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 56

You should look the output like the below:

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 57

Step 12#:Access Grafana UI

Access Grafana UI in your browser. Open a new tab in your web browser and type the following URL

http://YOUR_EC2_PUBLIC_IP:3000
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 58

you should see like this.

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 59

Enter the username and password as admin which is default.

Run the following command:

sudo nano /etc/grafana/grafana.ini
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 60

Do the following changes:

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 61
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 62

Step 13#:Add the Data Source

Add the data source as Prometheus.

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 63
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 64

Here add your IP address.

Step 14#:Create the Dashboards

Go to the dashboard section and create the new dashboard.

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 65

Run the following command in your terminal:

sudo systemctl restart grafana-server
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 66

You will be see the dashboard like the following:

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 67

Step 15#:Setting Up the Alerts

Go to the Alerting Section in left side.

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 68

Create the new Alert rule and make sure you enter the following query which is there in the image:

rate(http_server_request_duration_seconds_count[1m])
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 69

Set up the other things like contact details and the select the dashboard and panel.

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 70

Once done wait for the firing, when the firing is done you will receive an notification through email.

Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 71
Monitoring Java API 5xx alerts with OpenTelemetry, Prometheus, and Grafana 72

Conclusion:

Combining OpenTelemetry, Prometheus, and Grafana provides a powerful and flexible solution for monitoring 5xx errors in Java APIs. This approach not only helps to detect and visualize failures in real-time but also offers deep insights into application behavior through distributed tracing and metrics. As systems grow in complexity, having this level of observability becomes essential for maintaining performance, reducing downtime, and accelerating debugging.

Related Articles:

Install Spring Boot Application on Ubuntu 24.04 LTS

Reference:

Java OpenTelemetry

https://opentelemetry.io/docs/languages/java

Yash Chavan

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Share via
Copy link
Powered by Social Snap