All Products
Search
Document Center

Cloud Monitor:Report Java application data using OpenTelemetry

Last Updated:Dec 04, 2025

After you instrument an application with OpenTelemetry and report its trace data to Cloud Monitor 2.0, Cloud Monitor 2.0 begins monitoring the application. You can view various monitoring data, such as application topology, call traces, abnormal transactions, slow transactions, and SQL analysis. This topic describes how to use the OpenTelemetry Java Agent or software development kit (SDK) for automatic or manual instrumentation and data reporting.

Background information

The OpenTelemetry Java Agent supports automatic instrumentation for many Java frameworks. For a complete list, see Supported Libraries and Versions.

Expand to view supported Java frameworks

Framework

Framework version requirements

Akka Actors

2.5+

Akka HTTP

10.0+

Apache Axis2

1.6+

Apache Camel

2.20+ (3.x is not supported)

Apache DBCP

2.0+

Apache CXF JAX-RS

3.2+

Apache CXF JAX-WS

3.0+

Apache Dubbo

2.7+

Apache HttpAsyncClient

4.1+

Apache HttpClient

2.0+

Apache Kafka Producer/Consumer API

0.11+

Apache Kafka Streams API

0.11+

Apache MyFaces

1.2+ (3.x is not supported)

Apache Pulsar

2.8+

Apache RocketMQ gRPC/Protobuf-based Client

5.0+

Apache RocketMQ Remoting-based Client

4.8+

Apache Struts 2

2.3+

Apache Tapestry

5.4+

Apache Wicket

8.0+

Armeria

1.3+

AsyncHttpClient

1.9+

AWS Lambda

1.0+

AWS SDK

1.11.x and 2.2+

Azure Core

1.14+

Cassandra Driver

3.0+

Couchbase Client

2.0+ and 3.1+

c3p0

0.9.2+

Dropwizard Metrics

4.0+ (disabled by default)

Dropwizard Views

0.7+

Eclipse Grizzly

2.3+

Eclipse Jersey

2.0+ (3.x is not supported)

Eclipse Jetty HTTP Client

9.2+ (10+ is not supported)

Eclipse Metro

2.2+

Eclipse Mojarra

1.2+ (3.x is not supported)

Elasticsearch API Client

7.16+ and 8.0+

Elasticsearch REST Client

5.0+

Elasticsearch Transport Client

5.0+

Finatra

2.9+

Geode Client

1.4+

Google HTTP Client

1.19+

Grails

3.0+

GraphQL Java

12.0+

gRPC

1.6+

Guava ListenableFuture

10.0+

GWT

2.0+

Hibernate

3.3+

Hibernate Reactive

1.0+

HikariCP

3.0+

HttpURLConnection

Java 8+

Hystrix

1.4+

Java Executors

Java 8+

Java Http Client

Java 11+

java.util.logging

Java 8+

Java Platform

Java 8+

JAX-RS

0.5+

JAX-RS Client

1.1+

JAX-WS

2.0+ (excluding 3.x)

JBoss Log Manager

1.1+

JDBC

Java 8+

Jedis

1.4+

JMS

1.1+

Jodd Http

4.2+

JSP

2.3+

Kotlin Coroutines

1.0+

Ktor

1.0+

Kubernetes Client

7.0+

Lettuce

4.0+

Log4j 1

1.2+

Log4j 2

2.11+

Logback

1.0+

Micrometer

1.5+

MongoDB Driver

3.1+

Netty

3.8+

OkHttp

2.2+

Oracle UCP

11.2+

OSHI

5.3.1+

Play

2.4+

Play WS

1.0+

Quartz

2.0+

R2DBC

1.0+

RabbitMQ Client

2.7+

Ratpack

1.4+

Reactor

3.1+

Reactor Netty

0.9+

Rediscala

1.8+

Redisson

3.0+

RESTEasy

3.0+

Restlet

1.0+

RMI

Java 8+

RxJava

1.0+

Scala ForkJoinPool

2.8+

Servlet

2.2+

Spark Web Framework

2.3+

Spring Boot

-

Spring Batch

3.0+ (5.0+ is not supported)

Spring Cloud Gateway

2.0+

Spring Data

1.8+

Spring Integration

4.1+ (6.0+ is not supported)

