-
Notifications
You must be signed in to change notification settings - Fork 772
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[di] Expose a detached TracerProviderBuilder extension on IServiceCollection which may modify services. #4508
Changes from all commits
b839b69
64bec10
0a7cae7
11a85e2
92e08ad
499fde6
7da28fc
a022ff6
26d2131
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
static OpenTelemetry.Trace.OpenTelemetryDependencyInjectionTracingServiceCollectionExtensions.ConfigureOpenTelemetryTracerProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<OpenTelemetry.Trace.TracerProviderBuilder!>! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
static OpenTelemetry.Trace.OpenTelemetryDependencyInjectionTracingServiceCollectionExtensions.ConfigureOpenTelemetryTracerProvider(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<OpenTelemetry.Trace.TracerProviderBuilder!>! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,44 +26,76 @@ public static class OpenTelemetryDependencyInjectionTracingServiceCollectionExte | |
{ | ||
/// <summary> | ||
/// Registers an action used to configure the OpenTelemetry <see | ||
/// cref="TracerProviderBuilder"/> used to create the <see | ||
/// cref="TracerProvider"/> for the <see cref="IServiceCollection"/> being | ||
/// configured. | ||
/// cref="TracerProviderBuilder"/>. | ||
/// </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 metrics use the | ||
/// <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> | ||
/// </list> | ||
/// </remarks> | ||
/// <param name="services">The <see cref="IServiceCollection" /> to add | ||
/// services to.</param> | ||
/// <param name="services"><see cref="IServiceCollection" />.</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<IServiceProvider, TracerProviderBuilder> configure) | ||
Action<TracerProviderBuilder> configure) | ||
{ | ||
RegisterBuildAction(services, configure); | ||
Guard.ThrowIfNull(services); | ||
Guard.ThrowIfNull(configure); | ||
|
||
configure(new TracerProviderServiceCollectionBuilder(services)); | ||
|
||
return services; | ||
} | ||
|
||
private static void RegisterBuildAction(IServiceCollection services, Action<IServiceProvider, TracerProviderBuilder> configure) | ||
/// <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 | ||
/// cref="TracerProviderBuilder"/>.</param> | ||
/// <returns>The <see cref="IServiceCollection"/> so that additional calls | ||
/// can be chained.</returns> | ||
public static IServiceCollection ConfigureOpenTelemetryTracerProvider( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Could we add some guidance here for end users? some message saying - if you don't need access to ServiceProvider then use the other overload. |
||
this IServiceCollection services, | ||
Action<IServiceProvider, TracerProviderBuilder> configure) | ||
{ | ||
Guard.ThrowIfNull(services); | ||
Guard.ThrowIfNull(configure); | ||
|
||
services.AddSingleton<IConfigureTracerProviderBuilder>( | ||
new ConfigureTracerProviderBuilderCallbackWrapper(configure)); | ||
|
||
return services; | ||
} | ||
|
||
private sealed class ConfigureTracerProviderBuilderCallbackWrapper : IConfigureTracerProviderBuilder | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good improvement! Was confusing before "used to configure ... used to create the ... for the ... being configured" 😆