アプリケーションリアルタイム監視サービス(ARMS)のアプリケーションモニタリング サブサービスを統合して、一般的な Java フレームワークを使用するアプリケーションを監視すると、ARMS エージェントはフレームワークを自動的にインストルメントします。このようにして、コードを変更することなくトレースが収集されます。ただし、クロスプロセスコンテキストを渡す場合は、OpenTelemetry SDK for Java をインストールできます。
ARMS エージェントでサポートされているコンポーネントとフレームワークについては、ARMS でサポートされている Java コンポーネントとフレームワークをご参照ください。
シナリオ
クロスプロセス通信に独自のプロトコルを使用する場合、クライアントとサーバーはトレース内で接続されない場合があります。このような場合、トレース ID、スパン ID、サンプルフラグ、 baggage を含むトレースコンテキストをクライアント側で手動で取得し、コンテキストをサーバー側に渡す必要があります。
前提条件
ARMS のアプリケーションモニタリングが統合されていること。詳細については、アプリケーションモニタリングの概要をご参照ください。
ARMS エージェントが V4.x 以降であること。ARMS エージェントの更新方法については、ARMS エージェントの更新をご参照ください。
依存関係の追加
次の 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>クロスプロセスコンテキストを渡す
次のコードでは、CustomRpcCallMessage は独自のプロトコルでのクロスプロセス通信に使用されるエンティティを示し、headerMap を使用してコンテキストを渡します。 headerMap がない場合は、コードを手動で変更して headerMap フィールドを追加します。
class CustomRpcCallMessage {
private Map<String, String> headerMap;
//その他のフィールドは省略します。
public String getHeader(String key) {
return headerMap.get(key);
}
public void setHeader(String key, String value) {
this.headerMap.put(key, value);
}
public Map<String, String> getHeaderMap() {
return headerMap;
}
}
public class CrossProcessPropagateDemo {
public static void clientSide(String[] args) {
CustomRpcCallMessage rpcCall = new CustomRpcCallMessage();
TextMapSetter<CustomRpcCallMessage> setter = new TextMapSetter<CustomRpcCallMessage>() {
@Override
public void set(CustomRpcCallMessage carrier, String key, String value) {
carrier.setHeader(key, value);
}
};
W3CTraceContextPropagator.getInstance().inject(Context.current(), rpcCall, setter);
W3CBaggagePropagator.getInstance().inject(Context.current(), rpcCall, setter);
}
private static void serverSide() {
//サーバーからリクエストを受信します。
CustomRpcCallMessage rpcCall ;
TextMapGetter<CustomRpcCallMessage> getter = new TextMapGetter<CustomRpcCallMessage>() {
@Override
public Iterable<String> keys(CustomRpcCallMessage carrier) {
return carrier.getHeaderMap().keySet();
}
@Override
public String get(CustomRpcCallMessage carrier, String key) {
return carrier.getHeader(key);
}
};
Context context = W3CTraceContextPropagator.getInstance().extract(Context.current(), rpcCall, getter);
context = W3CBaggagePropagator.getInstance().extract(context, rpcCall, getter);
try (Scope scope = context.makeCurrent()) {
//サーバーの処理ロジックは省略します。
}
}
}
実際のビジネスシナリオでは、上記のコードスニペットの setter 変数と getter 変数の実装クラスのみを変更する必要があります。これにより、set メソッドと get メソッドが意図した意味を伝えることが保証されます。
関連手順
トレース ID をアプリケーションログに関連付けて、エラーを迅速に特定、分析、および解決できます。詳細については、Java アプリケーションのログにトレース ID を関連付けるをご参照ください。