すべてのプロダクト
Search
ドキュメントセンター

Managed Service for OpenTelemetry:OpenTelemetry を使用して Java アプリケーションのトレースデータを送信する

最終更新日:Dec 30, 2024

OpenTelemetry を使用してアプリケーションをインストルメントし、トレースデータを Managed Service for OpenTelemetry に送信すると、Managed Service for OpenTelemetry はアプリケーションの監視を開始します。アプリケーショントポロジー、トレース、異常トランザクション、低速トランザクション、SQL 分析など、アプリケーションの監視データを表示できます。このトピックでは、エージェントまたは OpenTelemetry SDK for Java を使用して Java アプリケーションを自動または手動でインストルメントし、Java アプリケーションのトレースデータを送信する方法について説明します。

背景情報

OpenTelemetry Java エージェント が自動的にインストルメントできる Java フレームワークを次の表に示します。詳細については、サポートされているライブラリ、フレームワーク、アプリケーションサーバー、および JVM を参照してください。

サポートされている Java フレームワーク

フレームワーク

フレームワークバージョン

Akka Actors

2.5 以降

Akka HTTP

10.0 以降

Apache Axis2

1.6 以降

Apache Camel

2.20 以降 (3.x を除く)

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 を除く)

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 および 2.2 以降

Azure Core

1.14 以降

Cassandra Driver

3.0 以降

Couchbase Client

2.0 以降および 3.1 以降

c3p0

0.9.2 以降

Dropwizard Metrics

4.0 以降 (デフォルトでは無効)

Dropwizard Views

0.7 以降

Eclipse Grizzly

2.3 以降

Eclipse Jersey

2.0 以降 (3.x を除く)

Eclipse Jetty HTTP Client

9.2 以降 (10 以降を除く)

Eclipse Metro

2.2 以降

Eclipse Mojarra

1.2 以降 (3.x を除く)

Elasticsearch API Client

7.16 以降および 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 以降 (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 以降を除く)

Spring Cloud Gateway

2.0 以降

Spring Data

1.8 以降

Spring Integration

4.1 以降 (6.0 以降を除く)

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 を除く)

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 以降

サンプルコード

java-opentelemetry-demo からサンプルコードをダウンロードします。

方法 1:OpenTelemetry Java エージェントを使用してアプリケーションを自動的にインストルメントする

OpenTelemetry Java エージェント を使用すると、非侵入的な方法で OpenTelemetry を Managed Service for OpenTelemetry に接続できます。OpenTelemetry Java エージェントを使用すると、数百の Java フレームワークのトレースデータを自動的にアップロードできます。サポートされている Java フレームワークの詳細については、サポートされているライブラリ、フレームワーク、アプリケーションサーバー、および JVM を参照してください。

  1. OpenTelemetry Java エージェント をダウンロードします。

  2. トレースデータを送信するために、Java 起動設定の JVM パラメータを変更します。

    トレースデータを直接送信する場合は、<token><endpoint> を前提条件で取得した情報に置き換えます。

    説明

    HTTP メソッドではトークンを設定する必要はありません。エンドポイントのみを設定する必要があります。

    gRPC

    java -javaagent:/path/to/opentelemetry-javaagent.jar \   // ファイルのダウンロードアドレスへのパスを変更します。
    -Dotel.exporter.otlp.protocol=grpc \
    -Dotel.exporter.otlp.headers=Authentication=<token> \   // 前提条件で取得したトークンを指定します。
    -Dotel.exporter.otlp.endpoint=<endpoint> \   // 前提条件で取得したエンドポイントを指定します。
    -Dotel.logs.exporter=none \
    -jar /path/to/your/app.jar

    例:

    java -javaagent:/path/to/opentelemetry-javaagent.jar \
    -Dotel.exporter.otlp.protocol=grpc \
    -Dotel.exporter.otlp.headers=Authentication=ggxw4l****@7323a5caae3****_ggxw4l****@53df7ad2afe**** \
    -Dotel.exporter.otlp.endpoint=http://tracing-analysis-dc-hz-internal.aliyuncs.com:8090 \
    -Dotel.logs.exporter=none \
    -jar /path/to/your/app.jar
    説明

    OpenTelemetry Collector を使用してトレースデータを転送する場合は、-Dotel.exporter.otlp.headers=Authentication=<token> を削除し、<endpoint> をオンプレミスにデプロイされているサービスの URL に置き換えます。

方法 2:OpenTelemetry SDK for Java を使用してアプリケーションを手動でインストルメントする

