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.
Step 1: Obtain endpoint information
Log on to the Cloud Monitor 2.0 console, and select a workspace. In the left navigation pane, click Integration Center.
In the APM & Tracing section, click the Java card. Then, set Operating environment type to Manual Installation and Select Java Protocol to Opentelemetry.
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.

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.
Download the Java Agent. The latest version is recommended.
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.jarand/path/to/your/app.jarwith 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.jarNoteTo 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.
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.
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>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; } }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(); } }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.
Download the Java Agent. The latest version is recommended.
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>NoteThe
opentelemetry-sdk-extension-autoconfiguredependency automatically configures the SDK and passes the Java Agent configuration to the Java SDK.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");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 -- "); } }
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.jarand/path/to/your/app.jarwith 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.jarRun the program to generate and report trace data.
View monitoring data
Log on to the Cloud Monitor 2.0 console, and select a workspace. In the left navigation pane, choose .
On the Application List page, click the name of the application to view its monitoring details. For more information, see Application Monitoring.