Skip to content

Commit

Permalink
Showing 5 changed files with 71 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ public static IServiceCollection AddOpenTelemetryTracerProviderBuilderServices(t
services.AddOpenTelemetryProviderBuilderServices();

services.RegisterOptionsFactory(configuration => new ExportActivityProcessorOptions(configuration));
services.TryAddSingleton<TracerProviderBuilderState>();

return services;
}
7 changes: 5 additions & 2 deletions src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs
Original file line number Diff line number Diff line change
@@ -45,8 +45,9 @@ internal TracerProviderBuilderBase(TracerProviderBuilderState state)
this.State = state;
}

// This ctor is for AddOpenTelemetryTracing scenario where the builder
// is bound to an external service collection.
// This ctor is for ConfigureOpenTelemetryTracing +
// AddOpenTelemetryTracing scenarios where the builder is bound to an
// external service collection.
internal TracerProviderBuilderBase(IServiceCollection services)
{
Guard.ThrowIfNull(services);
@@ -65,6 +66,8 @@ protected TracerProviderBuilderBase()
var services = new ServiceCollection();

services.AddOpenTelemetryTracerProviderBuilderServices();
services.AddSingleton<TracerProvider>(
sp => throw new NotSupportedException("External TracerProvider created through Sdk.CreateTracerProviderBuilder cannot be accessed using service provider."));

this.services = services;
this.ownsServices = true;
11 changes: 11 additions & 0 deletions src/OpenTelemetry/Trace/Builder/TracerProviderBuilderState.cs
Original file line number Diff line number Diff line change
@@ -38,6 +38,7 @@ internal sealed class TracerProviderBuilderState
internal Sampler? Sampler;
internal bool SetErrorStatusOnException;

private bool hasEnteredBuildPhase;
private TracerProviderBuilderSdk? builder;

public TracerProviderBuilderState(IServiceProvider serviceProvider)
@@ -49,6 +50,16 @@ public TracerProviderBuilderState(IServiceProvider serviceProvider)

public TracerProviderBuilderSdk Builder => this.builder ??= new TracerProviderBuilderSdk(this);

public void CheckForCircularBuild()
{
if (this.hasEnteredBuildPhase)
{
throw new NotSupportedException("TracerProvider cannot be accessed while build is executing.");
}

this.hasEnteredBuildPhase = true;
}

public void AddInstrumentation(
string instrumentationName,
string instrumentationVersion,
6 changes: 4 additions & 2 deletions src/OpenTelemetry/Trace/TracerProviderSdk.cs
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry.Internal;
using OpenTelemetry.Resources;

@@ -47,6 +48,9 @@ internal TracerProviderSdk(
{
Debug.Assert(serviceProvider != null, "serviceProvider was null");

var state = serviceProvider!.GetRequiredService<TracerProviderBuilderState>();
state.CheckForCircularBuild();

this.ServiceProvider = serviceProvider!;

if (ownsServiceProvider)
@@ -57,8 +61,6 @@ internal TracerProviderSdk(

OpenTelemetrySdkEventSource.Log.TracerProviderSdkEvent("Building TracerProvider.");

var state = new TracerProviderBuilderState(serviceProvider!);

TracerProviderBuilderServiceCollectionHelper.InvokeRegisteredConfigureStateCallbacks(
serviceProvider!,
state);
Original file line number Diff line number Diff line change
@@ -455,6 +455,56 @@ public void ConfigureBuilderIConfigurationModifiableTest()
Assert.True(configureBuilderCalled);
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void TracerProviderNestedResolutionUsingBuilderTest(bool callNestedConfigure)
{
bool innerTestExecuted = false;

using var provider = Sdk.CreateTracerProviderBuilder()
.ConfigureServices(services =>
{
if (callNestedConfigure)
{
services.ConfigureOpenTelemetryTracing();
}
})
.ConfigureBuilder((sp, builder) =>
{
innerTestExecuted = true;
Assert.Throws<NotSupportedException>(() => sp.GetService<TracerProvider>());
})
.Build();

Assert.True(innerTestExecuted);

Assert.Throws<NotSupportedException>(() => provider.GetServiceProvider()?.GetService<TracerProvider>());
}

[Fact]
public void TracerProviderNestedResolutionUsingConfigureTest()
{
bool innerTestExecuted = false;

var serviceCollection = new ServiceCollection();

serviceCollection.ConfigureOpenTelemetryTracing(builder =>
{
builder.ConfigureBuilder((sp, builder) =>
{
innerTestExecuted = true;
Assert.Throws<NotSupportedException>(() => sp.GetService<TracerProvider>());
});
});

using var serviceProvider = serviceCollection.BuildServiceProvider();

var resolvedProvider = serviceProvider.GetRequiredService<TracerProvider>();

Assert.True(innerTestExecuted);
}

private static void RunBuilderServiceLifecycleTest(
TracerProviderBuilder builder,
Func<TracerProviderSdk> buildFunc,

0 comments on commit 9b8702e

Please sign in to comment.