diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md
index cbd76ab1688..13f7b12e21d 100644
--- a/src/OpenTelemetry/CHANGELOG.md
+++ b/src/OpenTelemetry/CHANGELOG.md
@@ -11,6 +11,9 @@
null-valued tag.
([#3325](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3325))
+* `CompositeProcessor` will now ensure `ParentProvider` is set on its children
+ ([#3368](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3368))
+
## 1.3.0
Released 2022-Jun-03
diff --git a/src/OpenTelemetry/CompositeProcessor.cs b/src/OpenTelemetry/CompositeProcessor.cs
index 49c2258bd49..72eb166f074 100644
--- a/src/OpenTelemetry/CompositeProcessor.cs
+++ b/src/OpenTelemetry/CompositeProcessor.cs
@@ -79,6 +79,16 @@ public override void OnStart(T data)
}
}
+ internal override void SetParentProvider(BaseProvider parentProvider)
+ {
+ base.SetParentProvider(parentProvider);
+
+ for (var cur = this.head; cur != null; cur = cur.Next)
+ {
+ cur.Value.SetParentProvider(parentProvider);
+ }
+ }
+
///
protected override bool OnForceFlush(int timeoutMilliseconds)
{
diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs
index 0c33a7268a3..d4a7a2d15da 100644
--- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs
+++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs
@@ -128,11 +128,13 @@ internal OpenTelemetryLoggerProvider AddProcessor(BaseProcessor proce
}
else
{
- this.Processor = new CompositeProcessor(new[]
+ var newCompositeProcessor = new CompositeProcessor(new[]
{
this.Processor,
- processor,
});
+ newCompositeProcessor.SetParentProvider(this);
+ newCompositeProcessor.AddProcessor(processor);
+ this.Processor = newCompositeProcessor;
}
return this;
diff --git a/src/OpenTelemetry/Trace/TracerProviderSdk.cs b/src/OpenTelemetry/Trace/TracerProviderSdk.cs
index cd760e29548..88f4e15e2b9 100644
--- a/src/OpenTelemetry/Trace/TracerProviderSdk.cs
+++ b/src/OpenTelemetry/Trace/TracerProviderSdk.cs
@@ -277,11 +277,13 @@ internal TracerProviderSdk AddProcessor(BaseProcessor processor)
}
else
{
- this.processor = new CompositeProcessor(new[]
+ var newCompositeProcessor = new CompositeProcessor(new[]
{
this.processor,
- processor,
});
+ newCompositeProcessor.SetParentProvider(this);
+ newCompositeProcessor.AddProcessor(processor);
+ this.processor = newCompositeProcessor;
}
return this;
diff --git a/test/OpenTelemetry.Tests/Trace/CompositeActivityProcessorTests.cs b/test/OpenTelemetry.Tests/Trace/CompositeActivityProcessorTests.cs
index c73f212cab7..37522f89aac 100644
--- a/test/OpenTelemetry.Tests/Trace/CompositeActivityProcessorTests.cs
+++ b/test/OpenTelemetry.Tests/Trace/CompositeActivityProcessorTests.cs
@@ -99,5 +99,30 @@ public void CompositeActivityProcessor_ForceFlush(int timeout)
Assert.True(p1.ForceFlushCalled);
Assert.True(p2.ForceFlushCalled);
}
+
+ [Fact]
+ public void CompositeActivityProcessor_ForwardsParentProvider()
+ {
+ using TracerProvider provider = new TestProvider();
+
+ using var p1 = new TestActivityProcessor(null, null);
+ using var p2 = new TestActivityProcessor(null, null);
+
+ using var processor = new CompositeProcessor(new[] { p1, p2 });
+
+ Assert.Null(processor.ParentProvider);
+ Assert.Null(p1.ParentProvider);
+ Assert.Null(p2.ParentProvider);
+
+ processor.SetParentProvider(provider);
+
+ Assert.Equal(provider, processor.ParentProvider);
+ Assert.Equal(provider, p1.ParentProvider);
+ Assert.Equal(provider, p2.ParentProvider);
+ }
+
+ private sealed class TestProvider : TracerProvider
+ {
+ }
}
}
diff --git a/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs b/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs
index a18a24df015..59c1335bee4 100644
--- a/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs
+++ b/test/OpenTelemetry.Tests/Trace/TracerProviderSdkTest.cs
@@ -700,9 +700,11 @@ public void SdkProcessesLegacyActivityEvenAfterAddingNewProcessor()
// AddLegacyOperationName chained to TracerProviderBuilder
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
- .AddProcessor(testActivityProcessor)
- .AddLegacySource(operationNameForLegacyActivity)
- .Build();
+ .AddProcessor(testActivityProcessor)
+ .AddLegacySource(operationNameForLegacyActivity)
+ .Build();
+
+ Assert.Equal(tracerProvider, testActivityProcessor.ParentProvider);
Activity activity = new Activity(operationNameForLegacyActivity);
activity.Start();
@@ -736,6 +738,12 @@ public void SdkProcessesLegacyActivityEvenAfterAddingNewProcessor()
tracerProvider.AddProcessor(testActivityProcessorNew);
+ var sdkProvider = (TracerProviderSdk)tracerProvider;
+
+ Assert.True(sdkProvider.Processor is CompositeProcessor);
+ Assert.Equal(tracerProvider, sdkProvider.Processor.ParentProvider);
+ Assert.Equal(tracerProvider, testActivityProcessorNew.ParentProvider);
+
Activity activityNew = new Activity(operationNameForLegacyActivity); // Create a new Activity with the same operation name
activityNew.Start();
activityNew.Stop();