Instrumenting Java Application with Maven Using OpenTelemetry Java Agent

In this article, we’ll demonstrate how to instrument a Java application built with Maven using the OpenTelemetry Java Agent. Observability is a cornerstone of modern application development. OpenTelemetry provides a unified framework to collect and analyze telemetry data such as traces, metrics, and logs. By the end, you’ll have a Spring Boot application configured for tracing, metrics, and logging with minimal manual effort.

Prerequisites

Before you start, ensure you have the following installed on your system.

  • AWS Account with Ubuntu 24.04 LTS EC2 Instance.
  • Java Development Kit (JDK), Maven installed.

Step #1:Set Up Ubuntu EC2 Instance

If you don’t have JDK or Maven installed on your system you can install it by using following commands.

First Update the package list.

sudo apt update
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 1

Spring Boot requires Java, so install OpenJDK.

sudo apt install openjdk-17-jdk -y
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 2

Verify the Java installation.

java -version
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 3

You should see the version details of your Java installation.

Now lets install Maven. Maven is the build tool used to manage Java projects.

sudo apt install maven -y
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 4

Verify the Maven installation.

mvn -version
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 5

Step #2:Create a New Java Application with Maven

Maven follows a standard directory layout, which makes it easier to manage projects. To create a new Maven project, you can use the command line.

Run the following command to create a new project.

mvn archetype:generate -DgroupId=com.example -DartifactId=java-simple -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 6
  • groupId: A unique identifier for your project (usually the package name).
  • artifactId: The name of your project.
  • archetypeArtifactId: The template for the project; maven-archetype-quickstart creates a simple Java project.
  • interactiveMode: Set to false to skip interactive prompts.

Navigate to the project directory.

cd java-simple
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 7

Open the pom.xml file and update the file for Spring Boot dependencies.

The pom.xml (Project Object Model) file is the core of a Maven project. It contains configuration details, such as dependencies, build settings, and project information.

nano pom.xml
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 8

replace its content with the following:

<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 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>helloworld</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>helloworld</name>
  <url>http://maven.apache.org</url>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.0.0</version>
    <relativePath />
  </parent>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </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>
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 9

Step #3:Create the Java Application and Controller

Create a new file named DiceApplication.java and RestController.java in the src/main/java/com/example directory with the following content:

For that first navigate to the directory.

cd src/main/java/com/example
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 10

Remove the default App.java file.

sudo rm App.java
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 11

Create a file named DiceApplication.java

nano DiceApplication.java
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 12

Add the following code:

package com.example;

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

@SpringBootApplication
public class DiceApplication {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(DiceApplication.class);
        app.setBannerMode(Banner.Mode.OFF);
        app.run(args);
    }
}

Explanation of the code:

This is the main application code for a simple Java Spring Boot project, which launches a web application without displaying the Spring Boot banner.

  1. Package Declaration:
    • package com.example;: Defines the package for the DiceApplication class. In Java, packages help organize classes logically and avoid naming conflicts.
  2. Import Statements:
    • Imports Spring Boot classes for app startup (SpringApplication) and configuration (SpringBootApplication), along with Banner for optional customization.
  3. Class Annotation:
    • @SpringBootApplication: This annotation marks the main class of the Spring Boot application, enabling features like:
      • @Configuration: Allows Java-based configuration in place of XML.
      • @EnableAutoConfiguration: Enables automatic configuration of Spring based on dependencies.
      • @ComponentScan: Scans the package for Spring components (like controllers and services), making them available to the application.
  4. Class and main Method:
    • Declares DiceApplication as the main class.
    • SpringApplication app = new SpringApplication(DiceApplication.class); – Initializes the application.
    • app.setBannerMode(Banner.Mode.OFF); – Disables the banner for cleaner console output.
    • app.run(args); – Starts the application, launching the embedded web server.

Create the RollController class to simulate a dice roll.

nano RollController.java
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 13

Add the following code.

package com.example;

import java.util.Optional;
import java.util.concurrent.ThreadLocalRandom;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

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

    @GetMapping("/rolldice")
    public String index(@RequestParam("player") Optional<String> player) {
        int result = this.getRandomNumber(1, 6);
        if (player.isPresent()) {
            logger.info("{} is rolling the dice: {}", player.get(), result);
        } else {
            logger.info("Anonymous player is rolling the dice: {}", result);
        }
        return Integer.toString(result);
    }

    public int getRandomNumber(int min, int max) {
        return ThreadLocalRandom.current().nextInt(min, max + 1);
    }
}
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 14

Explanation of the code:

This RollController class handles HTTP requests for rolling a dice. It provides an endpoint (/rolldice) that simulates rolling a dice and logs the result, optionally associating it with a player name.

  1. Package Declaration:
    • package com.example; – Organizes the class under the com.example package.
  2. Imports:
    • java.util.Optional, java.util.concurrent.ThreadLocalRandom: For handling optional player input and generating random dice numbers.
    • org.slf4j.Logger, org.slf4j.LoggerFactory: For logging the dice roll results.
    • org.springframework.web.bind.annotation.GetMapping, org.springframework.web.bind.annotation.RequestParam, org.springframework.web.bind.annotation.RestController: For defining the RESTful controller and handling GET requests with optional query parameters.
  3. @RestController Annotation:
    • Indicates that the class is a Spring REST controller, capable of handling HTTP requests and returning HTTP responses.
  4. Logger:
    • private static final Logger logger = LoggerFactory.getLogger(RollController.class); – Initializes a logger for the class to log dice roll information.
  5. index Method:
    • @GetMapping("/rolldice"): Maps the /rolldice URL to this method, allowing HTTP GET requests to trigger the dice roll logic.
    • @RequestParam("player") Optional<String> player: Captures the optional player query parameter from the URL (e.g., /rolldice?player=John).
    • int result = this.getRandomNumber(1, 6);: Rolls the dice by generating a random number between 1 and 6.
    • Logs the dice roll result, either associating it with a player if the name is provided or logging it as an anonymous roll.
    • Returns the dice roll result as a string.
  6. getRandomNumber Method:
    • Generates a random number between the specified min and max values using ThreadLocalRandom.current().nextInt(min, max + 1).

Step #4:Build and Run the Java Application

Navigate back to the root directory of the project.

cd ../../../../..
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 15

Build the project.

mvn package
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 16

The output JAR file will be located in the target directory.

Run the application.

java -jar ./target/helloworld-1.0-SNAPSHOT.jar
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 17

The application is now running, and you can access it at http://<EC2-Instance-IP>:8080/rolldice.

Integrate OpenTelemetry for PHP Application with Zero-Code Instrumentation 16

Step #5:Integrate OpenTelemetry Java Agent

Download the OpenTelemetry Java Agent.

curl -L -O https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 18

Set environment variables.

export JAVA_TOOL_OPTIONS="-javaagent:/home/ubuntu/java-simple/opentelemetry-javaagent.jar" \
OTEL_TRACES_EXPORTER=logging \
OTEL_METRICS_EXPORTER=logging \
OTEL_LOGS_EXPORTER=logging \
OTEL_METRIC_EXPORT_INTERVAL=15000
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 19

Run the application with OpenTelemetry.

java -jar ./target/helloworld-1.0-SNAPSHOT.jar
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 17

The application is now running, lets access it again at http://<EC2-Instance-IP>:8080/rolldice.

Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 21

When the application runs, you should see telemetry data such as traces, logs, and metrics in the console. The OpenTelemetry agent automatically instruments the application, requiring no code changes for monitoring.

Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 22
Instrumenting Java Application with Maven Using OpenTelemetry Java Agent 23

Conclusion:

In this article, we demonstrated how to instrument a Java application built with Maven using the OpenTelemetry Java Agent. Maven is a powerful tool that simplifies the process of building and managing Java projects. This setup allows seamless collection of telemetry data, offering valuable insights into java application performance. By leveraging OpenTelemetry, developers can create resilient and observable applications effortlessly.

Related Articles:

How to Build Spring Boot Project Using Gradle

Reference:

Official Opentelemetry Page

Prasad Hole

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