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

Application Real-Time Monitoring Service:OpenTelemetry SDK for Java を使用してトレースにカスタム インストルメンテーション コードを追加する

最終更新日:Apr 22, 2025

Application Real-Time Monitoring Service (ARMS) のアプリケーションモニタリングを使用して一般的な Java フレームワークでアプリケーションをモニタリングする場合、ARMS エージェントはフレームワークを自動的にインストルメントします。ビジネスコードを変更することなく、トレース情報を収集できます。トレース情報にビジネス メソッドの実行ステータスを反映させるには、OpenTelemetry SDK for Java を使用して、コードにカスタム インストルメンテーション コードを追加できます。このトピックでは、SDK を使用してアプリケーションをインストルメントし、トレース コンテキスト、カスタム baggage、および属性をキャプチャする方法について説明します。

ARMS でサポートされているコンポーネントとフレームワークについては、「ARMS でサポートされている Java コンポーネントとフレームワーク」をご参照ください。

前提条件

依存関係の追加

次の Maven 依存関係を追加して、OpenTelemetry SDK for Java を導入します。詳細については、「インストルメンテーション」をご参照ください。

<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-sdk</artifactId>
    </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>

ARMS と OpenTelemetry ベースのインストルメンテーションの互換性

用語

ここでは、一般的に使用される用語のみを紹介します。その他の名称については、「OpenTelemetry 仕様」をご参照ください。

  • Span:リモート呼び出しや内部メソッド呼び出しなど、リクエスト内の特定の操作。

  • SpanContext:traceId や spanId などの情報を含む、単一のリクエストトレースのコンテキスト。

  • Attribute:主要な情報を記録するために使用される、Span の追加の属性フィールド。

  • Baggage:トレース全体に伝搬されるキーと値のペア。

OpenTelemetry SDK for Java の使用

SDK を使用して、次の操作を実行できます。

  • インストルメンテーション コードを使用して新しい Span を作成する。

  • Span に属性を追加する。

  • トレース コンテキストで baggage 項目を伝搬する。

  • トレース コンテキストにアクセスし、traceId や spanId などの識別子を出力する。

次のサンプルコードは、SDK を使用して上記の操作を実行する方法を示しています。

重要

SDK を使用して手動で作成された OpenTelemetry インスタンスを直接使用するのではなく、GlobalOpenTelemetry.get() メソッドを呼び出して OpenTelemetry インスタンスを取得する必要があります。そうしないと、SDK インストルメンテーションによって生成された Span データは、ARMS エージェント v4.x を使用すると表示されなくなります。

@RestController
@RequestMapping("/ot")
public class OpenTelemetryController {

    private Tracer tracer;

    private ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();

    @PostConstruct
    public void init() {
	    OpenTelemetrySdk.builder()
			.setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
			.buildAndRegisterGlobal();

		tracer = GlobalOpenTelemetry.get().getTracer("manual-sdk", "1.0.0");

        ses.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                Span span = tracer.spanBuilder("schedule")
                        .setAttribute("schedule.time", System.currentTimeMillis())
                        .startSpan();
                try (Scope scope = span.makeCurrent()) {
                    System.out.println("scheduled!"); // スケジュールされました!
                    Thread.sleep(500L);
                    span.setAttribute("schedule.success", true);
                    System.out.println(Span.current().getSpanContext().getTraceId()); // トレース ID を取得します。
                } catch (Throwable t) {
                    span.setStatus(StatusCode.ERROR, t.getMessage());
                } finally {
                    span.end();
                }
            }
        }, 10, 30, TimeUnit.SECONDS);
    }

    @ResponseBody
    @RequestMapping("/parent")
    public String parent() {
        Span span = tracer.spanBuilder("parent").setSpanKind(SpanKind.SERVER).startSpan();
        try (Scope scope = span.makeCurrent()) {
            // Baggage を使用して、サービスのカスタムタグを伝搬します。
            Baggage baggage =  Baggage.current().toBuilder()
                    .put("user.id", "1")
                    .put("user.name", "name")
                    .build();
            try (Scope baggageScope = baggage.storeInContext(Context.current()).makeCurrent()) {
                child();
            }
            span.setAttribute("http.method", "GET");
            span.setAttribute("http.uri", "/parent");
        } finally {
            span.end();
        }
        return "parent";
    }

    private void child() {
        Span span = tracer.spanBuilder("child").startSpan();
        try (Scope scope = span.makeCurrent()) {
            System.out.println("current traceId = " + Span.current().getSpanContext().getTraceId()); // 現在の traceId = 
            System.out.println("userId in baggage = " + Baggage.current().getEntryValue("user.id")); // baggage 内の userId = 
            Thread.sleep(1000);
        } catch (Throwable e) {
            span.setStatus(StatusCode.ERROR, e.getMessage());
        } finally {
            span.end();
        }
    }
}

詳細:

  1. init メソッドで、OpenTelemetryController のスケジュールされたタスクが ScheduledExecutorService を使用して開始されます。スケジュールされたタスクが開始されると、Span が作成され、タスクが終了するとこの Span が閉じられます。

  2. parent メソッドの OpenTelemetryController では、OpenTelemetry SDK の複数のメソッドが呼び出されます。

    1. このメソッドが呼び出されるたびに、parent という名前の Span が作成され、メソッドが終了するとこの Span が閉じられます。

    2. また、Baggage SDK を呼び出して、user.iduser.name という名前の2 つの Baggage ペアを追加します。これらの2 つの Baggage は、ダウンストリーム アプリケーションに伝搬されます。

    3. 手順 2.a で作成された Span に 2 つの属性が追加されます。

  3. child メソッドの OpenTelemetryController では、次の操作が実行されます。

    1. このメソッドが呼び出されるたびに、child という名前の Span が作成され、メソッドが終了するとこの Span が閉じられます。この Span は、手順 2.a で作成された Span の子であることに注意してください。

    2. メソッドはトレース コンテキストを取得し、traceId を出力します。

    3. 手順 2.b で追加された baggage 項目 (user.id と user.name) も取得して出力します。

エージェントバージョンの比較

次の表に示すように、ARMS エージェントのバージョンによって、上記の手順に対するサポートが異なります。

手順

ARMS エージェント v4.x 以降

ARMS エージェント v3.x 以前

1

サポートされています。新しい Span が生成されます。

サポートされています。新しい Span が生成されます。

2.1

サポートされています

サポートされています

2.2

サポートされています

サポートされていません

2.3

サポートされています

サポートされています

3.1

サポートされています

サポートされています。手順 2.a で作成された Span のメソッドスタックとして、この span が使用されます。

3.2

サポートされています。出力される traceId は、エージェントによって提供されるものと同じです。

サポートされていません。出力される traceId は、エージェントによって提供されるものとは異なります。

3.2

サポートされています

サポートされています

インストルメンテーションの効果

ARMS エージェント v4.x 以降

  • 手順 1:

    OpenTelemetry SDK を介して生成された Span は正常に表示できます。

    image

  • 手順 2 と手順 3:

    OpenTelemetry SDK によって生成された Span (赤いボックスで示されている) と Tomcat のインストルメンテーションによって生成された Span (黄色のボックスで示されている) は、同じトレースの一部です。OpenTelemetry SDK によって生成された Span に関連付けられた属性は正常に設定されています (青いボックスで示されている)。

    image.png

ARMS エージェント v3.x 以降

  • 手順 1:

    2024-12-16_15-41-45

  • 手順 2 と手順 3:

    OpenTelemetry SDK によって生成されたスパン(赤枠内)と Tomcat のイベントトラッキングによって生成されたスパン(黄枠内)は、同じトレースの一部です。これらのうち、child という名前のスパンは、parent という名前のスパン内のメソッドスタックとして存在します。さらに、OpenTelemetry SDK によって生成されたスパンに関連付けられた属性が正常に設定されています(青枠内)。

    image

    image

関連手順

トレース ID をアプリケーション ビジネスログに関連付けることで、エラーをすばやく特定、分析、および解決するためにアクセスできます。