Skip to content

Update vendored ConfluentKafka instrumentation to 0.2.0-alpha.2 - #19319

Open
Sébastien Ros (sebastienros) wants to merge 3 commits into
mainfrom
sebros/update-kafka-otel-0-2
Open

Update vendored ConfluentKafka instrumentation to 0.2.0-alpha.2#19319
Sébastien Ros (sebastienros) wants to merge 3 commits into
mainfrom
sebros/update-kafka-otel-0-2

Conversation

@sebastienros

@sebastienros Sébastien Ros (sebastienros) commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Description

Updates the vendored OpenTelemetry.Instrumentation.ConfluentKafka source from 0.1.0-alpha.2 to 0.2.0-alpha.2. This brings Kafka telemetry onto the OpenTelemetry messaging semantic conventions v1.43, includes the 0.1.0-alpha.7 fix that records consumer metrics when ConsumeException is thrown, and incorporates the remaining 0.2 instrumentation changes.

The vendored fork keeps Aspire's internal visibility, explicit instrumentation name/version, AOT-compatible property fetcher, and analyzer exemptions. The vendoring instructions now document the updated pin and local adaptations.

Upstream changelog since 0.1.0-alpha.2

OpenTelemetry.Instrumentation.ConfluentKafka 0.1.0-alpha.3 through 0.2.0-alpha.2

0.2.0-alpha.2 (2026-Jul-17)

  • Updated OpenTelemetry core component version(s) to 1.17.0. (#4773)

0.2.0-alpha.1 (2026-Jul-08)

  • Updated OpenTelemetry core component version(s) to 1.16.0. (#4487)
  • Supported manual configuration of traces and metrics for Kafka consumers and producers created outside a DI container. (#4545)
  • Assemblies are now digitally signed using cosign. (#4637)
  • Breaking change: Updated the traces and metrics emitted by the Kafka producer and consumer to follow the v1.43.0 messaging semantic conventions. The producer send span (previously publish) and consumer poll span (previously receive, and now emitted with ActivityKind.Client) now set:
    • messaging.operation.name and messaging.operation.type (replacing messaging.operation)
    • messaging.client.id (replacing messaging.client_id)
    • messaging.consumer.group.name (replacing messaging.kafka.consumer.group)
    • messaging.destination.partition.id as a string (replacing messaging.kafka.destination.partition)
    • messaging.kafka.offset (replacing messaging.kafka.message.offset)
    • messaging.kafka.message.key is emitted as a string when the key has an unambiguous canonical representation; otherwise, the attribute is omitted.
    • Metrics were renamed to messaging.client.operation.duration, messaging.client.sent.messages, and messaging.client.consumed.messages.
    • error.type now reports the language-agnostic Kafka error code for Kafka errors (ProduceException/ConsumeException), or the exception type name for other failures. (#4636)
  • Metrics and traces now include a telemetry schema URL. (#4636)

0.1.0-alpha.7 (2026-May-29)

  • Fixed an issue in InstrumentedConsumer where messaging.receive.duration and messaging.receive.messages metrics were not emitted when ConsumeException is thrown by the Consume method. (#4433)

0.1.0-alpha.6 (2026-Apr-21)

  • Updated OpenTelemetry core component version(s) to 1.15.3. (#4166)

0.1.0-alpha.5 (2026-Jan-21)

  • Updated OpenTelemetry core component version(s) to 1.15.0. (#3721)

0.1.0-alpha.4 (2025-Nov-13)

  • Added support for .NET 10.0. (#2822)
  • Updated .NET 10.0 NuGet package versions from 10.0.0-rc.2.25502.107 to 10.0.0. (#3403)
  • Updated OpenTelemetry core component version(s) to 1.14.0. (#3403)

0.1.0-alpha.3 (2025-Oct-23)

  • Dropped support for .NET 6 and added a .NET Standard 2.0 target. (#2142)
  • Trace instrumentation now calls Activity.SetStatus instead of the deprecated OpenTelemetry API package extension when setting span status. (#2358)
  • The messaging.receive.duration and messaging.publish.duration histograms use the Advice API to set default explicit buckets following the OpenTelemetry specification. (#2430)
  • Rethrow exception on consume and process. (#2847)
  • Updated OpenTelemetry core component version(s) to 1.13.1. (#3218)

Breaking changes

Kafka telemetry consumers must update dashboards, alerts, and queries for these signal changes:

Previous signal New signal
Producer span: <topic> publish Producer span: send <topic>
Consumer span: <topic> receive (Consumer kind) Consumer span: poll <topic> (Client kind)
messaging.publish.duration / messaging.receive.duration messaging.client.operation.duration
messaging.publish.messages messaging.client.sent.messages
messaging.receive.messages messaging.client.consumed.messages
messaging.client_id messaging.client.id
messaging.kafka.consumer.group messaging.consumer.group.name
messaging.kafka.destination.partition messaging.destination.partition.id
messaging.kafka.message.offset messaging.kafka.offset

Aspire's opt-in legacy Aspire.Confluent.Kafka statistics meter now uses the same sent/consumed message metric names and client ID attribute as the vendored instrumentation.

Validation

  • MSBUILDTERMINALLOGGER=false dotnet build src/Components/Aspire.Confluent.Kafka/Aspire.Confluent.Kafka.csproj --no-restore --nologo
  • MSBUILDTERMINALLOGGER=false dotnet test --project tests/Aspire.Confluent.Kafka.Tests/Aspire.Confluent.Kafka.Tests.csproj --no-launch-profile -- --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true" (501 passed, 18 skipped across net8.0, net9.0, and net10.0)

Fixes # (issue)

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings August 12, 2026 23:08
@sebastienros Sébastien Ros (sebastienros) added the breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. label Aug 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 19319

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 19319"

@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates vendored Confluent Kafka instrumentation to 0.2.0-alpha.2 and OpenTelemetry messaging conventions v1.43.

Changes:

  • Updates Kafka spans, metrics, attributes, and exception telemetry.
  • Aligns Aspire’s legacy Kafka meter with renamed signals.
  • Updates tests, telemetry documentation, and vendoring instructions.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/Aspire.Confluent.Kafka.Tests/OtelTracesTests.cs Verifies renamed spans and kinds.
tests/Aspire.Confluent.Kafka.Tests/OtelMetricsTests.cs Verifies new metric names.
tests/Aspire.Confluent.Kafka.Tests/Aspire8MetricsTests.cs Updates legacy metric assertions.
src/Vendoring/README.md Updates the vendored version and adaptations.
src/Vendoring/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs Registers the producer activity source.
src/Vendoring/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs Registers the consumer activity source.
src/Vendoring/OpenTelemetry.Instrumentation.ConfluentKafka/Shared/SemanticConventions.cs Updates semantic-convention constants.
src/Vendoring/OpenTelemetry.Instrumentation.ConfluentKafka/Shared/Guard.cs Synchronizes validation helpers.
src/Vendoring/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs Updates process-span behavior.
src/Vendoring/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs Registers the producer meter.
src/Vendoring/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs Registers the consumer meter.
src/Vendoring/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs Updates producer telemetry.
src/Vendoring/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs Synchronizes consumer construction.
src/Vendoring/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumer.cs Updates consumer and exception telemetry.
src/Vendoring/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaInstrumentedProducerBuilderOptions.cs Adds producer builder options.
src/Vendoring/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaInstrumentedConsumerBuilderOptions.cs Adds consumer builder options.
src/Vendoring/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaCommon.cs Defines instrumentation identity and instruments.
src/Components/Telemetry.md Documents renamed Kafka metrics.
src/Components/Aspire.Confluent.Kafka/ConfluentKafkaMetrics.cs Renames legacy metrics and client tag.

Comment thread src/Components/Aspire.Confluent.Kafka/ConfluentKafkaMetrics.cs
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 908e2f89-e34c-451e-bb4e-d239dd7b566c
Copilot AI review requested due to automatic review settings August 13, 2026 00:15
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/Components/Aspire.Confluent.Kafka/ConfluentKafkaMetrics.cs:59

  • These names do not match the underlying librdkafka statistics. txmsgs/rxmsgs count messages transmitted to or consumed from brokers, while the v1.43 metrics represent producer send attempts and deliveries to the application. Queued or failed sends and prefetched-but-undelivered records therefore make this legacy meter disagree with the vendored meter for the same metric names. Keep the statistics under custom names, or emit these semantic-convention counters from the producer/consumer operation paths instead.
        public const string TxMessages = "messaging.client.sent.messages";
        public const string TxMessageBytes = "messaging.kafka.message.transmitted";
        public const string RxMessages = "messaging.client.consumed.messages";

tests/Aspire.Confluent.Kafka.Tests/OtelInstrumentationTests.cs:15

  • This new class can run in parallel with OtelTracesTests and OtelMetricsTests, although all three attach exporters to the same static Kafka ActivitySource/Meter. Telemetry emitted here can consequently enter another test's exporter (and its unsynchronized List), causing count assertions such as Assert.Equal(5, activities.Count) to fail nondeterministically. Put all Kafka telemetry tests in one serialized collection or otherwise disable parallel execution between them.
public class OtelInstrumentationTests

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

Comment thread src/Components/Aspire.Confluent.Kafka/MetricsService.cs Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 908e2f89-e34c-451e-bb4e-d239dd7b566c
@github-actions

Copy link
Copy Markdown
Contributor

Tests selector (audit mode)

The full test matrix and all jobs still run in audit mode. The tests and jobs below are what selective CI would run under enforcement.

10 / 102 test projects · 3 jobs, from 22 changed files.

Selected test projects (10 / 102)

Aspire.Cli.EndToEnd.Tests, Aspire.Confluent.Kafka.Tests, Aspire.Dashboard.Components.Tests, Aspire.Dashboard.Tests, Aspire.Hosting.DotnetTool.Tests, Aspire.Hosting.Kafka.Tests, Aspire.Hosting.RemoteHost.Tests, Aspire.Hosting.Testing.Tests, Aspire.Managed.Tests, Aspire.Playground.Tests

Selected jobs (3)

deployment-e2e, extension-e2e, polyglot


How these were chosen — grouped by what changed

⚠️ 6 of the 10 selected test projects come from a single change — src/Aspire.Dashboard/Otlp/Model/OtlpSpan.cs.

🔧 src/Aspire.Dashboard/Otlp/Model/OtlpSpan.cs (changed source)
6 via the project graph: Aspire.Dashboard.Components.Tests, Aspire.Hosting.DotnetTool.Tests (2 hops), Aspire.Hosting.RemoteHost.Tests (2 hops), Aspire.Hosting.Testing.Tests, Aspire.Managed.Tests (2 hops), Aspire.Playground.Tests (2 hops)

🔧 src/Components/Aspire.Confluent.Kafka/AssemblyInfo.cs (changed source)
1 directly: Aspire.Confluent.Kafka.Tests
1 via the project graph: Aspire.Hosting.Kafka.Tests

📦 affected project Aspire.Managed
1 test: Aspire.Cli.EndToEnd.Tests

🔧 src/Components/Aspire.Confluent.Kafka/ConfluentKafkaMetrics.cs (changed source)
1 directly: Aspire.Confluent.Kafka.Tests

🔧 src/Components/Aspire.Confluent.Kafka/MetricsService.cs (changed source)
1 directly: Aspire.Confluent.Kafka.Tests

🧪 tests/Aspire.Confluent.Kafka.Tests/Aspire8MetricsTests.cs (changed test)
1 directly: Aspire.Confluent.Kafka.Tests

🧪 tests/Aspire.Confluent.Kafka.Tests/OtelInstrumentationTests.cs (changed test)
1 directly: Aspire.Confluent.Kafka.Tests

🧪 tests/Aspire.Confluent.Kafka.Tests/OtelMetricsTests.cs (changed test)
1 directly: Aspire.Confluent.Kafka.Tests

🧪 tests/Aspire.Confluent.Kafka.Tests/OtelTracesTests.cs (changed test)
1 directly: Aspire.Confluent.Kafka.Tests

🧪 tests/Aspire.Confluent.Kafka.Tests/TestServices/FakeKafkaConsumer.cs (changed test)
1 directly: Aspire.Confluent.Kafka.Tests

🧪 tests/Aspire.Dashboard.Tests/Model/SpanWaterfallViewModelTests.cs (changed test)
1 directly: Aspire.Dashboard.Tests

🧪 tests/Aspire.Dashboard.Tests/TelemetryRepositoryTests/OtlpSpanTests.cs (changed test)
1 directly: Aspire.Dashboard.Tests

Job reasons

Job Triggered by
deployment-e2e affected project Aspire.Managed
extension-e2e src/Aspire.Dashboard/Otlp/Model/OtlpSpan.cs
• affected project Aspire.Dashboard
polyglot affected project Aspire.Managed

Selection computed for commit 5084334.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated no new comments.

@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@adamint Adam Ratzman (adamint) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you take a look at these? I think they need to be fixed before merging.

}
=> this.consumer.Close();

private static bool ShouldInstrument(ConsumeResult<TKey, TValue>? result, string? errorType) =>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we record messaging.client.operation.duration for every completed poll here? This still skips timeout/null and partition-EOF results, so the new operation metric only measures polls that returned a message (or threw ConsumeException). I think the message counter can stay gated, but the operation duration should include empty polls too.

}

Assert.Equal(5, activities.Where(x => x.OperationName == $"{topic} publish").Count());
Assert.Equal(5, activities.Count);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we filter these activities to this test's unique topic before asserting? OtelInstrumentationTests subscribes to the same process-wide ActivitySource outside the Kafka collection, so it can run concurrently and add activities to this exporter. The old operation-name filter avoided that contamination; this exact global count will be flaky.

var metricNames = metrics
.Where(x => x.MeterName == "OpenTelemetry.Instrumentation.ConfluentKafka")
.Select(x => x.Name)
.Distinct()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we assert the send and poll duration points separately instead of reducing this to distinct metric names? Both operations use messaging.client.operation.duration now, so producer emission alone makes this pass if consumer duration recording disappears.

@martincostello

Copy link
Copy Markdown
Contributor

FYI we shipped 0.3.0-alpha.1 last week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-integrations Issues pertaining to Aspire Integrations packages breaking-change Issue or PR that represents a breaking API or functional change over a prerelease.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants