The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

OpenTracingの使用

このガイドでは、QuarkusアプリケーションがOpenTracingを利用してインタラクティブなウェブアプリケーションのための分散トレースを提供する方法について説明します。

OpenTelemetryは 、Quarkusのトレースとテレメトリーに対する推奨アプローチです。

QuarkusがEclipse MicroProfile 6にアップグレードされると、SmallRye OpenTracingのサポートが停止されます。

この技術は、deprecatedと考えられています。

deprecated は、このエクステンションが Quarkus の将来のバージョンで置き換えられるか削除される可能性が高いことを意味します。

とりうるステータスの完全なリストについては、 FAQの項目 を参照してください。

前提条件

このガイドを完成させるには、以下が必要です:

  • 約15分

  • IDE

  • JDK 11+ がインストールされ、 JAVA_HOME が適切に設定されていること

  • Apache Maven 3.9.3

  • 動作するコンテナランタイム(Docker, Podman)

  • 使用したい場合は、 Quarkus CLI

  • ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること

アーキテクチャ

このガイドでは、分散トレースを実証するための簡単なRESTアプリケーションを作成します。

ソリューション

次のセクションで紹介する手順に沿って、ステップを踏んでアプリを作成することをお勧めします。ただし、すぐに完成した例に飛んでも構いません。

Gitレポジトリをクローンするか git clone https://github.com/quarkusio/quarkus-quickstarts.gitアーカイブ をダウンロードします。

The solution is located in the opentracing-quickstart directory.

Mavenプロジェクトの作成

まず、新しいプロジェクトが必要です。以下のコマンドで新規プロジェクトを作成します:

コマンドラインインタフェース
quarkus create app org.acme:opentracing-quickstart \
    --extension='resteasy-reactive,quarkus-smallrye-opentracing' \
    --no-code
cd opentracing-quickstart

Gradleプロジェクトを作成するには、 --gradle または --gradle-kotlin-dsl オプションを追加します。

For more information about how to install and use the Quarkus CLI, see the Quarkus CLI guide.

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:3.4.1:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=opentracing-quickstart \
    -Dextensions='resteasy-reactive,quarkus-smallrye-opentracing' \
    -DnoCode
cd opentracing-quickstart

Gradleプロジェクトを作成するには、 -DbuildTool=gradle または -DbuildTool=gradle-kotlin-dsl オプションを追加します。

Windowsユーザーの場合:

  • If using cmd, (don’t use backward slash \ and put everything on the same line)

  • If using Powershell, wrap -D parameters in double quotes e.g. "-DprojectArtifactId=opentracing-quickstart"

このコマンドはMaven プロジェクトを生成し、OpenTracingのサポートとデフォルトの Jaeger トレーサーを含む smallrye-opentracing エクステンションをインポートします。

すでにQuarkusプロジェクトを設定されている場合は、プロジェクトのベースディレクトリーで以下のコマンドを実行することで、プロジェクトに smallrye-opentracing エクステンションを追加することができます:

コマンドラインインタフェース
quarkus extension add 'smallrye-opentracing'
Maven
./mvnw quarkus:add-extension -Dextensions='smallrye-opentracing'
Gradle
./gradlew addExtension --extensions='smallrye-opentracing'

これにより、ビルドファイルに以下の内容が追加されます:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-smallrye-opentracing</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-smallrye-opentracing")

Jakarta REST リソースの調査

以下の内容で src/main/java/org/acme/opentracing/TracedResource.java ファイルを作成します:

package org.acme.opentracing;

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"); (1)
        return "hello";
    }
}
1 ログイベントは OpenTracing の情報も含んでいます。OpenTracingの情報をコンソール出力するためには、必要なOpenTracingイベントのキーを持つコンソールログハンドラを application.properties ファイルで定義する必要があります。

このアプリケーションにはトレース用のコードが含まれていないことに注意してください。デフォルトでは、このエンドポイントに送信されたリクエストは、コードを変更することなくトレースされます。トレース情報を拡張することも可能です。これは、 MicroProfile OpenTracing の実装である SmallRye OpenTracing で実現できます。

設定の作成

