diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 3b0283f1f15..eb7319f9db7 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -11,6 +11,10 @@ Notes](../../RELEASENOTES.md). buffer estimate. Such content is now truncated. ([#7543](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7543)) +* Fixed activity creation throwing when multiple tracer providers return a + sampler attribute with the same key. + ([#7558](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7558)) + ## 1.17.0 Released 2026-Jul-16 diff --git a/src/OpenTelemetry/Trace/TracerProviderSdk.cs b/src/OpenTelemetry/Trace/TracerProviderSdk.cs index a59b23d9519..7c609b28b5b 100644 --- a/src/OpenTelemetry/Trace/TracerProviderSdk.cs +++ b/src/OpenTelemetry/Trace/TracerProviderSdk.cs @@ -492,7 +492,7 @@ private static ActivitySamplingResult ComputeActivitySamplingResult( { foreach (var att in attributes) { - options.SamplingTags.Add(att.Key, att.Value); + options.SamplingTags[att.Key] = att.Value; } } } diff --git a/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTests.cs b/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTests.cs index e80672fc86f..9f17b80a02c 100644 --- a/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTests.cs +++ b/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTests.cs @@ -250,6 +250,40 @@ public void TracerProviderSdkSamplerAttributesAreAppliedToActivity(SamplingDecis } } + [Fact] + public void TracerProviderSdkDuplicateSamplerAttributesUseLastValue() + { + const string attributeKey = "duplicate-sampler-attribute"; + var firstSampler = new TestSampler + { + SamplingAction = _ => new SamplingResult( + SamplingDecision.RecordAndSample, + [new(attributeKey, "first")]), + }; + var secondSampler = new TestSampler + { + SamplingAction = _ => new SamplingResult( + SamplingDecision.RecordAndSample, + [new(attributeKey, "second")]), + }; + + var activitySourceName = Utils.GetCurrentMethodName(); + using var activitySource = new ActivitySource(activitySourceName); + using var firstProvider = Sdk.CreateTracerProviderBuilder() + .AddSource(activitySourceName) + .SetSampler(firstSampler) + .Build(); + using var secondProvider = Sdk.CreateTracerProviderBuilder() + .AddSource(activitySourceName) + .SetSampler(secondSampler) + .Build(); + + using var activity = activitySource.StartActivity("root"); + + Assert.NotNull(activity); + Assert.Equal("second", activity.GetTagItem(attributeKey)); + } + [Fact] public void TracerSdkSetsActivitySamplingResultAsPropagationWhenParentIsRemote() {