Kafka Connect: Add otel tracing for kafka iceberg sink#17117
Draft
dttung2905 wants to merge 2 commits into
Draft
Kafka Connect: Add otel tracing for kafka iceberg sink#17117dttung2905 wants to merge 2 commits into
dttung2905 wants to merge 2 commits into
Conversation
Signed-off-by: dttung2905 <ttdao.2015@accountancy.smu.edu.sg>
Signed-off-by: dttung2905 <ttdao.2015@accountancy.smu.edu.sg>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This fixes : #17115
Adds optional OpenTelemetry distributed tracing to the Iceberg Kafka Connect sink. When enabled, the connector creates spans for the two main pipeline stages and continues upstream traces by extracting the W3C
traceparentheader from Kafka Connect record headers.Tracing is opt-in (
iceberg.tracing.enabled=falseby default), usesopentelemetry-apiascompileOnly, and degrades gracefully when the API is missing.Closes #<issue-number> (link your GitHub issue here)
Motivation
CDC pipelines commonly flow Source → Debezium → Kafka → Iceberg sink. Debezium already injects
traceparentinto record headers (ActivateTracingSpanSMT, debezium-connector-cassandra#173), but the Iceberg sink did not consume that context — traces broke at the sink boundary.This PR positions the Iceberg sink as the downstream consumer that continues distributed traces and exposes Iceberg-specific latency (ingest vs commit).
Architecture
sequenceDiagram participant Upstream as Upstream (Debezium / any traceparent injector) participant Kafka as Kafka Topic participant SW as SinkWriter participant CO as Coordinator Upstream->>Kafka: record + traceparent header Kafka->>SW: SinkRecord SW->>SW: extract traceparent from headers SW->>SW: span iceberg-sink-ingest (buffer) Note over SW,CO: default 5 min commit interval CO->>CO: span iceberg-sink-commit (durability) CO->>CO: Iceberg catalog commitSpans
iceberg-sink-ingestSinkRecord.headers()(traceparent)iceberg-sink-commitPackage layout
Tracingtracing.enabled && OTEL availablegate, one-time misconfiguration warningTracingUtilsKafkaConnectHeadersGetterTextMapGetter<Headers>for W3C context extraction from Connect headersInstrumentation points
SinkWriter.writeToTable()— ingest span after table routing is resolved (correctdb.table, supports static/dynamic routing)Coordinator.commit()— commit span wrappingdoCommit()CommitterImpl.initialize()— one-time warning if tracing enabled but API missingCaveats and limitations
Possible double spans with OTEL Java agent
If the Connect worker runs the OTEL Java agent with Kafka Connect
SinkTaskinstrumentation enabled, operators may see both:SinkTask.putspansiceberg-sink-ingestspansIngest span ≠ catalog durability
iceberg-sink-ingestends when the record is buffered to a file, not when it is committed to the Iceberg catalog. Do not use ingest span duration as end-to-end write latency.Commit spans are not linked to ingest spans
There is no span link or shared trace ID between a record's ingest span and the commit that makes it durable. Correlating them requires matching on
kafka.topic/kafka.offsetor future span-link work.Multi-table routing creates multiple ingest spans
When static routing sends one record to multiple tables, one
iceberg-sink-ingestspan is created per target table (sibling spans under the same upstream parent).Debezium envelope attributes are best-effort
opandts_msare extracted only when the record value is a ConnectStructwith those fields. Plain JSON/Avro records won't have them.isOpenTelemetryAvailable()means API on classpath, not export configuredGlobalOpenTelemetry.get()succeeds with a no-op tracer when only the API JAR is present. Actual trace export requires SDK + exporter or the OTEL Java agent on the worker JVM.Out of scope (this PR)
ConnectMetrics/ JMX registrationSpanKind.CONSUMER,messaging.destination.name) — usesINTERNAL+ custom attributes for Debezium compatibilityRelated work
TODO: