[di] Expose a detached TracerProviderBuilder extension on IServiceCollection which may modify services. (#4508)
This commit is contained in:
parent
eb12f9b386
commit
107dd264c2
|
|
@ -0,0 +1 @@
|
||||||
|
static OpenTelemetry.Trace.OpenTelemetryDependencyInjectionTracingServiceCollectionExtensions.ConfigureOpenTelemetryTracerProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<OpenTelemetry.Trace.TracerProviderBuilder!>! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
static OpenTelemetry.Trace.OpenTelemetryDependencyInjectionTracingServiceCollectionExtensions.ConfigureOpenTelemetryTracerProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<OpenTelemetry.Trace.TracerProviderBuilder!>! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
|
||||||
|
|
@ -8,6 +8,12 @@
|
||||||
`TracerProvider`.
|
`TracerProvider`.
|
||||||
([#4468](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4468))
|
([#4468](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4468))
|
||||||
|
|
||||||
|
* Added an `IServiceCollection.ConfigureOpenTelemetryTracerProvider` overload
|
||||||
|
which may be used to configure `TracerProviderBuilder`s while the
|
||||||
|
`IServiceCollection` is modifiable (before the `IServiceProvider` has been
|
||||||
|
created).
|
||||||
|
([#4508](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4508))
|
||||||
|
|
||||||
## 1.5.0-alpha.2
|
## 1.5.0-alpha.2
|
||||||
|
|
||||||
Released 2023-Mar-31
|
Released 2023-Mar-31
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,7 @@ public static class OpenTelemetryDependencyInjectionTracingServiceCollectionExte
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers an action used to configure the OpenTelemetry <see
|
/// Registers an action used to configure the OpenTelemetry <see
|
||||||
/// cref="TracerProviderBuilder"/> used to create the <see
|
/// cref="TracerProviderBuilder"/>.
|
||||||
/// cref="TracerProvider"/> for the <see cref="IServiceCollection"/> being
|
|
||||||
/// configured.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Notes:
|
/// Notes:
|
||||||
|
|
@ -36,14 +34,53 @@ public static class OpenTelemetryDependencyInjectionTracingServiceCollectionExte
|
||||||
/// <item>This is safe to be called multiple times and by library authors.
|
/// <item>This is safe to be called multiple times and by library authors.
|
||||||
/// Each registered configuration action will be applied
|
/// Each registered configuration action will be applied
|
||||||
/// sequentially.</item>
|
/// sequentially.</item>
|
||||||
/// <item>A <see cref="TracerProvider"/> will not be created automatically
|
/// <item>A <see cref="TracerProvider"/> will NOT be created automatically
|
||||||
/// using this method. To begin collecting metrics use the
|
/// using this method. To begin collecting traces use the
|
||||||
/// <c>IServiceCollection.AddOpenTelemetry</c> extension in the
|
/// <c>IServiceCollection.AddOpenTelemetry</c> extension in the
|
||||||
/// <c>OpenTelemetry.Extensions.Hosting</c> package.</item>
|
/// <c>OpenTelemetry.Extensions.Hosting</c> package.</item>
|
||||||
/// </list>
|
/// </list>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="services">The <see cref="IServiceCollection" /> to add
|
/// <param name="services"><see cref="IServiceCollection" />.</param>
|
||||||
/// services to.</param>
|
/// <param name="configure">Callback action to configure the <see
|
||||||
|
/// cref="TracerProviderBuilder"/>.</param>
|
||||||
|
/// <returns>The <see cref="IServiceCollection"/> so that additional calls
|
||||||
|
/// can be chained.</returns>
|
||||||
|
public static IServiceCollection ConfigureOpenTelemetryTracerProvider(
|
||||||
|
this IServiceCollection services,
|
||||||
|
Action<TracerProviderBuilder> configure)
|
||||||
|
{
|
||||||
|
Guard.ThrowIfNull(services);
|
||||||
|
Guard.ThrowIfNull(configure);
|
||||||
|
|
||||||
|
configure(new TracerProviderServiceCollectionBuilder(services));
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers an action used to configure the OpenTelemetry <see
|
||||||
|
/// cref="TracerProviderBuilder"/> once the <see cref="IServiceProvider"/>
|
||||||
|
/// is available.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Notes:
|
||||||
|
/// <list type="bullet">
|
||||||
|
/// <item>This is safe to be called multiple times and by library authors.
|
||||||
|
/// Each registered configuration action will be applied
|
||||||
|
/// sequentially.</item>
|
||||||
|
/// <item>A <see cref="TracerProvider"/> will NOT be created automatically
|
||||||
|
/// using this method. To begin collecting traces use the
|
||||||
|
/// <c>IServiceCollection.AddOpenTelemetry</c> extension in the
|
||||||
|
/// <c>OpenTelemetry.Extensions.Hosting</c> package.</item>
|
||||||
|
/// <item>The supplied configuration delegate is called once the <see
|
||||||
|
/// cref="IServiceProvider"/> is available. Services may NOT be added to a
|
||||||
|
/// <see cref="TracerProviderBuilder"/> once the <see
|
||||||
|
/// cref="IServiceProvider"/> has been created. Many helper extensions
|
||||||
|
/// register services and may throw if invoked inside the configuration
|
||||||
|
/// delegate.</item>
|
||||||
|
/// </list>
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="services"><see cref="IServiceCollection" />.</param>
|
||||||
/// <param name="configure">Callback action to configure the <see
|
/// <param name="configure">Callback action to configure the <see
|
||||||
/// cref="TracerProviderBuilder"/>.</param>
|
/// cref="TracerProviderBuilder"/>.</param>
|
||||||
/// <returns>The <see cref="IServiceCollection"/> so that additional calls
|
/// <returns>The <see cref="IServiceCollection"/> so that additional calls
|
||||||
|
|
@ -51,19 +88,14 @@ public static class OpenTelemetryDependencyInjectionTracingServiceCollectionExte
|
||||||
public static IServiceCollection ConfigureOpenTelemetryTracerProvider(
|
public static IServiceCollection ConfigureOpenTelemetryTracerProvider(
|
||||||
this IServiceCollection services,
|
this IServiceCollection services,
|
||||||
Action<IServiceProvider, TracerProviderBuilder> configure)
|
Action<IServiceProvider, TracerProviderBuilder> configure)
|
||||||
{
|
|
||||||
RegisterBuildAction(services, configure);
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RegisterBuildAction(IServiceCollection services, Action<IServiceProvider, TracerProviderBuilder> configure)
|
|
||||||
{
|
{
|
||||||
Guard.ThrowIfNull(services);
|
Guard.ThrowIfNull(services);
|
||||||
Guard.ThrowIfNull(configure);
|
Guard.ThrowIfNull(configure);
|
||||||
|
|
||||||
services.AddSingleton<IConfigureTracerProviderBuilder>(
|
services.AddSingleton<IConfigureTracerProviderBuilder>(
|
||||||
new ConfigureTracerProviderBuilderCallbackWrapper(configure));
|
new ConfigureTracerProviderBuilderCallbackWrapper(configure));
|
||||||
|
|
||||||
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class ConfigureTracerProviderBuilderCallbackWrapper : IConfigureTracerProviderBuilder
|
private sealed class ConfigureTracerProviderBuilderCallbackWrapper : IConfigureTracerProviderBuilder
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
// <copyright file="TracerProviderServiceCollectionBuilder.cs" company="OpenTelemetry Authors">
|
||||||
|
// Copyright The OpenTelemetry Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
// </copyright>
|
||||||
|
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using OpenTelemetry.Internal;
|
||||||
|
|
||||||
|
namespace OpenTelemetry.Trace;
|
||||||
|
|
||||||
|
internal sealed class TracerProviderServiceCollectionBuilder : TracerProviderBuilder, ITracerProviderBuilder
|
||||||
|
{
|
||||||
|
public TracerProviderServiceCollectionBuilder(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.ConfigureOpenTelemetryTracerProvider((sp, builder) => this.Services = null);
|
||||||
|
|
||||||
|
this.Services = services;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IServiceCollection? Services { get; set; }
|
||||||
|
|
||||||
|
public TracerProvider? Provider => null;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override TracerProviderBuilder AddInstrumentation<TInstrumentation>(Func<TInstrumentation> instrumentationFactory)
|
||||||
|
{
|
||||||
|
Guard.ThrowIfNull(instrumentationFactory);
|
||||||
|
|
||||||
|
this.ConfigureBuilderInternal((sp, builder) =>
|
||||||
|
{
|
||||||
|
builder.AddInstrumentation(instrumentationFactory);
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override TracerProviderBuilder AddSource(params string[] names)
|
||||||
|
{
|
||||||
|
Guard.ThrowIfNull(names);
|
||||||
|
|
||||||
|
this.ConfigureBuilderInternal((sp, builder) =>
|
||||||
|
{
|
||||||
|
builder.AddSource(names);
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override TracerProviderBuilder AddLegacySource(string operationName)
|
||||||
|
{
|
||||||
|
Guard.ThrowIfNullOrWhitespace(operationName);
|
||||||
|
|
||||||
|
this.ConfigureBuilderInternal((sp, builder) =>
|
||||||
|
{
|
||||||
|
builder.AddLegacySource(operationName);
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public TracerProviderBuilder ConfigureServices(Action<IServiceCollection> configure)
|
||||||
|
=> this.ConfigureServicesInternal(configure);
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IDeferredTracerProviderBuilder.Configure" />
|
||||||
|
public TracerProviderBuilder ConfigureBuilder(Action<IServiceProvider, TracerProviderBuilder> configure)
|
||||||
|
=> this.ConfigureBuilderInternal(configure);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
TracerProviderBuilder IDeferredTracerProviderBuilder.Configure(Action<IServiceProvider, TracerProviderBuilder> configure)
|
||||||
|
=> this.ConfigureBuilderInternal(configure);
|
||||||
|
|
||||||
|
private TracerProviderBuilder ConfigureBuilderInternal(Action<IServiceProvider, TracerProviderBuilder> configure)
|
||||||
|
{
|
||||||
|
var services = this.Services
|
||||||
|
?? throw new NotSupportedException("Builder cannot be configured during TracerProvider construction.");
|
||||||
|
|
||||||
|
services.ConfigureOpenTelemetryTracerProvider(configure);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TracerProviderBuilder ConfigureServicesInternal(Action<IServiceCollection> configure)
|
||||||
|
{
|
||||||
|
Guard.ThrowIfNull(configure);
|
||||||
|
|
||||||
|
var services = this.Services
|
||||||
|
?? throw new NotSupportedException("Services cannot be configured during TracerProvider construction.");
|
||||||
|
|
||||||
|
configure(services);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -28,7 +28,7 @@ namespace OpenTelemetry.Trace;
|
||||||
public class TracerProviderBuilderBase : TracerProviderBuilder, ITracerProviderBuilder
|
public class TracerProviderBuilderBase : TracerProviderBuilder, ITracerProviderBuilder
|
||||||
{
|
{
|
||||||
private readonly bool allowBuild;
|
private readonly bool allowBuild;
|
||||||
private IServiceCollection? services;
|
private readonly TracerProviderServiceCollectionBuilder innerBuilder;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="TracerProviderBuilderBase"/> class.
|
/// Initializes a new instance of the <see cref="TracerProviderBuilderBase"/> class.
|
||||||
|
|
@ -43,9 +43,7 @@ public class TracerProviderBuilderBase : TracerProviderBuilder, ITracerProviderB
|
||||||
.TryAddSingleton<TracerProvider>(
|
.TryAddSingleton<TracerProvider>(
|
||||||
sp => throw new NotSupportedException("Self-contained TracerProvider cannot be accessed using the application IServiceProvider call Build instead."));
|
sp => throw new NotSupportedException("Self-contained TracerProvider cannot be accessed using the application IServiceProvider call Build instead."));
|
||||||
|
|
||||||
services.ConfigureOpenTelemetryTracerProvider((sp, builder) => this.services = null);
|
this.innerBuilder = new TracerProviderServiceCollectionBuilder(services);
|
||||||
|
|
||||||
this.services = services;
|
|
||||||
|
|
||||||
this.allowBuild = true;
|
this.allowBuild = true;
|
||||||
}
|
}
|
||||||
|
|
@ -58,9 +56,7 @@ public class TracerProviderBuilderBase : TracerProviderBuilder, ITracerProviderB
|
||||||
.AddOpenTelemetryTracerProviderBuilderServices()
|
.AddOpenTelemetryTracerProviderBuilderServices()
|
||||||
.TryAddSingleton<TracerProvider>(sp => new TracerProviderSdk(sp, ownsServiceProvider: false));
|
.TryAddSingleton<TracerProvider>(sp => new TracerProviderSdk(sp, ownsServiceProvider: false));
|
||||||
|
|
||||||
services.ConfigureOpenTelemetryTracerProvider((sp, builder) => this.services = null);
|
this.innerBuilder = new TracerProviderServiceCollectionBuilder(services);
|
||||||
|
|
||||||
this.services = services;
|
|
||||||
|
|
||||||
this.allowBuild = false;
|
this.allowBuild = false;
|
||||||
}
|
}
|
||||||
|
|
@ -71,12 +67,7 @@ public class TracerProviderBuilderBase : TracerProviderBuilder, ITracerProviderB
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override TracerProviderBuilder AddInstrumentation<TInstrumentation>(Func<TInstrumentation> instrumentationFactory)
|
public override TracerProviderBuilder AddInstrumentation<TInstrumentation>(Func<TInstrumentation> instrumentationFactory)
|
||||||
{
|
{
|
||||||
Guard.ThrowIfNull(instrumentationFactory);
|
this.innerBuilder.AddInstrumentation(instrumentationFactory);
|
||||||
|
|
||||||
this.ConfigureBuilderInternal((sp, builder) =>
|
|
||||||
{
|
|
||||||
builder.AddInstrumentation(instrumentationFactory);
|
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -84,12 +75,7 @@ public class TracerProviderBuilderBase : TracerProviderBuilder, ITracerProviderB
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override TracerProviderBuilder AddSource(params string[] names)
|
public override TracerProviderBuilder AddSource(params string[] names)
|
||||||
{
|
{
|
||||||
Guard.ThrowIfNull(names);
|
this.innerBuilder.AddSource(names);
|
||||||
|
|
||||||
this.ConfigureBuilderInternal((sp, builder) =>
|
|
||||||
{
|
|
||||||
builder.AddSource(names);
|
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -97,23 +83,18 @@ public class TracerProviderBuilderBase : TracerProviderBuilder, ITracerProviderB
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override TracerProviderBuilder AddLegacySource(string operationName)
|
public override TracerProviderBuilder AddLegacySource(string operationName)
|
||||||
{
|
{
|
||||||
Guard.ThrowIfNullOrWhitespace(operationName);
|
this.innerBuilder.AddLegacySource(operationName);
|
||||||
|
|
||||||
this.ConfigureBuilderInternal((sp, builder) =>
|
|
||||||
{
|
|
||||||
builder.AddLegacySource(operationName);
|
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
TracerProviderBuilder ITracerProviderBuilder.ConfigureServices(Action<IServiceCollection> configure)
|
TracerProviderBuilder ITracerProviderBuilder.ConfigureServices(Action<IServiceCollection> configure)
|
||||||
=> this.ConfigureServicesInternal(configure);
|
=> this.innerBuilder.ConfigureServices(configure);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
TracerProviderBuilder IDeferredTracerProviderBuilder.Configure(Action<IServiceProvider, TracerProviderBuilder> configure)
|
TracerProviderBuilder IDeferredTracerProviderBuilder.Configure(Action<IServiceProvider, TracerProviderBuilder> configure)
|
||||||
=> this.ConfigureBuilderInternal(configure);
|
=> this.innerBuilder.ConfigureBuilder(configure);
|
||||||
|
|
||||||
internal TracerProvider InvokeBuild()
|
internal TracerProvider InvokeBuild()
|
||||||
=> this.Build();
|
=> this.Build();
|
||||||
|
|
@ -134,7 +115,7 @@ public class TracerProviderBuilderBase : TracerProviderBuilder, ITracerProviderB
|
||||||
Guard.ThrowIfNullOrWhitespace(instrumentationVersion);
|
Guard.ThrowIfNullOrWhitespace(instrumentationVersion);
|
||||||
Guard.ThrowIfNull(instrumentationFactory);
|
Guard.ThrowIfNull(instrumentationFactory);
|
||||||
|
|
||||||
return this.ConfigureBuilderInternal((sp, builder) =>
|
return this.innerBuilder.ConfigureBuilder((sp, builder) =>
|
||||||
{
|
{
|
||||||
if (builder is TracerProviderBuilderSdk tracerProviderBuilderState)
|
if (builder is TracerProviderBuilderSdk tracerProviderBuilderState)
|
||||||
{
|
{
|
||||||
|
|
@ -157,14 +138,14 @@ public class TracerProviderBuilderBase : TracerProviderBuilder, ITracerProviderB
|
||||||
throw new NotSupportedException("A TracerProviderBuilder bound to external service cannot be built directly. Access the TracerProvider using the application IServiceProvider instead.");
|
throw new NotSupportedException("A TracerProviderBuilder bound to external service cannot be built directly. Access the TracerProvider using the application IServiceProvider instead.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var services = this.services;
|
var services = this.innerBuilder.Services;
|
||||||
|
|
||||||
if (services == null)
|
if (services == null)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException("TracerProviderBuilder build method cannot be called multiple times.");
|
throw new NotSupportedException("TracerProviderBuilder build method cannot be called multiple times.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.services = null;
|
this.innerBuilder.Services = null;
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
bool validateScopes = true;
|
bool validateScopes = true;
|
||||||
|
|
@ -175,34 +156,4 @@ public class TracerProviderBuilderBase : TracerProviderBuilder, ITracerProviderB
|
||||||
|
|
||||||
return new TracerProviderSdk(serviceProvider, ownsServiceProvider: true);
|
return new TracerProviderSdk(serviceProvider, ownsServiceProvider: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TracerProviderBuilder ConfigureBuilderInternal(Action<IServiceProvider, TracerProviderBuilder> configure)
|
|
||||||
{
|
|
||||||
var services = this.services;
|
|
||||||
|
|
||||||
if (services == null)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException("Builder cannot be configured during TracerProvider construction.");
|
|
||||||
}
|
|
||||||
|
|
||||||
services.ConfigureOpenTelemetryTracerProvider(configure);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TracerProviderBuilder ConfigureServicesInternal(Action<IServiceCollection> configure)
|
|
||||||
{
|
|
||||||
Guard.ThrowIfNull(configure);
|
|
||||||
|
|
||||||
var services = this.services;
|
|
||||||
|
|
||||||
if (services == null)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException("Services cannot be configured during TracerProvider construction.");
|
|
||||||
}
|
|
||||||
|
|
||||||
configure(services);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,26 +30,33 @@ public class ServiceCollectionExtensionsTests
|
||||||
[InlineData(3)]
|
[InlineData(3)]
|
||||||
public void ConfigureOpenTelemetryTracerProvider(int numberOfCalls)
|
public void ConfigureOpenTelemetryTracerProvider(int numberOfCalls)
|
||||||
{
|
{
|
||||||
var invocations = 0;
|
var beforeServiceProviderInvocations = 0;
|
||||||
|
var afterServiceProviderInvocations = 0;
|
||||||
|
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
|
|
||||||
for (int i = 0; i < numberOfCalls; i++)
|
for (int i = 0; i < numberOfCalls; i++)
|
||||||
{
|
{
|
||||||
services.ConfigureOpenTelemetryTracerProvider((sp, builder) => invocations++);
|
services.ConfigureOpenTelemetryTracerProvider(builder => beforeServiceProviderInvocations++);
|
||||||
|
services.ConfigureOpenTelemetryTracerProvider((sp, builder) => afterServiceProviderInvocations++);
|
||||||
}
|
}
|
||||||
|
|
||||||
using var serviceProvider = services.BuildServiceProvider();
|
using var serviceProvider = services.BuildServiceProvider();
|
||||||
|
|
||||||
var registrations = serviceProvider.GetServices<IConfigureTracerProviderBuilder>();
|
var registrations = serviceProvider.GetServices<IConfigureTracerProviderBuilder>();
|
||||||
|
|
||||||
|
Assert.Equal(numberOfCalls, beforeServiceProviderInvocations);
|
||||||
|
Assert.Equal(0, afterServiceProviderInvocations);
|
||||||
|
|
||||||
foreach (var registration in registrations)
|
foreach (var registration in registrations)
|
||||||
{
|
{
|
||||||
registration.ConfigureBuilder(serviceProvider, null!);
|
registration.ConfigureBuilder(serviceProvider, null!);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.Equal(invocations, registrations.Count());
|
Assert.Equal(numberOfCalls, beforeServiceProviderInvocations);
|
||||||
Assert.Equal(numberOfCalls, registrations.Count());
|
Assert.Equal(numberOfCalls, afterServiceProviderInvocations);
|
||||||
|
|
||||||
|
Assert.Equal(numberOfCalls * 2, registrations.Count());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -107,4 +114,8 @@ public class ServiceCollectionExtensionsTests
|
||||||
Assert.Equal(invocations, registrations.Count());
|
Assert.Equal(invocations, registrations.Count());
|
||||||
Assert.Equal(numberOfCalls, registrations.Count());
|
Assert.Equal(numberOfCalls, registrations.Count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private sealed class CustomType
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -311,6 +311,7 @@ namespace OpenTelemetry.Trace.Tests
|
||||||
{
|
{
|
||||||
bool innerConfigureBuilderTestExecuted = false;
|
bool innerConfigureBuilderTestExecuted = false;
|
||||||
bool innerConfigureOpenTelemetryLoggerProviderTestExecuted = false;
|
bool innerConfigureOpenTelemetryLoggerProviderTestExecuted = false;
|
||||||
|
bool innerConfigureOpenTelemetryLoggerProviderTestWithServiceProviderExecuted = false;
|
||||||
|
|
||||||
using var provider = Sdk.CreateTracerProviderBuilder()
|
using var provider = Sdk.CreateTracerProviderBuilder()
|
||||||
.ConfigureServices(services =>
|
.ConfigureServices(services =>
|
||||||
|
|
@ -318,7 +319,17 @@ namespace OpenTelemetry.Trace.Tests
|
||||||
if (callNestedConfigure)
|
if (callNestedConfigure)
|
||||||
{
|
{
|
||||||
services.ConfigureOpenTelemetryTracerProvider(
|
services.ConfigureOpenTelemetryTracerProvider(
|
||||||
(sp, builder) => innerConfigureOpenTelemetryLoggerProviderTestExecuted = true);
|
builder =>
|
||||||
|
{
|
||||||
|
innerConfigureOpenTelemetryLoggerProviderTestExecuted = true;
|
||||||
|
builder.AddInstrumentation<MyInstrumentation>();
|
||||||
|
});
|
||||||
|
services.ConfigureOpenTelemetryTracerProvider(
|
||||||
|
(sp, builder) =>
|
||||||
|
{
|
||||||
|
innerConfigureOpenTelemetryLoggerProviderTestWithServiceProviderExecuted = true;
|
||||||
|
Assert.Throws<NotSupportedException>(() => builder.AddInstrumentation<MyInstrumentation>());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.ConfigureBuilder((sp, builder) =>
|
.ConfigureBuilder((sp, builder) =>
|
||||||
|
|
@ -326,10 +337,22 @@ namespace OpenTelemetry.Trace.Tests
|
||||||
innerConfigureBuilderTestExecuted = true;
|
innerConfigureBuilderTestExecuted = true;
|
||||||
Assert.Throws<NotSupportedException>(() => sp.GetService<TracerProvider>());
|
Assert.Throws<NotSupportedException>(() => sp.GetService<TracerProvider>());
|
||||||
})
|
})
|
||||||
.Build();
|
.Build() as TracerProviderSdk;
|
||||||
|
|
||||||
|
Assert.NotNull(provider);
|
||||||
|
|
||||||
Assert.True(innerConfigureBuilderTestExecuted);
|
Assert.True(innerConfigureBuilderTestExecuted);
|
||||||
Assert.Equal(callNestedConfigure, innerConfigureOpenTelemetryLoggerProviderTestExecuted);
|
Assert.Equal(callNestedConfigure, innerConfigureOpenTelemetryLoggerProviderTestExecuted);
|
||||||
|
Assert.Equal(callNestedConfigure, innerConfigureOpenTelemetryLoggerProviderTestWithServiceProviderExecuted);
|
||||||
|
|
||||||
|
if (callNestedConfigure)
|
||||||
|
{
|
||||||
|
Assert.Single(provider.Instrumentations);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.Empty(provider.Instrumentations);
|
||||||
|
}
|
||||||
|
|
||||||
Assert.Throws<NotSupportedException>(() => provider.GetServiceProvider()?.GetService<TracerProvider>());
|
Assert.Throws<NotSupportedException>(() => provider.GetServiceProvider()?.GetService<TracerProvider>());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue