OpenTelemetryの使用
このガイドでは、Quarkusアプリケーションで OpenTelemetry (OTel)を利用して、インタラクティブなWebアプリケーションに分散トレースを提供する方法について説明します。
|
前提条件
このガイドを完成させるには、以下が必要です:
-
約15分
-
IDE
-
JDK 17+がインストールされ、
JAVA_HOMEが適切に設定されていること -
Apache Maven 3.9.6
-
Docker と Docker Compose、または Podman 、および Docker Compose
-
使用したい場合は、 Quarkus CLI
-
ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること
ソリューション
次の章で紹介する手順に沿って、ステップを踏んでアプリを作成することをお勧めします。ただし、すぐに完成した例に飛んでも構いません。
Gitレポジトリをクローンするか git clone -b 3.8 https://github.com/quarkusio/quarkus-quickstarts.git 、 アーカイブ をダウンロードします。
ソリューションは opentelemetry-quickstart ディレクトリ にあります。
Mavenプロジェクトの作成
まず、新しいプロジェクトが必要です。以下のコマンドで新規プロジェクトを作成します。
Windowsユーザーの場合:
-
cmdを使用する場合、(バックスラッシュ
\を使用せず、すべてを同じ行に書かないでください)。 -
Powershellを使用する場合は、
-Dパラメータを二重引用符で囲んでください。例:"-DprojectArtifactId=opentelemetry-quickstart"
このコマンドはMavenプロジェクトを生成し、 quarkus-opentelemetry エクステンションをインポートします。このエクステンションには、デフォルトのOpenTelemetryサポートと、 OTLPのgRPC spanエクスポーターが含まれています。
Quarkusプロジェクトがすでに設定されている場合、プロジェクトのベースディレクトリで次のコマンドを実行することで、 quarkus-opentelemetry エクステンションをプロジェクトに追加できます:
quarkus extension add opentelemetry
./mvnw quarkus:add-extension -Dextensions='opentelemetry'
./gradlew addExtension --extensions='opentelemetry'
これにより、以下がビルドファイルに追加されます。
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-opentelemetry</artifactId>
</dependency>
implementation("io.quarkus:quarkus-opentelemetry")
Jakarta REST リソースの調査
src/main/java/org/acme/opentelemetry/TracedResource.java のファイルを開くと、以下の内容が表示されます。
package org.acme.opentelemetry;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import org.jboss.logging.Logger;
@Path("/hello")
public class TracedResource {
private static final Logger LOG = Logger.getLogger(TracedResource.class);
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
LOG.info("hello");
return "hello";
}
}
このアプリケーションには、トレースのためのコードが含まれていないことに注意してください。デフォルトでは、このエンドポイントに送信されたリクエストは、コードの変更を必要とせずにトレースされます。
コンフィグレーションの作成
エクステンションを動作させるために必須の設定はありません。
デフォルトのプロパティ値を変更する必要がある場合、 src/main/resources/application.properties ファイルを使用して、アプリケーション内でデフォルトの OTLP gRPC Exporter を設定する方法の例を以下に示します:
quarkus.application.name=myservice (1)
quarkus.otel.exporter.otlp.traces.endpoint=http://localhost:4317 (2)
quarkus.otel.exporter.otlp.traces.headers=authorization=Bearer my_secret (3)
quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId}, parentId=%X{parentId}, spanId=%X{spanId}, sampled=%X{sampled} [%c{2.}] (%t) %s%e%n (4)
# Alternative to the console log
quarkus.http.access-log.pattern="...traceId=%{X,traceId} spanId=%{X,spanId}" (5)
| 1 | このアプリケーションから作成されたすべてのスパンには、そのスパンが myservice アプリケーションによって作成されたことを示す OpenTelemetry Resource が含まれます。設定されていない場合は、デフォルトでアーティファクトIDが設定されます。 |
| 2 | スパンを送信するためのgRPCエンドポイント。設定されていない場合、デフォルトは http://localhost:4317 . |
| 3 | 認証によく使われるオプションのgRPCヘッダー |
| 4 | ログメッセージにトレース情報を追加する。 |
| 5 | また、アクセスログにのみトレース情報を記載することもできます。この場合、コンソールログ形式の情報を省略する必要があります。 |
|
すべての設定は、 レガシー設定は現在非推奨となっていますが、移行期間中は引き続き使用できます。 |
OpenTelemetry エクステンション全体または一部を無効にする
Once you add the dependency, the extension will be enabled by default but there are a few ways to disable the OpenTelemetry extension globally or partially.
| プロパティ名 | デフォルト値 | 説明 |
|---|---|---|
|
true |
false の場合、ビルド 時に OpenTelemetry の使用を無効にします。 |
|
false |
OpenTelemetry autoconfiguration から取得されます。true の場合、実行時 に OpenTelemetry SDK の使用が無効化されます。 |
|
true |
false の場合、ビルド 時に OpenTelemetry トレースの使用を無効にします。 |
|
true |
If false will disable the default OTLP exporter at build time. |
If you need to enable or disable the exporter at runtime, you can use the サンプラー because it has the ability to filter out all the spans if needed.
アプリケーションの実行
最初のステップは、テレメトリデータを受信して処理し、キャプチャしたトレースを表示する Jaegerにエクスポートするための OpenTelemetry Collectorの設定と起動です。
|
Jaeger-all-in-oneは、Jaegerエージェント、OTelコレクター、クエリサービス/UIを含みます。分離型コレクタをインストールする必要はありません。トレースデータを直接Jaegerに送ることができます(OTLPレシーバーを有効にした後、詳細はこちらの ブログエントリ などをご覧ください)。 |
docker-compose up -d OpenTelemetry CollectorとJaegerシステムを、以下の docker-compose.yml ファイルを介して起動します。
version: "2"
services:
# Jaeger
jaeger-all-in-one:
image: jaegertracing/all-in-one:latest
ports:
- "16686:16686" # Jaeger UI
- "14268:14268" # Receive legacy OpenTracing traces, optional
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver, not yet used by Quarkus, optional
- "14250:14250" # Receive from external otel-collector, optional
environment:
- COLLECTOR_OTLP_ENABLED=true
オプションのポートは必要ないものは外しておいた方が良いです。
これでアプリケーションを実行する準備が整いました。トレーサーの設定に application.properties を使用している場合:
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
または、JVM引数でOTLP gRPCエンドポイントを設定する場合:
quarkus dev -Djvm.args="-Dquarkus.otel.exporter.otlp.traces.endpoint=http://localhost:4317"
./mvnw quarkus:dev -Djvm.args="-Dquarkus.otel.exporter.otlp.traces.endpoint=http://localhost:4317"
./gradlew --console=plain quarkusDev -Djvm.args="-Dquarkus.otel.exporter.otlp.traces.endpoint=http://localhost:4317"
OpenTelemetry Collector、Jaegerシステム、アプリケーションが動作している状態で、提供されているエンドポイントにリクエストを出すことができます。
$ curl http://localhost:8080/hello
hello
最初のリクエストが送信された時点で、ログにトレース情報が表示されるようになります:
10:49:02 INFO traceId=, parentId=, spanId=, sampled= [io.quarkus] (main) Installed features: [cdi, opentelemetry, resteasy-client, resteasy, smallrye-context-propagation, vertx]
10:49:03 INFO traceId=17ceb8429b9f25b0b879fa1503259456, parentId=3125c8bee75b7ad6, spanId=58ce77c86dd23457, sampled=true [or.ac.op.TracedResource] (executor-thread-1) hello
10:49:03 INFO traceId=ad23acd6d9a4ed3d1de07866a52fa2df, parentId=, spanId=df13f5b45cf4d1e2, sampled=true [or.ac.op.TracedResource] (executor-thread-0) hello
その後、 Jaeger UI にアクセスしてトレース情報を確認します。
CTRL+C を押すか、 q と入力して、アプリケーションを停止してください。
JDBC
JDBCインスツルメンテーションは、アプリケーションによって実行される各JDBCクエリのためにスパンを追加します。これを有効にするには、次の依存関係をビルドファイルに追加します。
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-jdbc</artifactId>
</dependency>
implementation("io.opentelemetry.instrumentation:opentelemetry-jdbc")
専用のJDBCデータソースラッパーを使用するため、データソースのテレメトリーを有効にする必要があります:
# enable tracing
quarkus.datasource.jdbc.telemetry=true
# configure datasource
quarkus.datasource.db-kind=postgresql
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/mydatabase
追加設定
一部のユースケースでは、OpenTelemetryのカスタム設定が必要になります。 これらのセクションでは、適切に構成するために必要なものについて概説します。
IDジェネレーター
OpenTelemetry エクステンションでは、トレースおよびスパンの識別子を作成する際に、デフォルトでランダムな ID ジェネレーターを使用します。
ベンダー固有のプロトコルの中には、カスタム ID ジェネレーターを必要とするものがありますが、プロデューサーを作成することで、デフォルトの ID ジェネレーターを上書きすることができます。OpenTelemetryエクステンションは、 IdGenerator CDI Beanを検出し、トレーサープロデューサーを構成する際にそれを使用します。
@Singleton
public class CustomConfiguration {
/** Creates a custom IdGenerator for OpenTelemetry */
@Produces
@Singleton
public IdGenerator idGenerator() {
return AwsXrayIdGenerator.getInstance();
}
}
プロパゲーター
OpenTelemetry は、 プロパゲーター を介して分野横断的な関心事を伝播し、状態を保存するための基になる"コンテキスト"を共有します 分散トランザクションの存続期間全体にわたってデータにアクセスします。
デフォルトでは、OpenTelemetryエクステンションは、 W3C Trace Contextと W3C Baggageプロパゲータを有効にしていますが、 設定リファレンスで説明されている propagators 設定を設定することで、サポートされているOpenTelemetryプロパゲータのいずれかを選択することができます。
追加プロパゲーター
-
b3,b3multi,jaeger,ottraceのプロパゲータは、プロジェクトに trace-propagatorsエクステンションを依存関係として追加する必要があります。
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-extension-trace-propagators</artifactId>
</dependency>
implementation("io.opentelemetry:opentelemetry-extension-trace-propagators")
-
xrayプロパゲーターは、お客様のプロジェクトに aws エクステンションを依存関係として追加することを必要とします。
<dependency>
<groupId>io.opentelemetry.contrib</groupId>
<artifactId>opentelemetry-aws-xray-propagator</artifactId>
</dependency>
implementation("io.opentelemetry.contrib:opentelemetry-aws-xray-propagator")
プロパゲーターをカスタマイズする
伝播ヘッダーをカスタマイズするには、 TextMapPropagatorCustomizer インターフェイスを実装します。たとえば、これを使用して、OpenTelemetry トレースヘッダーの伝播を制限し、機密性の高いデータがサードパーティーのシステムに送信されないようにすることができます。
/**
* /**
* Meant to be implemented by a CDI bean that provides arbitrary customization for the TextMapPropagator
* that are to be registered with OpenTelemetry
*/
public interface TextMapPropagatorCustomizer {
TextMapPropagator customize(Context context);
interface Context {
TextMapPropagator propagator();
ConfigProperties otelConfigProperties();
}
}
リソース
リソースは、テレメトリを生成しているエンティティの表現であり、誰がトレースを生成しているかを特徴づけるために、エクスポートされたトレースに属性を追加します。
設定リファレンス に記述されている resource-attributes トレーサーの設定を行うことで属性を追加することができます。 このプロパティは実行時にオーバーライドできるので、OpenTelemetry 拡張は Quarkus 設定リファレンス に記述されている優先順位に従ってその値を取得します。
カスタムリソースや OpenTelemetry SDK Extensionsで提供されているリソースを使用する必要がある場合は、複数のリソースプロデューサーを作成することができます。OpenTelemetryエクステンションは、 Resource CDI Beanを検出し、トレーサー・プロデューサーを構成する際にそれらをマージします。
@ApplicationScoped
public class CustomConfiguration {
@Produces
@ApplicationScoped
public Resource osResource() {
return OsResource.get();
}
@Produces
@ApplicationScoped
public Resource ecsResource() {
return EcsResource.get();
}
}
サンプラー
サンプラー は、トレースを破棄するか転送するかを決定し、コレクターに送信される収集されたトレースの数を制限することで、ノイズを効果的に管理し、オーバーヘッドを削減します。
Quarkus には 組み込みサンプラー が装備されており、カスタムサンプラーを作成するオプションもあります。
組み込みサンプラーを使用するには、OpenTelemetry 設定リファレンス の説明にあるように、必要なサンプラーパラメーターを設定することで、設定できます。たとえば、トレースの 50% を保持するようにサンプラーを設定できます。
# build time property only:
quarkus.otel.traces.sampler=traceidratio
# Runtime property:
quarkus.otel.traces.sampler.arg=0.5
|
An interesting use case for the sampler is to activate and deactivate tracing export at runtime, acording to this example:
|
|
Quarkus 3.0では、設定に大きな変更が加えられました。 最新のJava OpenTelemetry SDKに準拠するため、Sampler関連のプロパティ名と値が変更されます。移行期間中は、 サンプラーが親ベースである場合、現在廃止されたプロパティ
|
カスタムサンプラーを使用する必要がある場合、現在2種類の方法があります:
サンプラー CDI プロデューサー
サンプラー CDI プロデューサーを作成できます。Quarkus OpenTelemetry エクステンションは Sampler CDI Bean を検出し、Tracer を設定するときにそれを使用します。
@Singleton
public class CustomConfiguration {
/** Creates a custom sampler for OpenTelemetry */
@Produces
@Singleton
public Sampler sampler() {
return JaegerRemoteSampler.builder()
.setServiceName("my-service")
.build();
}
}
OTelサンプラーSPI
これにより、OTel 自動設定で使用可能な SPI フックが使用されます。 シンプルな Sampler クラスを作成できます。
public class CustomSPISampler implements Sampler {
@Override
public SamplingResult shouldSample(Context context,
String s,
String s1,
SpanKind spanKind,
Attributes attributes,
List<LinkData> list) {
// Do some sampling here
return Sampler.alwaysOn().shouldSample(context, s, s1, spanKind, attributes, list);
}
@Override
public String getDescription() {
return "custom-spi-sampler-description";
}
}
次に Sampler Provider を作成できます。
public class CustomSPISamplerProvider implements ConfigurableSamplerProvider {
@Override
public Sampler createSampler(ConfigProperties configProperties) {
return new CustomSPISampler();
}
@Override
public String getName() {
return "custom-spi-sampler";
}
}
resources/META-INF/services に io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSamplerProvider という名前の SPI ローダーテキストファイルを作成し、その中に CustomSPISamplerProvider クラスの完全修飾名を記述します。
次に、設定を有効にします。
quarkus.otel.traces.sampler=custom-spi-sampler
ご覧のとおり、CDI の方が操作がはるかに簡単です。
追加の計器
Quarkusエクステンションの中には、トレースが後続の実行に伝搬されることを保証するために追加のコードを必要とするものがあります。これらのセクションでは、プロセスの境界を越えてトレースを伝搬するために必要なことを説明します。
このセクションで説明されている計器は、Quarkusでテストされており、標準モードとネイティブモードの両方で動作します。
CDI
CDI 対応の任意の Bean のメソッドに io.opentelemetry.instrumentation.annotations.WithSpan
アノテーションを付与すると、新しい Span が作成され、現在の Trace コンテキストとの必要な関係が確立されます。
CDI 対応の任意の Bean のメソッドに io.opentelemetry.instrumentation.annotations.AddingSpanAttributes アノテーションを付与すると、新しい Span は作成されませんが、アノテーションが付けられたメソッドのパラメーターが現在の Span の属性として追加されます。
メソッドに誤って @AddingSpanAttributes アノテーションと @WithSpan アノテーションが付けられている場合は、 @WithSpan アノテーションが優先されます。
メソッドのパラメーターに io.opentelemetry.instrumentation.annotations.SpanAttribute アノテーションを付与することで、
どのメソッドパラメーターが Span の一部となるべきかを示すことができます。また、パラメーター名はカスタマイズすることも可能です。
例:
@ApplicationScoped
class SpanBean {
@WithSpan
void span() {
}
@WithSpan("name")
void spanName() {
}
@WithSpan(kind = SERVER)
void spanKind() {
}
@WithSpan
void spanArgs(@SpanAttribute(value = "arg") String arg) {
}
@AddingSpanAttributes
void addArgumentToExistingSpan(@SpanAttribute(value = "arg") String arg) {
}
}
使用可能なOpenTelemetry CDI依存関係注入
MicroProfile Telemetry Tracingの仕様に基づき、Quarkusは以下のクラスのCDI依存関係注入をサポートしています。
-
io.opentelemetry.api.OpenTelemetry -
io.opentelemetry.api.trace.Tracer -
io.opentelemetry.api.trace.Span -
io.opentelemetry.api.baggage.Baggage
これらのクラスは、CDIが有効なBeanに注入することができます。例えば、 Tracer は、カスタムスパンを開始するために特に有用です。
@Inject
Tracer tracer;
...
public void tracedWork() {
Span span = tracer.spanBuilder("My custom span")
.setAttribute("attr", "attr.value")
.setParent(Context.current().with(Span.current()))
.setSpanKind(SpanKind.INTERNAL)
.startSpan();
// traced work
span.end();
}
SmallRye Reactive Messaging - Kafka
SmallRye Reactive Messaging extension for Kafkaを使用すると、スパンをKafka Recordに伝搬させることができます。
TracingMetadata tm = TracingMetadata.withPrevious(Context.current());
Message out = Message.of(...).withMetadata(tm);
上記は、生成されている Message に追加できる TracingMetadata オブジェクトを作成し、OpenTelemetry Context を取得して、伝播のために現在のスパンを抽出しています。
エクスポーター
デフォルト
The Quarkus OpenTelemetry extension uses its own exporter built on top of Vert.x for optimal performance and maintainability.
The exporter is automatically wired with CDI, that’s why the quarkus.otel.traces.exporter property defaults to cdi.
The quarkus.otel.exporter.otlp.traces.protocol default to grpc and http/protobuf can also be used.
Quarkiverse について
追加のエクスポーターは、Quarkiverseの quarkus-opentelemetry-exporter プロジェクトで利用できるようになる予定です。
OpenTelemetry 設定リファレンス
Quarkusは、OpenTelemetryのAutoconfiguration for Tracesをサポートしています。設定は、 OpenTelemetry SDK Autoconfigure で確認できるものと一致し、 quarkus.* プレフィックスを追加しています。
Quarkus OpenTelemetryの設定プロパティに quarkus.otel.* プレフィックスが付くようになりました。
プレフィックスが quarkus.opentelemetry. の *レガシープロパティ は、現在、移行期間中、デフォルトとして新しいプロパティにマッピングされています。詳細は以下の「デフォルト」欄を参照してください。
ビルド時に固定される設定プロパティ - 他のすべての設定プロパティは実行時にオーバーライド可能
タイプ |
デフォルト |
|
|---|---|---|
List of exporters supported by Quarkus. List of exporters to be used for tracing, separated by commas. Has one of the values on Default on Quarkus is Environment variable: Show more |
文字列のリスト |
|
The sampler to use for tracing. Has one of the values on Fallbacks to the legacy property Environment variable: Show more |
string |
|
Environment variable: |
boolean |
|
No Metrics exporter for now Environment variable: Show more |
文字列のリスト |
|
No Log exporter for now. Environment variable: Show more |
文字列のリスト |
|
The propagators to be used. Use a comma-separated list for multiple propagators. Has values from Default is Environment variable: Show more |
文字列のリスト |
|
Enables instrumentation for gRPC. Environment variable: Show more |
boolean |
|
Enables instrumentation for SmallRye Reactive Messaging. Environment variable: Show more |
boolean |
|
Enables instrumentation for JAX-RS Rest Client backed by RESTEasy Classic. Environment variable: Show more |
boolean |
|
Enables instrumentation for RESTEasy Reactive. Environment variable: Show more |
boolean |
|
Enables instrumentation for RESTEasy Classic. Environment variable: Show more |
boolean |
|
If true, disable the OpenTelemetry SDK. Runtime configuration. Defaults to Environment variable: Show more |
boolean |
|
Suppress non-application uris from trace collection. This will suppress tracing of Providing a custom This is a Quarkus specific property. Suppressing non-application uris is enabled by default. Fallbacks to the legacy property Environment variable: Show more |
boolean |
|
Include static resources from trace collection. This is a Quarkus specific property. Include static resources is disabled by default. Providing a custom Fallbacks to the legacy property Environment variable: Show more |
boolean |
|
Sampler argument. Depends on the When setting the stock sampler to Defaults to Environment variable: Show more |
string |
|
The maximum length of attribute values. Applies to spans and logs. By default, there is no limit. Environment variable: Show more |
string |
|
The maximum number of attributes. Applies to spans, span events, span links, and logs. Default is Environment variable: Show more |
int |
|
The maximum length of span attribute values. Takes precedence over By default, there is no limit. Environment variable: Show more |
int |
|
The maximum number of attributes per span. Takes precedence over Default is Environment variable: Show more |
int |
|
The maximum number of events per span. Default is Environment variable: Show more |
int |
|
The maximum number of links per span. Default is Environment variable: Show more |
int |
|
The interval, in milliseconds, between two consecutive exports. Default is Environment variable: Show more |
|
|
The maximum queue size. Default is Environment variable: Show more |
int |
|
The maximum batch size. Default is Environment variable: Show more |
int |
|
The maximum allowed time, in milliseconds, to export data. Default is Environment variable: Show more |
|
|
Specify resource attributes in the following format: Environment variable: Show more |
文字列のリスト |
|
Specify logical service name. Takes precedence over service.name defined with otel.resource.attributes and from quarkus.application.name. Defaults to Environment variable: Show more |
string |
|
Specify resource attribute keys that are filtered. Environment variable: Show more |
文字列のリスト |
|
The maximum amount of time Quarkus will wait for the OpenTelemetry SDK to flush unsent spans and shutdown. Environment variable: Show more |
|
|
Enables instrumentation for Vert.x HTTP. Environment variable: Show more |
boolean |
|
Enables instrumentation for Vert.x Event Bus. Environment variable: Show more |
boolean |
|
Enables instrumentation for Vert.x SQL Client. Environment variable: Show more |
boolean |
|
Sets the OTLP endpoint to connect to. If unset, defaults to Environment variable: Show more |
string |
|
OTLP Exporter specific. Will override Fallbacks to the legacy property Environment variable: Show more |
string |
|
Key-value pairs to be used as headers associated with gRPC requests. The format is similar to the Environment variable: Show more |
文字列のリスト |
|
Sets the method used to compress payloads. If unset, compression is disabled. Currently supported compression methods include Environment variable: Show more |
|
|
Sets the maximum time to wait for the collector to process an exported batch of spans. If unset, defaults to `OtlpExporterRuntimeConfig#DEFAULT_TIMEOUT_SECS`s. Environment variable: Show more |
|
|
OTLP defines the encoding of telemetry data and the protocol used to exchange data between the client and the server. Depending on the exporter, the available protocols will be different. Currently, only Environment variable: Show more |
string |
|
Comma-separated list of the path to the key files (Pem format). Environment variable: Show more |
文字列のリスト |
|
Comma-separated list of the path to the certificate files (Pem format). Environment variable: Show more |
文字列のリスト |
|
Comma-separated list of the trust certificate files (Pem format). Environment variable: Show more |
文字列のリスト |
|
If proxy connection must be used. Environment variable: Show more |
boolean |
|
Set proxy username. Environment variable: Show more |
string |
|
Set proxy password. Environment variable: Show more |
string |
|
Set proxy port. Environment variable: Show more |
int |
|
Set proxy host. Environment variable: Show more |
string |
|
期間フォーマットについて
期間の値を書くには、標準の 数字で始まる簡略化した書式を使うこともできます:
その他の場合は、簡略化されたフォーマットが解析のために
|