アプリケーション内でJaeger トレーサーを設定するには、2つの方法があります。

最初のアプローチは、 src/main/resources/application.properties ファイル内でプロパティーを設定することです:

quarkus.jaeger.service-name=myservice (1)
quarkus.jaeger.sampler-type=const (2)
quarkus.jaeger.sampler-param=1 (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)
1 quarkus.jaeger.service-name プロパティー (または JAEGER_SERVICE_NAME 環境変数) を指定しなかった場合は、"no-op" トレーサーが設定され、バックエンドにトレースデータは報告されなくなります。
2 定数サンプリングを行うサンプラーを設定します。
3 すべてのリクエストをサンプリングします。すべてのリクエストをサンプリングしたくない場合は、sampler-param をに0から1の間の値を設定します (例: 0.50)。
4 ログメッセージにトレースIDを追加します。

2つ目の方法は、プロパティを 環境変数 として指定する方法です。これらは、次のセクションに示すように jvm.args として指定できます。

アプリケーションの実行

まず、トレースシステムを起動し、キャプチャしたトレースを収集・表示します:

docker run -p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778 -p 16686:16686 -p 14268:14268 jaegertracing/all-in-one:latest

これでアプリケーションを実行する準備が整いました。もし、トレーサーの設定に application.properties を使っている場合は次のようにします:

コマンドラインインタフェース
quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./gradlew --console=plain quarkusDev

または、環境変数でトレーサーを設定する場合:

コマンドラインインタフェース
quarkus dev -Djvm.args="-DJAEGER_SERVICE_NAME=myservice -DJAEGER_SAMPLER_TYPE=const -DJAEGER_SAMPLER_PARAM=1"
Maven
./mvnw quarkus:dev -Djvm.args="-DJAEGER_SERVICE_NAME=myservice -DJAEGER_SAMPLER_TYPE=const -DJAEGER_SAMPLER_PARAM=1"
Gradle
./gradlew --console=plain quarkusDev -Djvm.args="-DJAEGER_SERVICE_NAME=myservice -DJAEGER_SAMPLER_TYPE=const -DJAEGER_SAMPLER_PARAM=1"

アプリケーションとトレースシステムの両方が起動したら、提供されたエンドポイントにリクエストを行うことができます:

$ curl http://localhost:8080/hello
hello

最初のリクエストが送信されると、アプリ内のJaegerトレーサーが初期化されます:

2019-10-16 09:35:23,464 INFO  [io.jae.Configuration] (executor-thread-1) Initialized tracer=JaegerTracer(version=Java-0.34.0, serviceName=myservice, reporter=RemoteReporter(sender=UdpSender(), closeEnqueueTimeout=1000), sampler=ConstSampler(decision=true, tags={sampler.type=const, sampler.param=true}), tags={hostname=localhost.localdomain, jaeger.version=Java-0.34.0, ip=127.0.0.1}, zipkinSharedRpcSpan=false, expandExceptionLogs=false, useTraceId128Bit=false)
13:20:11 INFO  traceId=1336b2b0a76a96a3, parentId=0, spanId=1336b2b0a76a96a3, sampled=true [or.ac.qu.TracedResource] (executor-thread-63) hello

その後、 Jaeger UI にアクセスしてトレース情報を確認します。

CTRL+C を押して、アプリケーションを停止します。

追加メソッドのトレース

REST エンドポイントは自動的にトレースされます。追加でメソッドをトレースする必要がある場合は、CDI beanのクラスや非privateのメソッドに org.eclipse.microprofile.opentracing.Traced アノテーションを追加することができます。

これは、非RESTコール(メッセージからのリクエストなど)からの着信リクエストをトレースしたり、トレース内にスパンを作成したりするのに便利です。

ここでは、メソッドがトレースされている FrancophoneService の例を示します。

import jakarta.enterprise.context.ApplicationScoped;

import org.eclipse.microprofile.opentracing.Traced;

@Traced
@ApplicationScoped
public class FrancophoneService {

    public String bonjour() {
        return "bonjour";
    }
}
OpenTracingの機能をリアクティブなメッセージングベースのアプリケーションに追加する最良の方法は、すべての受信メソッドに Traced アノテーションを追加することです。