OpenTelemetry Java エージェントは、OpenTelemetry SDK for Java に基づいて実装されています。SDK はさまざまなカスタム機能を提供します。OpenTelemetry Java エージェントを使用して追加されたインストルメンテーションがビジネス要件を満たさなくなった場合、またはビジネス要件に基づいてカスタムインストルメンテーションを追加する場合は、次の手順を実行します。

  1. Maven プロジェクトの pom.xml ファイルに次の依存関係を追加します。

    <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.23.0-alpha</version>
      </dependency>
    </dependencies>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.opentelemetry</groupId>
                <artifactId>opentelemetry-bom</artifactId>
                <version>1.23.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
  2. OpenTelemetry トレーサーを取得します。

    • 次のコードでは、<logical-service-name> はサービスの名前を指定し、<host-name> はホスト名を指定します。ビジネス要件に基づいて値を指定します。

    • トレースデータを直接送信する場合は、<token> を前提条件で取得したトークンに置き換え、<endpoint> をトレースデータを送信するリージョンのエンドポイントに置き換えます。

    package com.alibaba.arms.brightroar.console.util;
    
    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.trace.OtlpGrpcSpanExporter;
    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 {
            // OpenTelemetry トレーサーを取得します。
            Resource resource = Resource.getDefault()
                    .merge(Resource.create(Attributes.of(
                            ResourceAttributes.SERVICE_NAME, "<logical-service-name>",
                            ResourceAttributes.HOST_NAME, "<host-name>"
                    )));
    
            SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
                    .addSpanProcessor(BatchSpanProcessor.builder(OtlpGrpcSpanExporter.builder()
                            .setEndpoint("<endpoint>")
                            .addHeader("Authentication", "<token>")
                            .build()).build())
                    .setResource(resource)
                    .build();
    
            OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
                    .setTracerProvider(sdkTracerProvider)
                    .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
                    .buildAndRegisterGlobal();
    
            tracer = openTelemetry.getTracer("<your_tracer_name>", "1.0.0");
        }
    
        private static Tracer tracer;
    
        public static Tracer getTracer() {
            return tracer;
        }
    
    }
  3. コントローラーコードとサービスコードを変更します。

    • コントローラーコードのサンプル:

      package com.alibaba.arms.brightroar.console.controller;
      
      import com.alibaba.arms.brightroar.console.service.UserService;
      import com.alibaba.arms.brightroar.console.util.OpenTelemetrySupport;
      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 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;
      
      /**
       * 参考文献:
       * 1. https://opentelemetry.io/docs/java/manual_instrumentation/
       */
      @RestController
      @RequestMapping("/user")
      public class UserController {
      
          @Autowired
          private UserService userService;
      
          private ExecutorService es = Executors.newFixedThreadPool(5);
      
          private void biz() {
              Tracer tracer = OpenTelemetrySupport.getTracer();
              Span span = tracer.spanBuilder("biz (manual)")
                      .setParent(Context.current().with(Span.current())) // オプション。システムは設定を自動的に構成します。
                      .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); // 非同期ジョブ
                          } catch (Throwable e) {
                          }
                          asyncSpan.end();
                      }
                  });
      
                  Thread.sleep(1000); // ビジネスロジックのシミュレーション
                  System.out.println("biz done");
                  OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
                  openTelemetry.getPropagators();
              } catch (Throwable t) {
                  span.setStatus(StatusCode.ERROR, "handle biz error");
              } finally {
                  span.end();
              }
          }
      
          private void child(String userType) {
              Span span = OpenTelemetrySupport.getTracer().spanBuilder("child span").startSpan();
              try (Scope scope = span.makeCurrent()) {
                  span.setAttribute("user.type", userType);
                  System.out.println(userType);
                  biz();
              } catch (Throwable t) {
                  span.setStatus(StatusCode.ERROR, "handle child span error");
              } finally {
                  span.end();
              }
          }
      
          @RequestMapping("/async")
          public String async() {
              System.out.println("UserController.async -- " + Thread.currentThread().getId());
              Span span = OpenTelemetrySupport.getTracer().spanBuilder("parent span").startSpan();
              span.setAttribute("user.id", "123456");
              try (Scope scope = span.makeCurrent()) {
                  userService.async();
                  child("vip");
              } catch (Throwable t) {
                  span.setStatus(StatusCode.ERROR, "handle parent span error");
              } finally {
                  span.end();
              }
              return "async";
          }
      
      }
         
    • サービスコードのサンプル:

      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 -- ");
          }
      }
  4. アプリケーションを起動します。

    Managed Service for OpenTelemetry コンソールアプリケーションページで、アプリケーションの名前をクリックします。表示されるページで、トレースデータを表示します。

