9.3. 分散トレースの設定
カスタムリソースでトレースタイプを指定して、Kafka コンポーネントで分散トレースを有効にします。メッセージをエンドツーエンドで追跡するために Kafka クライアントにトレーサーをインストルメント化します。
分散トレースを設定するには、次の手順を順番に実行します。
- MirrorMaker、Kafka Connect、Kafka Bridge のトレースを設定します。
クライアントのトレースを設定します。
トレーサーでクライアントをインストルメント化します。
9.3.1. 前提条件 リンクのコピーリンクがクリップボードにコピーされました!
分散トレースを設定する前に、Jaeger バックエンドコンポーネントが OpenShift クラスターにデプロイされていることを確認してください。OpenShift クラスターに Jaeger をデプロイするには、Jaeger Operator を使用することをお勧めします。
デプロイメント手順は、Jaeger のドキュメント を参照してください。
AMQ Streams 以外のアプリケーションおよびシステムにトレースを設定する方法については、このコンテンツの対象外となります。
9.3.2. MirrorMaker、Kafka Connect、および Kafka Bridge リソースでのトレーシングの有効化 リンクのコピーリンクがクリップボードにコピーされました!
分散トレーシングは、MirrorMaker、MirrorMaker 2.0、Kafka Connect、および AMQ Streams Kafka Bridge でサポートされます。コンポーネントのカスタムリソースを設定して、トレーサーサービスを指定して有効にします。
リソースでトレースを有効にすると、次のイベントがトリガーされます。
- インターセプタークラスは、コンポーネントの統合コンシューマーとプロデューサーで更新されます。
- MirrorMaker、MirrorMaker 2.0 および Kafka Connect では、リソースで定義されたトレース設定に基づいて、トレーサーがトレースエージェントによって初期化されます。
- Kafka Bridge の場合、リソースで定義されたトレース設定に基づくトレーサーは、Kafka Bridge 自体によって初期化されます。
OpenTelemetry または OpenTracing を使用するトレースを有効にできます。
MirrorMaker および MirrorMaker 2.0 でのトレーシング
MirrorMaker および MirrorMaker 2.0 では、メッセージはソースクラスターからターゲットクラスターにトレーシングされます。トレースデータは、MirrorMaker または MirrorMaker 2.0 コンポーネントを出入りするメッセージを記録します。
Kafka Connect でのトレーシング
Kafka Connect の場合、Kafka Connect によって生成および消費されたメッセージのみがトレースされます。Kafka Connect と外部システム間で送信されるメッセージをトレースするには、これらのシステムのコネクターでトレースを設定する必要があります。
Kafka Bridge でのトレーシング
Kafka Bridge の場合、Kafka Bridge によって生成および消費されるメッセージがトレースされます。Kafka Bridge を介してメッセージを送受信するクライアントアプリケーションから受信する HTTP リクエストもトレーシングされます。エンドツーエンドのトレーシングを設定するために、HTTP クライアントでトレーシングを設定する必要があります。
手順
以下の手順を、KafkaMirrorMaker、KafkaMirrorMaker2、KafkaConnect、および KafkaBridge リソースごとに実行します。
spec.templateプロパティーで、トレーサーサービスを設定します。- トレーシング環境変数 をテンプレートの設定プロパティーとして使用します。
-
OpenTelemetry の場合、
spec.tracing.typeプロパティーをopentelemetryに設定します。 -
OpenTracing の場合、
spec.tracing.typeプロパティーをjaegerに設定します。
OpenTelemetry を使用した Kafka Connect のトレース設定の例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect-cluster spec: #... template: connectContainer: env: - name: OTEL_SERVICE_NAME value: my-otel-service - name: OTEL_EXPORTER_JAEGER_ENDPOINT value: "http://jaeger-host:14250" tracing: type: opentelemetry #...OpenTelemetry を使用した MirrorMaker のトレース設定の例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker metadata: name: my-mirror-maker spec: #... template: mirrorMakerContainer: env: - name: OTEL_SERVICE_NAME value: my-otel-service - name: OTEL_EXPORTER_JAEGER_ENDPOINT value: "http://jaeger-host:14250" tracing: type: opentelemetry #...OpenTelemetry を使用した MirrorMaker 2.0 のトレース設定の例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker2 metadata: name: my-mm2-cluster spec: #... template: connectContainer: env: - name: OTEL_SERVICE_NAME value: my-otel-service - name: OTEL_EXPORTER_JAEGER_ENDPOINT value: "http://jaeger-host:14250" tracing: type: opentelemetry #...OpenTelemetry を使用した Kafka Bridge のトレース設定の例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaBridge metadata: name: my-bridge spec: #... template: bridgeContainer: env: - name: OTEL_SERVICE_NAME value: my-otel-service - name: OTEL_EXPORTER_JAEGER_ENDPOINT value: "http://jaeger-host:14250" tracing: type: opentelemetry #...OpenTracing を使用した Kafka Connect のトレース設定の例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaConnect metadata: name: my-connect-cluster spec: #... template: connectContainer: env: - name: JAEGER_SERVICE_NAME value: my-jaeger-service - name: JAEGER_AGENT_HOST value: jaeger-agent-name - name: JAEGER_AGENT_PORT value: "6831" tracing: type: jaeger #...OpenTracing を使用した MirrorMaker のトレース設定の例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker metadata: name: my-mirror-maker spec: #... template: mirrorMakerContainer: env: - name: JAEGER_SERVICE_NAME value: my-jaeger-service - name: JAEGER_AGENT_HOST value: jaeger-agent-name - name: JAEGER_AGENT_PORT value: "6831" tracing: type: jaeger #...OpenTracing を使用した MirrorMaker 2.0 のトレース設定の例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker2 metadata: name: my-mm2-cluster spec: #... template: connectContainer: env: - name: JAEGER_SERVICE_NAME value: my-jaeger-service - name: JAEGER_AGENT_HOST value: jaeger-agent-name - name: JAEGER_AGENT_PORT value: "6831" tracing: type: jaeger #...OpenTracing を使用した Kafka Bridge のトレース設定の例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaBridge metadata: name: my-bridge spec: #... template: bridgeContainer: env: - name: JAEGER_SERVICE_NAME value: my-jaeger-service - name: JAEGER_AGENT_HOST value: jaeger-agent-name - name: JAEGER_AGENT_PORT value: "6831" tracing: type: jaeger #...リソースを作成または更新します。
oc apply -f <resource_configuration_file>
9.3.3. Kafka クライアントのトレースの初期化 リンクのコピーリンクがクリップボードにコピーされました!
トレーサーを初期化し、分散トレース用にクライアントアプリケーションをインストルメント化します。Kafka プロデューサークライアントとコンシューマークライアント、および Kafka Streams API アプリケーションをインストルメント化できます。OpenTracing または OpenTelemetry のトレーサーを初期化できます。
一連の トレース環境変数 を使用して、トレーサーを設定および初期化します。
手順
各クライアントアプリケーションで、トレーサーの依存関係を追加します。
クライアントアプリケーションの
pom.xmlファイルに Maven 依存関係を追加します。OpenTelemetry の依存関係
<dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId> <version>1.18.0-alpha</version> </dependency> <dependency> <groupId>io.opentelemetry.instrumentation</groupId> <artifactId>opentelemetry-kafka-clients-{OpenTelemetryKafkaClient}</artifactId> <version>1.18.0-alpha</version> </dependency> <dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-exporter-jaeger</artifactId> <version>1.18.0</version> </dependency>OpenTracing の依存関係
<dependency> <groupId>io.jaegertracing</groupId> <artifactId>jaeger-client</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>io.opentracing.contrib</groupId> <artifactId>opentracing-kafka-client</artifactId> <version>0.1.15</version> </dependency>- トレース環境変数 を使用して、トレーサーの設定を定義します。
環境変数で初期化されるトレーサーを作成します。
OpenTelemetry のトレーサーの作成
OpenTelemetry ot = GlobalOpenTelemetry.get();OpenTracing のトレーサーの作成
Tracer tracer = Configuration.fromEnv().getTracer();トレーサーをグローバルトレーサーとして登録します。
GlobalTracer.register(tracer);クライアントをインストルメント化します。
9.3.4. Kafka プロデューサーおよびコンシューマーをトレース用にインストルメント化 リンクのコピーリンクがクリップボードにコピーされました!
アプリケーションコードを計測して、Kafka プロデューサーとコンシューマーでのトレースを有効にします。デコレーターパターンまたはインターセプターを使用して、Java プロデューサーおよびコンシューマーアプリケーションコードをトレース用にインストルメント化します。続いて、メッセージが生成されたとき、またはトピックから取得されたときにトレースを記録できます。
OpenTelemetry および OpenTracing インストルメント化プロジェクトは、プロデューサーとコンシューマーのインストルメント化をサポートするクラスを提供します。
- デコレーターのインストルメント化
- デコレーターのインストルメント化の場合、トレース用に変更されたプロデューサーまたはコンシューマーインスタンスを作成します。OpenTelemetry と OpenTracing では、デコレーターのインストルメント化が異なります。
- インターセプターのインストルメント化
- インターセプターのインストルメント化の場合、トレース機能をコンシューマーまたはプロデューサーの設定に追加します。インターセプターのインストルメント化は、OpenTelemetry と OpenTracing で同じです。
前提条件
クライアントのトレースを初期化 している。
トレース JAR を依存関係としてプロジェクトに追加することで、プロデューサーアプリケーションとコンシューマーアプリケーションでインストルメント化を有効にします。
手順
各プロデューサーおよびコンシューマーアプリケーションのアプリケーションコードで、これらの手順を実行します。デコレーターパターンまたはインターセプターのいずれかを使用して、クライアントアプリケーションコードをインストルメント化します。
デコレーターパターンを使用するには、変更されたプロデューサーまたはコンシューマーインスタンスを作成して、メッセージを送受信します。
元の
KafkaProducerまたはKafkaConsumerクラスを渡します。OpenTelemetry のデコレーターインストルメント化の例
// Producer instance Producer < String, String > op = new KafkaProducer < > ( configs, new StringSerializer(), new StringSerializer() ); Producer < String, String > producer = tracing.wrap(op); KafkaTracing tracing = KafkaTracing.create(GlobalOpenTelemetry.get()); producer.send(...); //consumer instance Consumer<String, String> oc = new KafkaConsumer<>( configs, new StringDeserializer(), new StringDeserializer() ); Consumer<String, String> consumer = tracing.wrap(oc); consumer.subscribe(Collections.singleton("mytopic")); ConsumerRecords<Integer, String> records = consumer.poll(1000); ConsumerRecord<Integer, String> record = ... SpanContext spanContext = TracingKafkaUtils.extractSpanContext(record.headers(), tracer);OpenTracing のデコレーターインストルメント化の例
//producer instance KafkaProducer<Integer, String> producer = new KafkaProducer<>(senderProps); TracingKafkaProducer<Integer, String> tracingProducer = new TracingKafkaProducer<>(producer, tracer); TracingKafkaProducer.send(...) //consumer instance KafkaConsumer<Integer, String> consumer = new KafkaConsumer<>(consumerProps); TracingKafkaConsumer<Integer, String> tracingConsumer = new TracingKafkaConsumer<>(consumer, tracer); tracingConsumer.subscribe(Collections.singletonList("mytopic")); ConsumerRecords<Integer, String> records = tracingConsumer.poll(1000); ConsumerRecord<Integer, String> record = ... SpanContext spanContext = TracingKafkaUtils.extractSpanContext(record.headers(), tracer);インターセプターを使用するには、プロデューサーまたはコンシューマーの設定でインターセプタークラスを設定します。
通常の方法で
KafkaProducerクラスとKafkaConsumerクラスを使用します。TracingProducerInterceptorおよびTracingConsumerInterceptorインターセプタークラスは、トレース機能を処理します。インターセプターを使用したプロデューサー設定の例
senderProps.put(ProducerConfig.INTERCEPTOR_CLASSES_CONFIG, TracingProducerInterceptor.class.getName()); KafkaProducer<Integer, String> producer = new KafkaProducer<>(senderProps); producer.send(...);インターセプターを使用したコンシューマー設定の例
consumerProps.put(ConsumerConfig.INTERCEPTOR_CLASSES_CONFIG, TracingConsumerInterceptor.class.getName()); KafkaConsumer<Integer, String> consumer = new KafkaConsumer<>(consumerProps); consumer.subscribe(Collections.singletonList("messages")); ConsumerRecords<Integer, String> records = consumer.poll(1000); ConsumerRecord<Integer, String> record = ... SpanContext spanContext = TracingKafkaUtils.extractSpanContext(record.headers(), tracer);
9.3.5. Kafka Streams アプリケーションのトレース用のインストルメント化 リンクのコピーリンクがクリップボードにコピーされました!
アプリケーションコードを計測して、Kafka Streams API アプリケーションでのトレースを有効にします。デコレーターパターンまたはインターセプターを使用して、トレース用に Kafka Streams API アプリケーションをインストルメント化します。続いて、メッセージが生成されたとき、またはトピックから取得されたときにトレースを記録できます。
- デコレーターのインストルメント化
-
デコレーターのインストルメント化の場合、トレース用に変更された Kafka Streams インスタンスを作成します。OpenTracing インストルメント化プロジェクトは、Kafka Streams のインストルメント化をサポートする
TracingKafkaClientSupplierクラスを提供します。TracingKafkaClientSupplierサプライヤーインターフェイスのインスタンスをラップして作成し、Kafka Streams のトレースインストルメント化を行います。OpenTelemetry の場合、プロセスは同じですが、サポートを提供するためにカスタムTracingKafkaClientSupplierクラスを作成する必要があります。 - インターセプターのインストルメント化
- インターセプターインストルメント化の場合、トレース機能を Kafka Streams プロデューサーおよびコンシューマー設定に追加します。
前提条件
クライアントのトレースを初期化 している。
トレース JAR を依存関係としてプロジェクトに追加することにより、Kafka Streams アプリケーションでインストルメント化を有効にします。
-
カスタムの
TracingKafkaClientSupplierを記述して、OpenTelemetry で Kafka Streams をインストルメント化する。 カスタム
TracingKafkaClientSupplierが Kafka のDefaultKafkaClientSupplierを拡張し、プロデューサーとコンシューマーの作成メソッドを上書きして、インスタンスを Telemetry 関連のコードでラップできる。カスタム
TracingKafkaClientSupplierの例private class TracingKafkaClientSupplier extends DefaultKafkaClientSupplier { @Override public Producer<byte[], byte[]> getProducer(Map<String, Object> config) { KafkaTelemetry telemetry = KafkaTelemetry.create(GlobalOpenTelemetry.get()); return telemetry.wrap(super.getProducer(config)); } @Override public Consumer<byte[], byte[]> getConsumer(Map<String, Object> config) { KafkaTelemetry telemetry = KafkaTelemetry.create(GlobalOpenTelemetry.get()); return telemetry.wrap(super.getConsumer(config)); } @Override public Consumer<byte[], byte[]> getRestoreConsumer(Map<String, Object> config) { return this.getConsumer(config); } @Override public Consumer<byte[], byte[]> getGlobalConsumer(Map<String, Object> config) { return this.getConsumer(config); } }
手順
Kafka Streams API アプリケーションごとにこれらの手順を実行します。
デコレーターパターンを使用するには、
TracingKafkaClientSupplierサプライヤーインターフェイスのインスタンスを作成し、そのサプライヤーインターフェイスをKafkaStreamsに提供します。デコレーターのインストルメント化の例
KafkaClientSupplier supplier = new TracingKafkaClientSupplier(tracer); KafkaStreams streams = new KafkaStreams(builder.build(), new StreamsConfig(config), supplier); streams.start();インターセプターを使用するには、Kafka Streams プロデューサーおよびコンシューマー設定でインターセプタークラスを設定します。
TracingProducerInterceptorおよびTracingConsumerInterceptorインターセプタークラスは、トレース機能を処理します。インターセプターを使用したプロデューサーとコンシューマーの設定例
props.put(StreamsConfig.PRODUCER_PREFIX + ProducerConfig.INTERCEPTOR_CLASSES_CONFIG, TracingProducerInterceptor.class.getName()); props.put(StreamsConfig.CONSUMER_PREFIX + ConsumerConfig.INTERCEPTOR_CLASSES_CONFIG, TracingConsumerInterceptor.class.getName());
9.3.6. 別の OpenTelemetry トレースシステムの導入 リンクのコピーリンクがクリップボードにコピーされました!
デフォルトの Jaeger システムの代わりに、OpenTelemetry でサポートされる他のトレースシステムを指定できます。これを行うには、AMQ Streams で提供される Kafka イメージに必要なアーティファクトを追加します。必要な実装固有の環境変数も設定する必要があります。次に、OTEL_TRACES_EXPORTER 環境変数を使用して、新しいトレースの実装を有効にします。
この手順では、Zipkin トレースを実装する方法を示します。
手順
トレースアーティファクトを AMQ Streams Kafka イメージの
/opt/kafka/libs/ディレクトリーに追加します。新しいカスタムイメージを作成するための基本イメージとして、Red Hat Ecosystem Catalog の Kafka コンテナーイメージを使用できます。
Zipkin の OpenTelemetry アーティファクト
io.opentelemetry:opentelemetry-exporter-zipkin新しいトレース実装のトレースエクスポーターとエンドポイントを設定します。
Zikpin トレーサーの設定例
apiVersion: kafka.strimzi.io/v1beta2 kind: KafkaMirrorMaker2 metadata: name: my-mm2-cluster spec: #... template: connectContainer: env: - name: OTEL_SERVICE_NAME value: my-zipkin-service - name: OTEL_EXPORTER_ZIPKIN_ENDPOINT value: http://zipkin-exporter-host-name:9411/api/v2/spans1 - name: OTEL_TRACES_EXPORTER value: zipkin2 tracing: type: opentelemetry #...
9.3.7. カスタムスパン名 リンクのコピーリンクがクリップボードにコピーされました!
トレース スパン は Jaeger の論理作業単位で、操作名、開始時間、および期間が含まれます。スパンには組み込みの名前がありますが、使用する Kafka クライアントインストルメント化で、カスタムスパン名を指定できます。
カスタムスパン名の指定はオプションであり、プロデューサーおよびコンシューマークライアントインストルメント化 または Kafka Streams インストルメント化 でデコレーターパターンを使用する場合にのみ適用されます。
9.3.7.1. OpenTelemetry のスパン名の指定 リンクのコピーリンクがクリップボードにコピーされました!
OpenTelemetry でカスタムスパン名を直接指定できません。代わりに、コードをクライアントアプリケーションに追加してスパン名を取得し、追加のタグと属性を抽出します。
属性を抽出するコード例
//Defines attribute extraction for a producer
private static class ProducerAttribExtractor implements AttributesExtractor < ProducerRecord < ? , ? > , Void > {
@Override
public void onStart(AttributesBuilder attributes, ProducerRecord < ? , ? > producerRecord) {
set(attributes, AttributeKey.stringKey("prod_start"), "prod1");
}
@Override
public void onEnd(AttributesBuilder attributes, ProducerRecord < ? , ? > producerRecord, @Nullable Void unused, @Nullable Throwable error) {
set(attributes, AttributeKey.stringKey("prod_end"), "prod2");
}
}
//Defines attribute extraction for a consumer
private static class ConsumerAttribExtractor implements AttributesExtractor < ConsumerRecord < ? , ? > , Void > {
@Override
public void onStart(AttributesBuilder attributes, ConsumerRecord < ? , ? > producerRecord) {
set(attributes, AttributeKey.stringKey("con_start"), "con1");
}
@Override
public void onEnd(AttributesBuilder attributes, ConsumerRecord < ? , ? > producerRecord, @Nullable Void unused, @Nullable Throwable error) {
set(attributes, AttributeKey.stringKey("con_end"), "con2");
}
}
//Extracts the attributes
public static void main(String[] args) throws Exception {
Map < String, Object > configs = new HashMap < > (Collections.singletonMap(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"));
System.setProperty("otel.traces.exporter", "jaeger");
System.setProperty("otel.service.name", "myapp1");
KafkaTracing tracing = KafkaTracing.newBuilder(GlobalOpenTelemetry.get())
.addProducerAttributesExtractors(new ProducerAttribExtractor())
.addConsumerAttributesExtractors(new ConsumerAttribExtractor())
.build();
9.3.7.2. OpenTracing のスパン名の指定 リンクのコピーリンクがクリップボードにコピーされました!
OpenTracing のカスタムスパン名を指定するには、プロデューサーとコンシューマーをインストルメント化するときに BiFunction オブジェクトを追加の引数として渡します。
組み込みの名前とカスタムスパン名を指定して、デコレーターパターンでクライアントアプリケーションコードをインストルメント化する方法の詳細は、OpenTracing Apache Kafka client instrumentation を参照してください。