追加のInstrumentation

OpenTracing API Contributionsプロジェクト では、様々な技術/コンポーネントにトレースを追加するための追加の計器 (Instrumentation) を提供しています。

このセクションで説明されているInstrumentationは、Quarkusでテストされており、標準モードとネイティブモードの両方で動作します。

JDBC

JDBC Instrumentation は 、アプリケーションが実行するJDBCクエリごとにスパンを追加します。これを有効にするには、ビルドファイルに次の依存関係を追加します:

pom.xml
<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-jdbc</artifactId>
</dependency>
build.gradle
implementation("io.opentracing.contrib:opentracing-jdbc")

そして、コンフィギュレーションで有効にする必要があります。

quarkus.datasource.jdbc.tracing=true
`quarkus.datasource.jdbc.tracing` は、ビルド時設定プロパティです。すべてのトレース基盤がアプリケーションに含まれていることを確認します。

これはネイティブの実行可能ファイルをビルドする際に特に重要で、OpenTracing JDBCドライバが、基盤となるJDBCドライバとともに、リフレクション用に登録されていることを確認する必要があるからです。

トレースが有効な場合、JDBC の URL を tracing というプレフィックスで調整するのは Agroal エクステンションが担当するので、自分で JDBC の URL を調整する必要はありません。

デフォルトでは、 quarkus.datasource.jdbc.tracing が true の場合、実行時にトレースが有効になりますが、以下のプロパティを設定することで、明示的にトレースを無効にすることができます。

quarkus.datasource.jdbc.tracing.enabled=false

こうすることで、Quarkusアプリケーションをトレースできる状態にし、実行時にJDBCトレースを切り換えることができます。

Kafka

Kafka instrumentation は、Kafka トピックとの間で送受信されるメッセージごとにスパンを追加します。これを有効にするには、ビルドファイルに以下の依存関係を追加します:

pom.xml
<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-kafka-client</artifactId>
</dependency>
build.gradle
implementation("io.opentracing.contrib:opentracing-kafka-client")

KafkaのProducerとConsumerに登録する必要があるOpenTracingのインターセプターが含まれています。

Kafkaのガイド に従った場合、以下のように generated-priceprices のチャンネルにインターセプターを追加することができます:

# Configure the Kafka sink (we write to it)
mp.messaging.outgoing.generated-price.connector=smallrye-kafka
mp.messaging.outgoing.generated-price.topic=prices
mp.messaging.outgoing.generated-price.value.serializer=org.apache.kafka.common.serialization.IntegerSerializer
mp.messaging.outgoing.generated-price.interceptor.classes=io.opentracing.contrib.kafka.TracingProducerInterceptor

# Configure the Kafka source (we read from it)
mp.messaging.incoming.prices.connector=smallrye-kafka
mp.messaging.incoming.prices.value.deserializer=org.apache.kafka.common.serialization.IntegerDeserializer
mp.messaging.incoming.prices.interceptor.classes=io.opentracing.contrib.kafka.TracingConsumerInterceptor
interceptor.classes はカンマで区切られたクラスのリストを指定できます。

MongoDBクライアント

Mongo Driver instrumentation は 、アプリケーションが実行するコマンドごとにスパンを追加します。これを有効にするには、ビルドファイルに次の依存関係を追加します:

pom.xml
<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-mongo-common</artifactId>
</dependency>
build.gradle
implementation("io.opentracing.contrib:opentracing-mongo-common")

これには、mongoクライアントの設定に登録されるOpenTracing CommandListenerが含まれています。 MongoDBのガイド に従い、以下のようにconfigプロパティを定義してコマンドリスナーを登録します:

# Enable tracing commands in mongodb client
quarkus.mongodb.tracing.enabled=true

Zipkin互換モード

これを有効にするには、ビルドファイルに以下の依存関係を追加します:

pom.xml
<dependency>
    <groupId>io.jaegertracing</groupId>
    <artifactId>jaeger-zipkin</artifactId>
</dependency>
build.gradle
implementation("io.jaegertracing:jaeger-zipkin")