Spring JMS

2.0+

Spring Kafka

2.7+

Spring RabbitMQ

1.0+

Spring Scheduling

3.1+

Spring RestTemplate

3.1+

Spring Web MVC

3.1+

Spring Web Services

2.0+

Spring WebFlux

5.3+

Spymemcached

2.12+

Tomcat JDBC Pool

8.5+

Twilio

6.6+ (8.x is not supported)

Undertow

1.4+

Vaadin

14.2+

Vert.x Web

3.0+

Vert.x HttpClient

3.0+

Vert.x Kafka Client

3.6+

Vert.x RxJava2

3.5+

Vert.x SQL Client

4.0+

Vibur DBCP

11.0+

ZIO

2.0+

Step 1: Obtain endpoint information

  1. Log on to the Cloud Monitor 2.0 console, and select a workspace. In the left navigation pane, click Integration Center.

  2. In the APM & Tracing section, click the Java card. Then, set Operating environment type to Manual Installation and Select Java Protocol to Opentelemetry.

  3. In the Parameter Configurations section, click Click to get next to LicenseKey. Then, select the Instrumentation Type, Connection Type, and Export Protocol as needed. Enter the Service Name, Version, and Environment.

    The corresponding integration code is generated at the bottom of the page based on the configured parameters. The code contains endpoint information such as the Endpoint and LicenseKey.

    image

Step 2: Set up dependency libraries

Automatic instrumentation (recommended)

The OpenTelemetry Java Agent provides a non-intrusive integration method. It supports automatic trace data reporting for hundreds of Java frameworks. For a complete list of supported Java frameworks, see Supported Libraries and Versions.

  1. Download the Java Agent. The latest version is recommended.

  2. Report trace data by modifying the VM parameters for Java startup.

    The following code runs your application and loads the OpenTelemetry Java Agent. Replace the placeholders in the following code with the endpoint information that you obtained in Step 1. Replace /path/to/opentelemetry-javaagent.jar and /path/to/your/app.jar with the actual paths to the Java Agent and your JAR package.

    java -javaagent:/path/to/opentelemetry-javaagent.jar \
    -Dotel.resource.attributes=service.name=<service name>,acs.cms.workspace=<workspace>,service.version=<service version>,deployment.environment=<environment> \
    -Dotel.exporter.otlp.protocol=http/protobuf \
    -Dotel.exporter.otlp.traces.endpoint=<traces.endpoint> \
    -Dotel.exporter.otlp.metrics.endpoint=<metrics.endpoint> \
    -Dotel.exporter.otlp.headers="x-arms-license-key=<license-key>,x-arms-project=<arms-project>,x-cms-workspace=<workspace>" \
    -Dotel.logs.exporter=none \
    -jar /path/to/your/app.jar
    Note

    To generate test data, access your service. If you are using a test JAR package, you can access port 8087 on your local machine to generate test data.

  3. Run the program to generate and report trace data.

Manual instrumentation

The OpenTelemetry Java SDK is the foundation for the OpenTelemetry Java Agent and provides extensive customization capabilities. Use this method if the automatic instrumentation provided by the OpenTelemetry Java Agent does not meet your needs, or if you want to add custom business instrumentation.

  1. Import the Maven POM dependencies.

    <dependencies>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-api</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-sdk-trace</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-exporter-otlp</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-sdk</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-semconv</artifactId>
            <version>1.30.0-alpha</version>
        </dependency>
    </dependencies>
    
    <dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-bom</artifactId>
            <version>1.30.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
    </dependencyManagement>
  2. Obtain the OpenTelemetry Tracer.

    import io.opentelemetry.api.OpenTelemetry;
    import io.opentelemetry.api.common.Attributes;
    import io.opentelemetry.api.trace.Tracer;
    import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
    import io.opentelemetry.context.propagation.ContextPropagators;
    import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
    import io.opentelemetry.sdk.OpenTelemetrySdk;
    import io.opentelemetry.sdk.resources.Resource;
    import io.opentelemetry.sdk.trace.SdkTracerProvider;
    import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
    import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
    
    public class OpenTelemetrySupport {
    
        static {
            // Obtain the OpenTelemetry Tracer.
            Resource resource = Resource.getDefault()
                    .merge(Resource.create(Attributes.of(
                            ResourceAttributes.SERVICE_NAME, "<service name>",  // Application name.
                            ResourceAttributes.SERVICE_VERSION, "<service version>",  // Version number.
                            ResourceAttributes.DEPLOYMENT_ENVIRONMENT, "<environment>", // Deployment environment.
                            ResourceAttributes.HOST_NAME, "${host-name}", // Replace ${host-name} with your hostname.
                            AttributeKey.stringKey("acs.cms.workspace"), "<workspace>"  // Replace <workspace> with your workspace name.
                    )));
            
            SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
                    .addSpanProcessor(BatchSpanProcessor.builder(OtlpHttpSpanExporter.builder()
                            .setEndpoint("<endpoint>")  // Replace <endpoint> with the endpoint information obtained in Step 1.
                            .addHeader("x-arms-license-key", "<license-key>")  // Replace <license-key> with the information obtained in Step 1.
                            .addHeader("x-arms-project", "<arms-project>")  // Replace <arms-project> with the information obtained in Step 1.
                            .addHeader("x-cms-workspace", "<workspace>") // Replace <workspace> with your workspace name.
                            .build()).build())
                    .setResource(resource)
                    .build();
            
            OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
                    .setTracerProvider(sdkTracerProvider)
                    .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
                    .buildAndRegisterGlobal();
    
            tracer = openTelemetry.getTracer("OpenTelemetry Tracer", "1.0.0");
        }
    
        private static Tracer tracer;
    
        public static Tracer getTracer() {
            return tracer;
        }
    }
  3. Create a Span.

    import io.opentelemetry.api.trace.Span;
    import io.opentelemetry.api.trace.StatusCode;
    import io.opentelemetry.context.Scope;
    
    public class Main {
        
        public static void parentMethod() {
            Span span = OpenTelemetrySupport.getTracer().spanBuilder("parent span").startSpan();
            try (Scope scope = span.makeCurrent()) {
                span.setAttribute("good", "job");
                childMethod();
            } catch (Throwable t) {
                span.setStatus(StatusCode.ERROR, "handle parent span error");
            } finally {
                span.end();
            }
        }
    
        public static void childMethod() {
            Span span = OpenTelemetrySupport.getTracer().spanBuilder("child span").startSpan();
            try (Scope scope = span.makeCurrent()) {
                span.setAttribute("hello", "world");
            } catch (Throwable t) {
                span.setStatus(StatusCode.ERROR, "handle child span error");
            } finally {
                span.end();
            }
        }
    
        public static void main(String[] args) {
            parentMethod();
        }
    }
  4. Run the program to generate and report trace data.

Automatic and manual instrumentation

You can use the Java Agent for automatic instrumentation and simultaneously use the Java SDK to add custom business instrumentation.

  1. Download the Java Agent. The latest version is recommended.

  2. Add the following dependencies to the Maven dependencies for manual instrumentation.

    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-extension-annotations</artifactId>
    </dependency>
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId>
        <version>1.23.0-alpha</version>
    </dependency>
    Note

    The opentelemetry-sdk-extension-autoconfigure dependency automatically configures the SDK and passes the Java Agent configuration to the Java SDK.

    Expand to view the complete Maven POM dependencies

    <dependencies>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-api</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-sdk-trace</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-extension-annotations</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-exporter-otlp</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-sdk</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-semconv</artifactId>
            <version>1.30.0-alpha</version>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId>
            <version>1.23.0-alpha</version>
        </dependency>
    </dependencies>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.opentelemetry</groupId>
                <artifactId>opentelemetry-bom</artifactId>
                <version>1.30.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
  3. Obtain the OpenTelemetry Tracer.

    When you use both the Java Agent and the Java SDK for instrumentation, you do not need to use the OpenTelemetrySupport class from the manual instrumentation section to obtain the Tracer.

    OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
    Tracer tracer = openTelemetry.getTracer("instrumentation-library-name", "1.0.0");
  4. Modify the Controller and Service code as follows.

    • The following is the Controller code. The first and second methods shown in the code are recommended.

      package com.alibaba.arms.brightroar.console.controller;
      
      import com.alibaba.arms.brightroar.console.service.UserService;
      import io.opentelemetry.api.GlobalOpenTelemetry;
      import io.opentelemetry.api.OpenTelemetry;
      import io.opentelemetry.api.trace.Span;
      import io.opentelemetry.api.trace.StatusCode;
      import io.opentelemetry.api.trace.Tracer;
      import io.opentelemetry.context.Context;
      import io.opentelemetry.context.Scope;
      import io.opentelemetry.extension.annotations.SpanAttribute;
      import io.opentelemetry.extension.annotations.WithSpan;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;
      
      /**
      * References:
      * 1. https://opentelemetry.io/docs/java/manual_instrumentation/
      */
      @RestController
          @RequestMapping("/user")
          public class UserController {
      
              @Autowired
              private UserService userService;
      
              private ExecutorService es = Executors.newFixedThreadPool(5);
      
              // Method 1: Automatic instrumentation with manually added information using the API.
              @RequestMapping("/async")
              public String async() {
                  System.out.println("UserController.async -- " + Thread.currentThread().getId());
                  Span span = Span.current();
                  span.setAttribute("user.id", "123456");
                  userService.async();
                  child("vip");
                  return "async";
              }
      
              // Method 2: Create instrumentation using annotations.
              @WithSpan
              private void child(@SpanAttribute("user.type") String userType) {
                  System.out.println(userType);
                  biz();
              }
      
              // Method 3: Obtain a Tracer for purely manual instrumentation.
              private void biz() {
                  Tracer tracer = GlobalOpenTelemetry.get().getTracer("tracer");
                  Span span = tracer.spanBuilder("biz (manual)")
                      .setParent(Context.current().with(Span.current())) // Optional. Automatically set.
                      .startSpan();
      
                  try (Scope scope = span.makeCurrent()) {
                      span.setAttribute("biz-id", "111");
      
                      es.submit(new Runnable() {
                          @Override
                          public void run() {
                              Span asyncSpan = tracer.spanBuilder("async")
                                  .setParent(Context.current().with(span))
                                  .startSpan();
                              try {
                                  Thread.sleep(1000L); // some async jobs
                              } catch (Throwable e) {
                              }
                              asyncSpan.end();
                          }
                      });
      
                      Thread.sleep(1000); // fake biz logic
                      System.out.println("biz done");
                      OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
                      openTelemetry.getPropagators();
                  } catch (Throwable t) {
                      span.setStatus(StatusCode.ERROR, "handle biz error");
                  } finally {
                      span.end();
                  }
              }
      
          }
      
                                      
    • Service code:

      package com.alibaba.arms.brightroar.console.service;
      
      import org.springframework.scheduling.annotation.Async;
      import org.springframework.stereotype.Service;
      
      @Service
      public class UserService {
      
          @Async
          public void async() {
              System.out.println("UserService.async -- " + Thread.currentThread().getId());
              System.out.println("my name is async");
              System.out.println("UserService.async -- ");
          }
      }
  5. Report trace data by modifying the VM parameters for Java startup.

    Replace the placeholders in the following code with the endpoint information that you obtained in Step 1. Replace /path/to/opentelemetry-javaagent.jar and /path/to/your/app.jar with the actual paths to the Java Agent and your JAR package.

    java -javaagent:/path/to/opentelemetry-javaagent.jar \
    -Dotel.resource.attributes=service.name=<service name>,acs.cms.workspace=<workspace>,service.version=<service version>,deployment.environment=<environment> \
    -Dotel.exporter.otlp.protocol=http/protobuf \
    -Dotel.exporter.otlp.traces.endpoint=<traces.endpoint> \
    -Dotel.exporter.otlp.metrics.endpoint=<metrics.endpoint> \
    -Dotel.exporter.otlp.headers="x-arms-license-key=<license-key>,x-arms-project=<arms-project>,x-cms-workspace=<workspace>" \
    -Dotel.logs.exporter=none \
    -jar /path/to/your/app.jar
  6. Run the program to generate and report trace data.

View monitoring data

  1. Log on to the Cloud Monitor 2.0 console, and select a workspace. In the left navigation pane, choose Application Center > Application Observability > Application Insights.

  2. On the Application List page, click the name of the application to view its monitoring details. For more information, see Application Monitoring.