方法 3:OpenTelemetry Java エージェントと OpenTelemetry SDK for Java を使用してアプリケーションをインストルメントする

OpenTelemetry Java エージェントを使用して自動インストルメンテーションを実行し、OpenTelemetry SDK for Java を使用してビジネス要件に基づいてカスタムインストルメンテーションを追加できます。

  1. OpenTelemetry Java エージェント をダウンロードします。

  2. 方法 2 の依存関係に加えて、Maven プロジェクトの pom.xml ファイルに次の依存関係を追加します。

    <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>
    説明

    上記のコードでは、opentelemetry-sdk-extension-autoconfigure 依存関係は、OpenTelemetry SDK for Java を自動的に構成し、OpenTelemetry Java エージェントの設定を SDK に転送するために使用されます。

    Maven プロジェクトの pom.xml ファイルの依存関係を表示する

    <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.23.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.23.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
  3. OpenTelemetry トレーサーを取得します。

    OpenTelemetry Java エージェントと OpenTelemetry SDK for Java を使用してアプリケーションをインストルメントする場合、方法 2 で使用した OpenTelemetrySupport クラスを使用して OpenTelemetry トレーサーを取得する必要はありません。

    OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
    Tracer tracer = openTelemetry.getTracer("instrumentation-library-name", "1.0.0");
  4. コントローラーコードとサービスコードを変更します。

    • 次のサンプルコントローラーコードでは、方法 1 と方法 2 を使用することをお勧めします。

      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;
      
      /**
      * 参考文献:
      * 1. https://opentelemetry.io/docs/java/manual_instrumentation/
      */
      @RestController
          @RequestMapping("/user")
          public class UserController {
      
              @Autowired
              private UserService userService;
      
              private ExecutorService es = Executors.newFixedThreadPool(5);
      
              // 方法 1:アプリケーションで自動インストルメンテーションを実行します。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";
              }
      
              // 方法 2:タグに基づいてアプリケーションをインストルメントします。
              @WithSpan
              private void child(@SpanAttribute("user.type") String userType) {
                  System.out.println(userType);
                  biz();
              }
      
              // 方法 3:トレーサーを使用してアプリケーションを手動でインストルメントします。
              private void biz() {
                  Tracer tracer = GlobalOpenTelemetry.get().getTracer("tracer");
                  Span span = tracer.spanBuilder("biz (manual)")
                      .setParent(Context.current().with(Span.current())) // オプション。システムは設定を自動的に構成します。
                      .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); // 非同期ジョブ
                              } catch (Throwable e) {
                              }
                              asyncSpan.end();
                          }
                      });
      
                      Thread.sleep(1000); // ビジネスロジックのシミュレーション
                      System.out.println("biz done");
                      OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
                      openTelemetry.getPropagators();
                  } catch (Throwable t) {
                      span.setStatus(StatusCode.ERROR, "handle biz error");
                  } finally {
                      span.end();
                  }
              }
      
          }
      
                                      
    • サービスコードのサンプル:

      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. トレースデータを送信するために、Java 起動設定の JVM パラメータを変更します。

    -javaagent:/path/to/opentelemetry-javaagent.jar    // パスを OpenTelemetry Java エージェントのダウンロード URL に置き換えます。
    -Dotel.resource.attributes=service.name=<appName>     // <appName> を実際のアプリケーション名に置き換えます。
    -Dotel.exporter.otlp.headers=Authentication=<token>
    -Dotel.exporter.otlp.endpoint=<endpoint>
    • トレースデータを直接送信する場合は、<token> を前提条件で取得したトークンに置き換え、<endpoint> をトレースデータを送信するリージョンのエンドポイントに置き換えます。

      例:

      -javaagent:/Users/carpela/Downloads/opentelemetry-javaagent.jar
      -Dotel.resource.attributes=service.name=ot-java-agent-sample
      -Dotel.exporter.otlp.headers=Authentication=b590xxxxuqs@3a75d95xxxxx9b_b59xxxxguqs@53dxxxx2afe8301
      -Dotel.exporter.otlp.endpoint=http://tracing-analysis-dc-bj:8090
    • OpenTelemetry Collector を使用してトレースデータを転送する場合は、-Dotel.exporter.otlp.headers=Authentication=<token> を削除し、<endpoint> をオンプレミスにデプロイされているサービスの URL に置き換えます。

  6. アプリケーションを起動します。

    Managed Service for OpenTelemetry コンソールアプリケーションページで、アプリケーションの名前をクリックします。表示されるページで、トレースデータを表示します。