これはリクエストを zipkin フォーマットに変換するための依存関係を含んでいます。 zipkin 互換モードは、以下のように config プロパティを定義した後に有効になります:

# Enable zipkin compatibility mode
quarkus.jaeger.zipkin.compatibility-mode=true

Jaeger構成リファレンス

ビルド時に固定される設定プロパティ - その他の設定プロパティは実行時にオーバーライド可能です。

Configuration property

デフォルト

Defines if the Jaeger extension is enabled.

Environment variable: QUARKUS_JAEGER_ENABLED

Show more

boolean

true

Whether metrics are published in case a metrics extension is present.

Environment variable: QUARKUS_JAEGER_METRICS_ENABLED

Show more

boolean

false

The traces endpoint, in case the client should connect directly to the Collector, like http://jaeger-collector:14268/api/traces

Environment variable: QUARKUS_JAEGER_ENDPOINT

Show more

URI

Authentication Token to send as "Bearer" to the endpoint

Environment variable: QUARKUS_JAEGER_AUTH_TOKEN

Show more

string

Username to send as part of "Basic" authentication to the endpoint

Environment variable: QUARKUS_JAEGER_USER

Show more

string

Password to send as part of "Basic" authentication to the endpoint

Environment variable: QUARKUS_JAEGER_PASSWORD

Show more

string

The hostname and port for communicating with agent via UDP

Environment variable: QUARKUS_JAEGER_AGENT_HOST_PORT

Show more

host:port

Whether the reporter should also log the spans

Environment variable: QUARKUS_JAEGER_REPORTER_LOG_SPANS

Show more

boolean

The reporter’s maximum queue size

Environment variable: QUARKUS_JAEGER_REPORTER_MAX_QUEUE_SIZE

Show more

int

The reporter’s flush interval

Environment variable: QUARKUS_JAEGER_REPORTER_FLUSH_INTERVAL

Show more

Duration

The sampler type (const, probabilistic, ratelimiting or remote)

Environment variable: QUARKUS_JAEGER_SAMPLER_TYPE

Show more

string

The sampler parameter (number)

Environment variable: QUARKUS_JAEGER_SAMPLER_PARAM

Show more

BigDecimal

The host name and port when using the remote controlled sampler

Environment variable: QUARKUS_JAEGER_SAMPLER_MANAGER_HOST_PORT

Show more

host:port

The service name

Environment variable: QUARKUS_JAEGER_SERVICE_NAME

Show more

string

A comma separated list of name = value tracer level tags, which get added to all reported spans. The value can also refer to an environment variable using the format ${envVarName:default}, where the :default is optional, and identifies a value to be used if the environment variable cannot be found

Environment variable: QUARKUS_JAEGER_TAGS

Show more

string

Comma separated list of formats to use for propagating the trace context. Defaults to the standard Jaeger format. Valid values are jaeger and b3

Environment variable: QUARKUS_JAEGER_PROPAGATION

Show more

string

The sender factory class name

Environment variable: QUARKUS_JAEGER_SENDER_FACTORY

Show more

string

Whether the trace context should be logged.

Environment variable: QUARKUS_JAEGER_LOG_TRACE_CONTEXT

Show more

boolean

true

Whether the registration of tracer as the global tracer should be disabled. This setting should only be turned on in tests that need to install a mock tracer.

Environment variable: QUARKUS_JAEGER_DISABLE_TRACER_REGISTRATION

Show more

boolean

false

Whether jaeger should run in zipkin compatibility mode

Environment variable: QUARKUS_JAEGER_ZIPKIN_COMPATIBILITY_MODE

Show more

boolean

false

期間フォーマットについて

To write duration values, use the standard java.time.Duration format. See the Duration#parse() javadoc for more information.

You can also use a simplified format, starting with a number:

  • If the value is only a number, it represents time in seconds.

  • If the value is a number followed by ms, it represents time in milliseconds.

In other cases, the simplified format is translated to the java.time.Duration format for parsing:

  • If the value is a number followed by h, m, or s, it is prefixed with PT.

  • If the value is a number followed by d, it is prefixed with P.