From ad49139231baa19d8296df7648c89213bbc63dea Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 9 Mar 2021 13:57:35 -0800 Subject: [PATCH 01/16] Dependency injection support. --- examples/AspNetCore/Startup.cs | 17 +++--- .../Trace/TracerProviderBuilder.cs | 4 -- .../JaegerExporterHelperExtensions.cs | 11 +++- .../ZipkinExporterHelperExtensions.cs | 11 +++- .../TracerProviderBuilderHosting.cs | 56 +++++++++++++++++++ .../OpenTelemetryServicesExtensions.cs | 53 +++--------------- .../Trace/TracerProviderBuilderExtensions.cs | 45 +++++++++++++++ .../Trace/IResolvingTracerProviderBuilder.cs | 26 +++++++++ .../Trace/TracerProviderBuilderSdk.cs | 6 +- 9 files changed, 164 insertions(+), 65 deletions(-) create mode 100644 src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs create mode 100644 src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs create mode 100644 src/OpenTelemetry/Trace/IResolvingTracerProviderBuilder.cs diff --git a/examples/AspNetCore/Startup.cs b/examples/AspNetCore/Startup.cs index 7a0e7876643..c2c4a4a817e 100644 --- a/examples/AspNetCore/Startup.cs +++ b/examples/AspNetCore/Startup.cs @@ -23,7 +23,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.OpenApi.Models; -using OpenTelemetry; +using OpenTelemetry.Exporter; using OpenTelemetry.Resources; using OpenTelemetry.Trace; @@ -63,20 +63,17 @@ public void ConfigureServices(IServiceCollection services) .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(this.Configuration.GetValue("Jaeger:ServiceName"))) .AddAspNetCoreInstrumentation() .AddHttpClientInstrumentation() - .AddJaegerExporter(jaegerOptions => - { - jaegerOptions.AgentHost = this.Configuration.GetValue("Jaeger:Host"); - jaegerOptions.AgentPort = this.Configuration.GetValue("Jaeger:Port"); - })); + .AddJaegerExporter()); + + services.Configure(this.Configuration.GetSection("Jaeger")); break; case "zipkin": services.AddOpenTelemetryTracing((builder) => builder .AddAspNetCoreInstrumentation() .AddHttpClientInstrumentation() - .AddZipkinExporter(zipkinOptions => - { - zipkinOptions.Endpoint = new Uri(this.Configuration.GetValue("Zipkin:Endpoint")); - })); + .AddZipkinExporter()); + + services.Configure(this.Configuration.GetSection("Zipkin")); break; case "otlp": // Adding the OtlpExporter creates a GrpcChannel. diff --git a/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs b/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs index 5dfcaa7ca39..ed2c1431dc4 100644 --- a/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs +++ b/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs @@ -22,10 +22,6 @@ namespace OpenTelemetry.Trace /// public abstract class TracerProviderBuilder { - internal TracerProviderBuilder() - { - } - /// /// Adds an instrumentation to the provider. /// diff --git a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs index bcea406491d..6bcb5744f6c 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs @@ -38,7 +38,16 @@ public static TracerProviderBuilder AddJaegerExporter(this TracerProviderBuilder throw new ArgumentNullException(nameof(builder)); } - var exporterOptions = new JaegerExporterOptions(); + JaegerExporterOptions exporterOptions; + if (builder is IResolvingTracerProviderBuilder resolvingTracerProviderBuilder) + { + exporterOptions = resolvingTracerProviderBuilder.ResolveOptions(); + } + else + { + exporterOptions = new JaegerExporterOptions(); + } + configure?.Invoke(exporterOptions); var jaegerExporter = new JaegerExporter(exporterOptions); diff --git a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs index 4f88aacfefe..3c52b7a4ab4 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs @@ -38,7 +38,16 @@ public static TracerProviderBuilder AddZipkinExporter(this TracerProviderBuilder throw new ArgumentNullException(nameof(builder)); } - var exporterOptions = new ZipkinExporterOptions(); + ZipkinExporterOptions exporterOptions; + if (builder is IResolvingTracerProviderBuilder resolvingTracerProviderBuilder) + { + exporterOptions = resolvingTracerProviderBuilder.ResolveOptions(); + } + else + { + exporterOptions = new ZipkinExporterOptions(); + } + configure?.Invoke(exporterOptions); var zipkinExporter = new ZipkinExporter(exporterOptions); diff --git a/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs b/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs new file mode 100644 index 00000000000..bd1ec296823 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs @@ -0,0 +1,56 @@ +// +// 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. +// + +using System; +using System.Diagnostics; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +namespace OpenTelemetry.Trace +{ + internal class TracerProviderBuilderHosting : TracerProviderBuilderSdk, IResolvingTracerProviderBuilder + { + private readonly IServiceProvider serviceProvider; + + public TracerProviderBuilderHosting(IServiceProvider serviceProvider) + { + this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + } + + public TracerProviderBuilder AddProcessor() + where T : BaseProcessor + { + return this.AddProcessor(this.serviceProvider.GetRequiredService()); + } + + public TracerProviderBuilder SetSampler() + where T : Sampler + { + return this.SetSampler(this.serviceProvider.GetRequiredService()); + } + + public T ResolveService() + { + return this.serviceProvider.GetRequiredService(); + } + + public T ResolveOptions() + where T : class, new() + { + return this.serviceProvider.GetRequiredService>().Value; + } + } +} diff --git a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs index d6414cd3d43..62bc509ecb9 100644 --- a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs +++ b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs @@ -17,7 +17,6 @@ using System; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; -using OpenTelemetry; using OpenTelemetry.Extensions.Hosting.Implementation; using OpenTelemetry.Trace; @@ -35,8 +34,7 @@ public static class OpenTelemetryServicesExtensions /// The so that additional calls can be chained. public static IServiceCollection AddOpenTelemetryTracing(this IServiceCollection services) { - services.AddOpenTelemetryTracing(builder => { }); - return services; + return services.AddOpenTelemetryTracing((sp, builder) => { }); } /// @@ -52,10 +50,7 @@ public static IServiceCollection AddOpenTelemetryTracing(this IServiceCollection throw new ArgumentNullException(nameof(configure)); } - var builder = Sdk.CreateTracerProviderBuilder(); - configure(builder); - services.AddOpenTelemetryTracing(() => builder.Build()); - return services; + return services.AddOpenTelemetryTracing((sp, builder) => { configure(builder); }); } /// @@ -71,44 +66,12 @@ public static IServiceCollection AddOpenTelemetryTracing(this IServiceCollection throw new ArgumentNullException(nameof(configure)); } - var builder = Sdk.CreateTracerProviderBuilder(); - services.AddOpenTelemetryTracing((sp) => + return services.AddOpenTelemetryTracing(sp => { + var builder = new TracerProviderBuilderHosting(sp); configure(sp, builder); return builder.Build(); }); - return services; - } - - /// - /// Adds OpenTelemetry TracerProvider to the specified . - /// - /// The to add services to. - /// A delegate that provides the tracer provider to be registered. - /// The so that additional calls can be chained. - private static IServiceCollection AddOpenTelemetryTracing(this IServiceCollection services, Func createTracerProvider) - { - if (services is null) - { - throw new ArgumentNullException(nameof(services)); - } - - if (createTracerProvider is null) - { - throw new ArgumentNullException(nameof(createTracerProvider)); - } - - try - { - services.AddSingleton(s => createTracerProvider()); - AddOpenTelemetryTracingInternal(services); - } - catch (Exception ex) - { - HostingExtensionsEventSource.Log.FailedInitialize(ex); - } - - return services; } /// @@ -131,8 +94,9 @@ private static IServiceCollection AddOpenTelemetryTracing(this IServiceCollectio try { - services.AddSingleton(s => createTracerProvider(s)); - AddOpenTelemetryTracingInternal(services); + return services + .AddSingleton(s => createTracerProvider(s)) + .AddOpenTelemetryTracingInternal(); } catch (Exception ex) { @@ -142,9 +106,10 @@ private static IServiceCollection AddOpenTelemetryTracing(this IServiceCollectio return services; } - private static void AddOpenTelemetryTracingInternal(IServiceCollection services) + private static IServiceCollection AddOpenTelemetryTracingInternal(this IServiceCollection services) { services.TryAddEnumerable(ServiceDescriptor.Singleton()); + return services; } } } diff --git a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs new file mode 100644 index 00000000000..7a6a0029aee --- /dev/null +++ b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs @@ -0,0 +1,45 @@ +// +// 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. +// + +using System.Diagnostics; + +namespace OpenTelemetry.Trace +{ + public static class TracerProviderBuilderExtensions + { + public static TracerProviderBuilder AddProcessor(this TracerProviderBuilder tracerProviderBuilder) + where T : BaseProcessor + { + if (tracerProviderBuilder is TracerProviderBuilderHosting tracerProviderBuilderHosting) + { + tracerProviderBuilderHosting.AddProcessor(); + } + + return tracerProviderBuilder; + } + + public static TracerProviderBuilder SetSampler(this TracerProviderBuilder tracerProviderBuilder) + where T : Sampler + { + if (tracerProviderBuilder is TracerProviderBuilderHosting tracerProviderBuilderHosting) + { + tracerProviderBuilderHosting.SetSampler(); + } + + return tracerProviderBuilder; + } + } +} diff --git a/src/OpenTelemetry/Trace/IResolvingTracerProviderBuilder.cs b/src/OpenTelemetry/Trace/IResolvingTracerProviderBuilder.cs new file mode 100644 index 00000000000..ef5bbb97e57 --- /dev/null +++ b/src/OpenTelemetry/Trace/IResolvingTracerProviderBuilder.cs @@ -0,0 +1,26 @@ +// +// 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. +// + +namespace OpenTelemetry.Trace +{ + public interface IResolvingTracerProviderBuilder + { + T ResolveService(); + + T ResolveOptions() + where T : class, new(); + } +} diff --git a/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs b/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs index 3a9c6de9827..0e281e610f1 100644 --- a/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs +++ b/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs @@ -24,7 +24,7 @@ namespace OpenTelemetry.Trace /// /// Build TracerProvider with Resource, Sampler, Processors and Instrumentation. /// - internal class TracerProviderBuilderSdk : TracerProviderBuilder + public class TracerProviderBuilderSdk : TracerProviderBuilder { private readonly List instrumentationFactories = new List(); private readonly List> processors = new List>(); @@ -33,10 +33,6 @@ internal class TracerProviderBuilderSdk : TracerProviderBuilder private ResourceBuilder resourceBuilder = ResourceBuilder.CreateDefault(); private Sampler sampler = new ParentBasedSampler(new AlwaysOnSampler()); - internal TracerProviderBuilderSdk() - { - } - /// /// Adds an instrumentation to the provider. /// From ee986e23eb2227356f26b7d19e0819bca9c7b9dc Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 9 Mar 2021 14:07:27 -0800 Subject: [PATCH 02/16] Added DI-aware instrumentation methods. --- .../Implementation/TracerProviderBuilderHosting.cs | 8 ++++++++ .../Trace/TracerProviderBuilderExtensions.cs | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs b/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs index bd1ec296823..802184e647a 100644 --- a/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs +++ b/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs @@ -30,6 +30,14 @@ public TracerProviderBuilderHosting(IServiceProvider serviceProvider) this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); } + public TracerProviderBuilder AddInstrumentation() + where T : class + { + this.AddInstrumentation(() => this.ResolveService()); + + return this; + } + public TracerProviderBuilder AddProcessor() where T : BaseProcessor { diff --git a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs index 7a6a0029aee..1d553d7959a 100644 --- a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs @@ -20,6 +20,17 @@ namespace OpenTelemetry.Trace { public static class TracerProviderBuilderExtensions { + public static TracerProviderBuilder AddInstrumentation(this TracerProviderBuilder tracerProviderBuilder) + where T : class + { + if (tracerProviderBuilder is TracerProviderBuilderHosting tracerProviderBuilderHosting) + { + tracerProviderBuilderHosting.AddInstrumentation(); + } + + return tracerProviderBuilder; + } + public static TracerProviderBuilder AddProcessor(this TracerProviderBuilder tracerProviderBuilder) where T : BaseProcessor { From 186fa2f7e00451a14cf14d2bc763ebb6844f648f Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 9 Mar 2021 14:26:54 -0800 Subject: [PATCH 03/16] Renamed jaeger keys to match options. --- examples/AspNetCore/appsettings.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/AspNetCore/appsettings.json b/examples/AspNetCore/appsettings.json index fad736148cb..3279eec3559 100644 --- a/examples/AspNetCore/appsettings.json +++ b/examples/AspNetCore/appsettings.json @@ -10,8 +10,8 @@ "UseExporter": "console", "Jaeger": { "ServiceName": "jaeger-test", - "Host": "localhost", - "Port": 6831 + "AgentHost": "localhost", + "AgentPort": 6831 }, "Zipkin": { "ServiceName": "zipkin-test", From b99da7d819223a9d0039f80eb1d468bd109c9f11 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 9 Mar 2021 23:23:22 -0800 Subject: [PATCH 04/16] Added ConfigureOpenTelemetryTracing. --- .../TracerProviderBuilderHosting.cs | 4 +-- .../OpenTelemetryServicesExtensions.cs | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs b/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs index 802184e647a..f49082dc7e5 100644 --- a/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs +++ b/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs @@ -33,9 +33,7 @@ public TracerProviderBuilderHosting(IServiceProvider serviceProvider) public TracerProviderBuilder AddInstrumentation() where T : class { - this.AddInstrumentation(() => this.ResolveService()); - - return this; + return this.AddInstrumentation(() => this.ResolveService()); } public TracerProviderBuilder AddProcessor() diff --git a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs index 62bc509ecb9..0080cff90a3 100644 --- a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs +++ b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs @@ -15,6 +15,7 @@ // using System; +using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; using OpenTelemetry.Extensions.Hosting.Implementation; @@ -69,11 +70,32 @@ public static IServiceCollection AddOpenTelemetryTracing(this IServiceCollection return services.AddOpenTelemetryTracing(sp => { var builder = new TracerProviderBuilderHosting(sp); + + var tracerProviderBuilderConfigurationCallbacks = sp.GetService>(); + if (tracerProviderBuilderConfigurationCallbacks != null) + { + foreach (var tracerProviderBuilderConfigurationCallback in tracerProviderBuilderConfigurationCallbacks) + { + tracerProviderBuilderConfigurationCallback.Configure(sp, builder); + } + } + configure(sp, builder); return builder.Build(); }); } + /// + /// Register a callback to be called during the configuration of the OpenTelemetry . + /// + /// . + /// Configuration callback action. + /// The so that additional calls can be chained. + public static IServiceCollection ConfigureOpenTelemetryTracing(this IServiceCollection services, Action configure) + { + return services.AddSingleton(new TracerProviderBuilderConfigurationCallback { Configure = configure }); + } + /// /// Adds OpenTelemetry TracerProvider to the specified . /// @@ -111,5 +133,10 @@ private static IServiceCollection AddOpenTelemetryTracingInternal(this IServiceC services.TryAddEnumerable(ServiceDescriptor.Singleton()); return services; } + + private class TracerProviderBuilderConfigurationCallback + { + public Action Configure { get; set; } + } } } From 50212ace6390327456fc144203982020bef2dadf Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 10 Mar 2021 09:33:04 -0800 Subject: [PATCH 05/16] Code review. --- .../Implementation/TracerProviderBuilderHosting.cs | 8 ++++---- .../Trace/IResolvingTracerProviderBuilder.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs b/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs index f49082dc7e5..0848b4d4fdf 100644 --- a/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs +++ b/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs @@ -33,7 +33,7 @@ public TracerProviderBuilderHosting(IServiceProvider serviceProvider) public TracerProviderBuilder AddInstrumentation() where T : class { - return this.AddInstrumentation(() => this.ResolveService()); + return this.AddInstrumentation(() => this.serviceProvider.GetRequiredService()); } public TracerProviderBuilder AddProcessor() @@ -48,12 +48,12 @@ public TracerProviderBuilder SetSampler() return this.SetSampler(this.serviceProvider.GetRequiredService()); } - public T ResolveService() + public object GetService(Type serviceType) { - return this.serviceProvider.GetRequiredService(); + return this.serviceProvider.GetService(serviceType); } - public T ResolveOptions() + public T GetOptions() where T : class, new() { return this.serviceProvider.GetRequiredService>().Value; diff --git a/src/OpenTelemetry/Trace/IResolvingTracerProviderBuilder.cs b/src/OpenTelemetry/Trace/IResolvingTracerProviderBuilder.cs index ef5bbb97e57..dc3e0d9fbe8 100644 --- a/src/OpenTelemetry/Trace/IResolvingTracerProviderBuilder.cs +++ b/src/OpenTelemetry/Trace/IResolvingTracerProviderBuilder.cs @@ -14,13 +14,13 @@ // limitations under the License. // +using System; + namespace OpenTelemetry.Trace { - public interface IResolvingTracerProviderBuilder + public interface IResolvingTracerProviderBuilder : IServiceProvider { - T ResolveService(); - - T ResolveOptions() + T GetOptions() where T : class, new(); } } From 1f75aac634a7e4dedb093598b8462643d3c2c1cb Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Sat, 13 Mar 2021 11:07:03 -0800 Subject: [PATCH 06/16] Code review & tweaks. --- .../JaegerExporterHelperExtensions.cs | 32 ++++--- .../ZipkinExporterHelperExtensions.cs | 32 ++++--- .../TracerProviderBuilderHosting.cs | 95 +++++++++++++++---- .../OpenTelemetryServicesExtensions.cs | 53 +---------- .../Trace/TracerProviderBuilderExtensions.cs | 11 +++ .../ServiceProviderExtensions.cs | 24 +++++ ...erBuilder.cs => IDeferredTracerBuilder.cs} | 7 +- .../Trace/TracerProviderBuilderSdk.cs | 11 +++ 8 files changed, 167 insertions(+), 98 deletions(-) create mode 100644 src/OpenTelemetry/ServiceProviderExtensions.cs rename src/OpenTelemetry/Trace/{IResolvingTracerProviderBuilder.cs => IDeferredTracerBuilder.cs} (75%) diff --git a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs index 6bcb5744f6c..464649f3fdd 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs @@ -38,20 +38,24 @@ public static TracerProviderBuilder AddJaegerExporter(this TracerProviderBuilder throw new ArgumentNullException(nameof(builder)); } - JaegerExporterOptions exporterOptions; - if (builder is IResolvingTracerProviderBuilder resolvingTracerProviderBuilder) + if (builder is IDeferredTracerBuilder deferredTracerBuilder) { - exporterOptions = resolvingTracerProviderBuilder.ResolveOptions(); - } - else - { - exporterOptions = new JaegerExporterOptions(); + return deferredTracerBuilder.Configure((sp, builder) => + { + AddJaegerExporter(builder, sp.GetOptions(), configure); + }); } - configure?.Invoke(exporterOptions); - var jaegerExporter = new JaegerExporter(exporterOptions); + return AddJaegerExporter(builder, new JaegerExporterOptions(), configure); + } + + private static TracerProviderBuilder AddJaegerExporter(TracerProviderBuilder builder, JaegerExporterOptions options, Action configure = null) + { + configure?.Invoke(options); + + var jaegerExporter = new JaegerExporter(options); - if (exporterOptions.ExportProcessorType == ExportProcessorType.Simple) + if (options.ExportProcessorType == ExportProcessorType.Simple) { return builder.AddProcessor(new SimpleActivityExportProcessor(jaegerExporter)); } @@ -59,10 +63,10 @@ public static TracerProviderBuilder AddJaegerExporter(this TracerProviderBuilder { return builder.AddProcessor(new BatchActivityExportProcessor( jaegerExporter, - exporterOptions.BatchExportProcessorOptions.MaxQueueSize, - exporterOptions.BatchExportProcessorOptions.ScheduledDelayMilliseconds, - exporterOptions.BatchExportProcessorOptions.ExporterTimeoutMilliseconds, - exporterOptions.BatchExportProcessorOptions.MaxExportBatchSize)); + options.BatchExportProcessorOptions.MaxQueueSize, + options.BatchExportProcessorOptions.ScheduledDelayMilliseconds, + options.BatchExportProcessorOptions.ExporterTimeoutMilliseconds, + options.BatchExportProcessorOptions.MaxExportBatchSize)); } } } diff --git a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs index 3c52b7a4ab4..5daef5c36d0 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs @@ -38,20 +38,24 @@ public static TracerProviderBuilder AddZipkinExporter(this TracerProviderBuilder throw new ArgumentNullException(nameof(builder)); } - ZipkinExporterOptions exporterOptions; - if (builder is IResolvingTracerProviderBuilder resolvingTracerProviderBuilder) + if (builder is IDeferredTracerBuilder deferredTracerBuilder) { - exporterOptions = resolvingTracerProviderBuilder.ResolveOptions(); - } - else - { - exporterOptions = new ZipkinExporterOptions(); + return deferredTracerBuilder.Configure((sp, builder) => + { + AddZipkinExporter(builder, sp.GetOptions(), configure); + }); } - configure?.Invoke(exporterOptions); - var zipkinExporter = new ZipkinExporter(exporterOptions); + return AddZipkinExporter(builder, new ZipkinExporterOptions(), configure); + } + + private static TracerProviderBuilder AddZipkinExporter(TracerProviderBuilder builder, ZipkinExporterOptions options, Action configure = null) + { + configure?.Invoke(options); + + var zipkinExporter = new ZipkinExporter(options); - if (exporterOptions.ExportProcessorType == ExportProcessorType.Simple) + if (options.ExportProcessorType == ExportProcessorType.Simple) { return builder.AddProcessor(new SimpleActivityExportProcessor(zipkinExporter)); } @@ -59,10 +63,10 @@ public static TracerProviderBuilder AddZipkinExporter(this TracerProviderBuilder { return builder.AddProcessor(new BatchActivityExportProcessor( zipkinExporter, - exporterOptions.BatchExportProcessorOptions.MaxQueueSize, - exporterOptions.BatchExportProcessorOptions.ScheduledDelayMilliseconds, - exporterOptions.BatchExportProcessorOptions.ExporterTimeoutMilliseconds, - exporterOptions.BatchExportProcessorOptions.MaxExportBatchSize)); + options.BatchExportProcessorOptions.MaxQueueSize, + options.BatchExportProcessorOptions.ScheduledDelayMilliseconds, + options.BatchExportProcessorOptions.ExporterTimeoutMilliseconds, + options.BatchExportProcessorOptions.MaxExportBatchSize)); } } } diff --git a/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs b/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs index 0848b4d4fdf..f1c6691baaf 100644 --- a/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs +++ b/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs @@ -15,48 +15,109 @@ // using System; +using System.Collections.Generic; using System.Diagnostics; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; namespace OpenTelemetry.Trace { - internal class TracerProviderBuilderHosting : TracerProviderBuilderSdk, IResolvingTracerProviderBuilder + public class TracerProviderBuilderHosting : TracerProviderBuilderSdk, IDeferredTracerBuilder { - private readonly IServiceProvider serviceProvider; + private readonly List instrumentationFactories = new List(); + private readonly List processorTypes = new List(); + private readonly List> configurationActions = new List>(); + private Type samplerType; - public TracerProviderBuilderHosting(IServiceProvider serviceProvider) + internal TracerProviderBuilderHosting(IServiceCollection services) { - this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + this.Services = services ?? throw new ArgumentNullException(nameof(services)); } - public TracerProviderBuilder AddInstrumentation() - where T : class + public IServiceCollection Services { get; } + + TracerProviderBuilder IDeferredTracerBuilder.Configure(Action configure) + { + if (configure == null) + { + throw new ArgumentNullException(nameof(configure)); + } + + this.configurationActions.Add(configure); + return this; + } + + internal TracerProviderBuilder AddInstrumentation( + Func instrumentationFactory) + where TInstrumentation : class { - return this.AddInstrumentation(() => this.serviceProvider.GetRequiredService()); + if (instrumentationFactory == null) + { + throw new ArgumentNullException(nameof(instrumentationFactory)); + } + + this.instrumentationFactories.Add( + new InstrumentationFactory( + typeof(TInstrumentation).Name, + "semver:" + typeof(TInstrumentation).Assembly.GetName().Version, + typeof(TInstrumentation))); + + return this; } - public TracerProviderBuilder AddProcessor() + internal TracerProviderBuilder AddProcessor() where T : BaseProcessor { - return this.AddProcessor(this.serviceProvider.GetRequiredService()); + this.processorTypes.Add(typeof(T)); + return this; } - public TracerProviderBuilder SetSampler() + internal TracerProviderBuilder SetSampler() where T : Sampler { - return this.SetSampler(this.serviceProvider.GetRequiredService()); + this.samplerType = typeof(T); + return this; } - public object GetService(Type serviceType) + internal TracerProvider Build(IServiceProvider serviceProvider) { - return this.serviceProvider.GetService(serviceType); + foreach (InstrumentationFactory instrumentationFactory in this.instrumentationFactories) + { + this.AddInstrumentation( + instrumentationFactory.Name, + instrumentationFactory.Version, + () => serviceProvider.GetRequiredService(instrumentationFactory.Type)); + } + + foreach (Type processorType in this.processorTypes) + { + this.AddProcessor((BaseProcessor)serviceProvider.GetRequiredService(processorType)); + } + + if (this.samplerType != null) + { + this.SetSampler((Sampler)serviceProvider.GetRequiredService(this.samplerType)); + } + + foreach (Action configureAction in this.configurationActions) + { + configureAction(serviceProvider, this); + } + + return ((TracerProviderBuilderSdk)this).Build(); } - public T GetOptions() - where T : class, new() + internal readonly struct InstrumentationFactory { - return this.serviceProvider.GetRequiredService>().Value; + public readonly string Name; + public readonly string Version; + public readonly Type Type; + + internal InstrumentationFactory(string name, string version, Type type) + { + this.Name = name; + this.Version = version; + this.Type = type; + } } } } diff --git a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs index 0080cff90a3..5eabffd9be0 100644 --- a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs +++ b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs @@ -35,7 +35,7 @@ public static class OpenTelemetryServicesExtensions /// The so that additional calls can be chained. public static IServiceCollection AddOpenTelemetryTracing(this IServiceCollection services) { - return services.AddOpenTelemetryTracing((sp, builder) => { }); + return services.AddOpenTelemetryTracing(builder => { }); } /// @@ -51,49 +51,9 @@ public static IServiceCollection AddOpenTelemetryTracing(this IServiceCollection throw new ArgumentNullException(nameof(configure)); } - return services.AddOpenTelemetryTracing((sp, builder) => { configure(builder); }); - } - - /// - /// Adds OpenTelemetry TracerProvider to the specified . - /// - /// The to add services to. - /// The action to configure TracerProviderBuilder. - /// The so that additional calls can be chained. - public static IServiceCollection AddOpenTelemetryTracing(this IServiceCollection services, Action configure) - { - if (configure is null) - { - throw new ArgumentNullException(nameof(configure)); - } - - return services.AddOpenTelemetryTracing(sp => - { - var builder = new TracerProviderBuilderHosting(sp); - - var tracerProviderBuilderConfigurationCallbacks = sp.GetService>(); - if (tracerProviderBuilderConfigurationCallbacks != null) - { - foreach (var tracerProviderBuilderConfigurationCallback in tracerProviderBuilderConfigurationCallbacks) - { - tracerProviderBuilderConfigurationCallback.Configure(sp, builder); - } - } - - configure(sp, builder); - return builder.Build(); - }); - } - - /// - /// Register a callback to be called during the configuration of the OpenTelemetry . - /// - /// . - /// Configuration callback action. - /// The so that additional calls can be chained. - public static IServiceCollection ConfigureOpenTelemetryTracing(this IServiceCollection services, Action configure) - { - return services.AddSingleton(new TracerProviderBuilderConfigurationCallback { Configure = configure }); + var builder = new TracerProviderBuilderHosting(services); + configure(builder); + return services.AddOpenTelemetryTracing(sp => builder.Build(sp)); } /// @@ -133,10 +93,5 @@ private static IServiceCollection AddOpenTelemetryTracingInternal(this IServiceC services.TryAddEnumerable(ServiceDescriptor.Singleton()); return services; } - - private class TracerProviderBuilderConfigurationCallback - { - public Action Configure { get; set; } - } } } diff --git a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs index 1d553d7959a..10a56d47744 100644 --- a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System; using System.Diagnostics; namespace OpenTelemetry.Trace @@ -52,5 +53,15 @@ public static TracerProviderBuilder SetSampler(this TracerProviderBuilder tra return tracerProviderBuilder; } + + public static TracerProviderBuilder Configure(this TracerProviderBuilder tracerProviderBuilder, Action configure) + { + if (tracerProviderBuilder is IDeferredTracerBuilder deferredTracerBuilder) + { + deferredTracerBuilder.Configure(configure); + } + + return tracerProviderBuilder; + } } } diff --git a/src/OpenTelemetry/ServiceProviderExtensions.cs b/src/OpenTelemetry/ServiceProviderExtensions.cs new file mode 100644 index 00000000000..88f35355c78 --- /dev/null +++ b/src/OpenTelemetry/ServiceProviderExtensions.cs @@ -0,0 +1,24 @@ +using System; + +namespace OpenTelemetry +{ + public static class ServiceProviderExtensions + { + private static readonly Type OptionsGeneircType = Type.GetType("Microsoft.Extensions.Options.IOptions`1, Microsoft.Extensions.Options"); + + public static T GetOptions(this IServiceProvider serviceProvider) + where T : class, new() + { + if (OptionsGeneircType == null) + { + throw new InvalidOperationException("Microsoft.Extensions.Options.IOptions<> could not be found reflectively in the running process."); + } + + Type optionsType = OptionsGeneircType.MakeGenericType(typeof(T)); + + object options = serviceProvider.GetService(optionsType); + + return (T)optionsType.GetProperty("Value").GetMethod.Invoke(options, null); + } + } +} diff --git a/src/OpenTelemetry/Trace/IResolvingTracerProviderBuilder.cs b/src/OpenTelemetry/Trace/IDeferredTracerBuilder.cs similarity index 75% rename from src/OpenTelemetry/Trace/IResolvingTracerProviderBuilder.cs rename to src/OpenTelemetry/Trace/IDeferredTracerBuilder.cs index dc3e0d9fbe8..54ea08d74a5 100644 --- a/src/OpenTelemetry/Trace/IResolvingTracerProviderBuilder.cs +++ b/src/OpenTelemetry/Trace/IDeferredTracerBuilder.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,9 +18,8 @@ namespace OpenTelemetry.Trace { - public interface IResolvingTracerProviderBuilder : IServiceProvider + public interface IDeferredTracerBuilder { - T GetOptions() - where T : class, new(); + TracerProviderBuilder Configure(Action configure); } } diff --git a/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs b/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs index 0e281e610f1..dbff3513b2c 100644 --- a/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs +++ b/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs @@ -196,6 +196,17 @@ internal TracerProvider Build() this.legacyActivityOperationNames); } + protected TracerProviderBuilder AddInstrumentation( + string instrumentationName, + string instrumentationVersion, + Func instrumentationFactory) + { + this.instrumentationFactories.Add( + new InstrumentationFactory(instrumentationName, instrumentationVersion, instrumentationFactory)); + + return this; + } + internal readonly struct InstrumentationFactory { public readonly string Name; From 670aa36d6d092861efb22e5fb16f278acff92260 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Sat, 13 Mar 2021 12:37:31 -0800 Subject: [PATCH 07/16] Fallback logic for when IOptions is present, but not registered. --- src/OpenTelemetry/ServiceProviderExtensions.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry/ServiceProviderExtensions.cs b/src/OpenTelemetry/ServiceProviderExtensions.cs index 88f35355c78..655724de3ef 100644 --- a/src/OpenTelemetry/ServiceProviderExtensions.cs +++ b/src/OpenTelemetry/ServiceProviderExtensions.cs @@ -17,6 +17,10 @@ public static T GetOptions(this IServiceProvider serviceProvider) Type optionsType = OptionsGeneircType.MakeGenericType(typeof(T)); object options = serviceProvider.GetService(optionsType); + if (options == null) + { + return new T(); + } return (T)optionsType.GetProperty("Value").GetMethod.Invoke(options, null); } From d5e2482dd39b665ee489148054977ba85421d9c7 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 17 Mar 2021 17:42:05 -0700 Subject: [PATCH 08/16] Code review. --- .../OpenTelemetry.Exporter.Jaeger.csproj | 1 + .../OpenTelemetry.Exporter.Zipkin.csproj | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 9 +- .../OpenTelemetryServicesExtensions.cs | 12 +- .../Trace/TracerProviderBuilderExtensions.cs | 48 ++++ .../TracerProviderBuilderHosting.cs | 64 ++--- .../.publicApi/net452/PublicAPI.Unshipped.txt | 8 + .../.publicApi/net46/PublicAPI.Unshipped.txt | 8 + .../.publicApi/net461/PublicAPI.Unshipped.txt | 8 + .../netstandard2.0/PublicAPI.Unshipped.txt | 8 + .../Internal/ServiceProviderExtensions.cs | 47 ++++ .../ServiceProviderExtensions.cs | 28 --- .../Trace/IDeferredTracerBuilder.cs | 15 ++ .../Trace/TracerProviderBuilderBase.cs | 228 ++++++++++++++++++ .../Trace/TracerProviderBuilderExtensions.cs | 37 ++- .../Trace/TracerProviderBuilderSdk.cs | 204 +--------------- src/OpenTelemetry/Trace/TracerProviderSdk.cs | 2 +- 17 files changed, 444 insertions(+), 284 deletions(-) rename src/OpenTelemetry.Extensions.Hosting/{Implementation => Trace}/TracerProviderBuilderHosting.cs (90%) create mode 100644 src/OpenTelemetry/Internal/ServiceProviderExtensions.cs delete mode 100644 src/OpenTelemetry/ServiceProviderExtensions.cs create mode 100644 src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs diff --git a/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj b/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj index 2227d11ce22..3d33742d97a 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj +++ b/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj @@ -22,6 +22,7 @@ + diff --git a/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj b/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj index 96f46d41de9..fcd5e005612 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj +++ b/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj @@ -17,6 +17,7 @@ + diff --git a/src/OpenTelemetry.Extensions.Hosting/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Hosting/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 1d0c89fedbc..adda9dee43d 100644 --- a/src/OpenTelemetry.Extensions.Hosting/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Hosting/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,4 +1,11 @@ Microsoft.Extensions.DependencyInjection.OpenTelemetryServicesExtensions +OpenTelemetry.Trace.TracerProviderBuilderExtensions +OpenTelemetry.Trace.TracerProviderBuilderHosting +OpenTelemetry.Trace.TracerProviderBuilderHosting.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection static Microsoft.Extensions.DependencyInjection.OpenTelemetryServicesExtensions.AddOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection static Microsoft.Extensions.DependencyInjection.OpenTelemetryServicesExtensions.AddOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection -static Microsoft.Extensions.DependencyInjection.OpenTelemetryServicesExtensions.AddOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddProcessor(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.Build(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, System.IServiceProvider serviceProvider) -> OpenTelemetry.Trace.TracerProvider +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.Configure(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.SetSampler(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs index 5eabffd9be0..982bd013bfb 100644 --- a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs +++ b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs @@ -15,7 +15,6 @@ // using System; -using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; using OpenTelemetry.Extensions.Hosting.Implementation; @@ -76,9 +75,8 @@ private static IServiceCollection AddOpenTelemetryTracing(this IServiceCollectio try { - return services - .AddSingleton(s => createTracerProvider(s)) - .AddOpenTelemetryTracingInternal(); + services.TryAddEnumerable(ServiceDescriptor.Singleton()); + return services.AddSingleton(s => createTracerProvider(s)); } catch (Exception ex) { @@ -87,11 +85,5 @@ private static IServiceCollection AddOpenTelemetryTracing(this IServiceCollectio return services; } - - private static IServiceCollection AddOpenTelemetryTracingInternal(this IServiceCollection services) - { - services.TryAddEnumerable(ServiceDescriptor.Singleton()); - return services; - } } } diff --git a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs index 10a56d47744..d3c66bfae03 100644 --- a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs @@ -19,8 +19,17 @@ namespace OpenTelemetry.Trace { + /// + /// Contains extension methods for the class. + /// public static class TracerProviderBuilderExtensions { + /// + /// Adds instrumentation to the provider. + /// + /// Instrumentation type. + /// . + /// The supplied for chaining. public static TracerProviderBuilder AddInstrumentation(this TracerProviderBuilder tracerProviderBuilder) where T : class { @@ -32,6 +41,12 @@ public static TracerProviderBuilder AddInstrumentation(this TracerProviderBui return tracerProviderBuilder; } + /// + /// Adds a processor to the provider. + /// + /// Processor type. + /// . + /// The supplied for chaining. public static TracerProviderBuilder AddProcessor(this TracerProviderBuilder tracerProviderBuilder) where T : BaseProcessor { @@ -43,6 +58,12 @@ public static TracerProviderBuilder AddProcessor(this TracerProviderBuilder t return tracerProviderBuilder; } + /// + /// Sets the sampler on the provider. + /// + /// Sampler type. + /// . + /// The supplied for chaining. public static TracerProviderBuilder SetSampler(this TracerProviderBuilder tracerProviderBuilder) where T : Sampler { @@ -54,6 +75,12 @@ public static TracerProviderBuilder SetSampler(this TracerProviderBuilder tra return tracerProviderBuilder; } + /// + /// Register a callback action to configure the during initialization. + /// + /// . + /// Configuration callback. + /// The supplied for chaining. public static TracerProviderBuilder Configure(this TracerProviderBuilder tracerProviderBuilder, Action configure) { if (tracerProviderBuilder is IDeferredTracerBuilder deferredTracerBuilder) @@ -63,5 +90,26 @@ public static TracerProviderBuilder Configure(this TracerProviderBuilder tracerP return tracerProviderBuilder; } + + /// + /// Run the configured actions to initialize the . + /// + /// . + /// . + /// . + public static TracerProvider Build(this TracerProviderBuilder tracerProviderBuilder, IServiceProvider serviceProvider) + { + if (tracerProviderBuilder is IDeferredTracerBuilder deferredTracerBuilder) + { + return deferredTracerBuilder.Build(serviceProvider); + } + + if (tracerProviderBuilder is TracerProviderBuilderBase tracerProviderBuilderBase) + { + return tracerProviderBuilderBase.Build(); + } + + return null; + } } } diff --git a/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderHosting.cs similarity index 90% rename from src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs rename to src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderHosting.cs index f1c6691baaf..a76ca52aa01 100644 --- a/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs +++ b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderHosting.cs @@ -21,7 +21,10 @@ namespace OpenTelemetry.Trace { - public class TracerProviderBuilderHosting : TracerProviderBuilderSdk, IDeferredTracerBuilder + /// + /// A with support for deferred initialization using for dependency injection. + /// + public class TracerProviderBuilderHosting : TracerProviderBuilderBase, IDeferredTracerBuilder { private readonly List instrumentationFactories = new List(); private readonly List processorTypes = new List(); @@ -33,6 +36,9 @@ internal TracerProviderBuilderHosting(IServiceCollection services) this.Services = services ?? throw new ArgumentNullException(nameof(services)); } + /// + /// Gets the application services. + /// public IServiceCollection Services { get; } TracerProviderBuilder IDeferredTracerBuilder.Configure(Action configure) @@ -46,6 +52,34 @@ TracerProviderBuilder IDeferredTracerBuilder.Configure(Action serviceProvider.GetRequiredService(instrumentationFactory.Type)); + } + + foreach (Type processorType in this.processorTypes) + { + this.AddProcessor((BaseProcessor)serviceProvider.GetRequiredService(processorType)); + } + + if (this.samplerType != null) + { + this.SetSampler((Sampler)serviceProvider.GetRequiredService(this.samplerType)); + } + + foreach (Action configureAction in this.configurationActions) + { + configureAction(serviceProvider, this); + } + + return ((TracerProviderBuilderBase)this).Build(); + } + internal TracerProviderBuilder AddInstrumentation( Func instrumentationFactory) where TInstrumentation : class @@ -78,34 +112,6 @@ internal TracerProviderBuilder SetSampler() return this; } - internal TracerProvider Build(IServiceProvider serviceProvider) - { - foreach (InstrumentationFactory instrumentationFactory in this.instrumentationFactories) - { - this.AddInstrumentation( - instrumentationFactory.Name, - instrumentationFactory.Version, - () => serviceProvider.GetRequiredService(instrumentationFactory.Type)); - } - - foreach (Type processorType in this.processorTypes) - { - this.AddProcessor((BaseProcessor)serviceProvider.GetRequiredService(processorType)); - } - - if (this.samplerType != null) - { - this.SetSampler((Sampler)serviceProvider.GetRequiredService(this.samplerType)); - } - - foreach (Action configureAction in this.configurationActions) - { - configureAction(serviceProvider, this); - } - - return ((TracerProviderBuilderSdk)this).Build(); - } - internal readonly struct InstrumentationFactory { public readonly string Name; diff --git a/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt index 8de35a2051f..465965ee5a7 100644 --- a/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt @@ -1,4 +1,12 @@ +OpenTelemetry.Trace.IDeferredTracerBuilder +OpenTelemetry.Trace.IDeferredTracerBuilder.Build(System.IServiceProvider serviceProvider) -> OpenTelemetry.Trace.TracerProvider +OpenTelemetry.Trace.IDeferredTracerBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void +OpenTelemetry.Trace.TracerProviderBuilderBase +OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.TracerProviderBuilderBase.TracerProviderBuilderBase() -> void +override OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string[] names) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddLegacySource(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, string operationName) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.TracerProviderBuilderExtensions.SetErrorStatusOnException(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, bool enabled = true) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.TracerProviderExtensions.ForceFlush(this OpenTelemetry.Trace.TracerProvider provider, int timeoutMilliseconds = -1) -> bool diff --git a/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt index 8de35a2051f..465965ee5a7 100644 --- a/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt @@ -1,4 +1,12 @@ +OpenTelemetry.Trace.IDeferredTracerBuilder +OpenTelemetry.Trace.IDeferredTracerBuilder.Build(System.IServiceProvider serviceProvider) -> OpenTelemetry.Trace.TracerProvider +OpenTelemetry.Trace.IDeferredTracerBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void +OpenTelemetry.Trace.TracerProviderBuilderBase +OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.TracerProviderBuilderBase.TracerProviderBuilderBase() -> void +override OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string[] names) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddLegacySource(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, string operationName) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.TracerProviderBuilderExtensions.SetErrorStatusOnException(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, bool enabled = true) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.TracerProviderExtensions.ForceFlush(this OpenTelemetry.Trace.TracerProvider provider, int timeoutMilliseconds = -1) -> bool diff --git a/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt index 8af801f0f31..0d15f643400 100644 --- a/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt @@ -7,7 +7,15 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeScopes.get -> bool OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeScopes.set -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.get -> bool OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.set -> void +OpenTelemetry.Trace.IDeferredTracerBuilder +OpenTelemetry.Trace.IDeferredTracerBuilder.Build(System.IServiceProvider serviceProvider) -> OpenTelemetry.Trace.TracerProvider +OpenTelemetry.Trace.IDeferredTracerBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void +OpenTelemetry.Trace.TracerProviderBuilderBase +OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.TracerProviderBuilderBase.TracerProviderBuilderBase() -> void +override OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string[] names) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddLegacySource(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, string operationName) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.TracerProviderBuilderExtensions.SetErrorStatusOnException(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, bool enabled = true) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.TracerProviderExtensions.ForceFlush(this OpenTelemetry.Trace.TracerProvider provider, int timeoutMilliseconds = -1) -> bool diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 8af801f0f31..0d15f643400 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -7,7 +7,15 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeScopes.get -> bool OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeScopes.set -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.get -> bool OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.set -> void +OpenTelemetry.Trace.IDeferredTracerBuilder +OpenTelemetry.Trace.IDeferredTracerBuilder.Build(System.IServiceProvider serviceProvider) -> OpenTelemetry.Trace.TracerProvider +OpenTelemetry.Trace.IDeferredTracerBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void +OpenTelemetry.Trace.TracerProviderBuilderBase +OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.TracerProviderBuilderBase.TracerProviderBuilderBase() -> void +override OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string[] names) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddLegacySource(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, string operationName) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.TracerProviderBuilderExtensions.SetErrorStatusOnException(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, bool enabled = true) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.TracerProviderExtensions.ForceFlush(this OpenTelemetry.Trace.TracerProvider provider, int timeoutMilliseconds = -1) -> bool diff --git a/src/OpenTelemetry/Internal/ServiceProviderExtensions.cs b/src/OpenTelemetry/Internal/ServiceProviderExtensions.cs new file mode 100644 index 00000000000..4506f09e389 --- /dev/null +++ b/src/OpenTelemetry/Internal/ServiceProviderExtensions.cs @@ -0,0 +1,47 @@ +// +// 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. +// + +#if NET461 || NETSTANDARD2_0 +using Microsoft.Extensions.Options; +#endif + +namespace System +{ + /// + /// Extension methods for OpenTelemetry depedency injection support. + /// + internal static class ServiceProviderExtensions + { + /// + /// Get options from the supplied . + /// + /// Options type. + /// . + /// Options instance. + public static T GetOptions(this IServiceProvider serviceProvider) + where T : class, new() + { +#if NET461 || NETSTANDARD2_0 + IOptions options = (IOptions)serviceProvider.GetService(typeof(IOptions)); + + // Note: options could be null if user never invoked services.AddOptions(). + return options?.Value ?? new T(); +#else + return new T(); +#endif + } + } +} diff --git a/src/OpenTelemetry/ServiceProviderExtensions.cs b/src/OpenTelemetry/ServiceProviderExtensions.cs deleted file mode 100644 index 655724de3ef..00000000000 --- a/src/OpenTelemetry/ServiceProviderExtensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; - -namespace OpenTelemetry -{ - public static class ServiceProviderExtensions - { - private static readonly Type OptionsGeneircType = Type.GetType("Microsoft.Extensions.Options.IOptions`1, Microsoft.Extensions.Options"); - - public static T GetOptions(this IServiceProvider serviceProvider) - where T : class, new() - { - if (OptionsGeneircType == null) - { - throw new InvalidOperationException("Microsoft.Extensions.Options.IOptions<> could not be found reflectively in the running process."); - } - - Type optionsType = OptionsGeneircType.MakeGenericType(typeof(T)); - - object options = serviceProvider.GetService(optionsType); - if (options == null) - { - return new T(); - } - - return (T)optionsType.GetProperty("Value").GetMethod.Invoke(options, null); - } - } -} diff --git a/src/OpenTelemetry/Trace/IDeferredTracerBuilder.cs b/src/OpenTelemetry/Trace/IDeferredTracerBuilder.cs index 54ea08d74a5..1d99d3a8ff6 100644 --- a/src/OpenTelemetry/Trace/IDeferredTracerBuilder.cs +++ b/src/OpenTelemetry/Trace/IDeferredTracerBuilder.cs @@ -18,8 +18,23 @@ namespace OpenTelemetry.Trace { + /// + /// Describes a tracer builder tha support deferred initialization using a to perform dependency injection. + /// public interface IDeferredTracerBuilder { + /// + /// Register a callback action to configure the during initialization. + /// + /// Configuration callback. + /// The supplied for chaining. TracerProviderBuilder Configure(Action configure); + + /// + /// Run the configured actions to initialize the . + /// + /// . + /// . + TracerProvider Build(IServiceProvider serviceProvider); } } diff --git a/src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs b/src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs new file mode 100644 index 00000000000..a2c9dce71a8 --- /dev/null +++ b/src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs @@ -0,0 +1,228 @@ +// +// 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. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Trace +{ + /// + /// Build TracerProvider with Resource, Sampler, Processors and Instrumentation. + /// + public abstract class TracerProviderBuilderBase : TracerProviderBuilder + { + private readonly List instrumentationFactories = new List(); + private readonly List> processors = new List>(); + private readonly List sources = new List(); + private readonly Dictionary legacyActivityOperationNames = new Dictionary(StringComparer.OrdinalIgnoreCase); + private ResourceBuilder resourceBuilder = ResourceBuilder.CreateDefault(); + private Sampler sampler = new ParentBasedSampler(new AlwaysOnSampler()); + + protected TracerProviderBuilderBase() + { + } + + /// + /// Adds an instrumentation to the provider. + /// + /// Type of instrumentation class. + /// Function that builds instrumentation. + /// Returns for chaining. + public override TracerProviderBuilder AddInstrumentation( + Func instrumentationFactory) + where TInstrumentation : class + { + if (instrumentationFactory == null) + { + throw new ArgumentNullException(nameof(instrumentationFactory)); + } + + this.instrumentationFactories.Add( + new InstrumentationFactory( + typeof(TInstrumentation).Name, + "semver:" + typeof(TInstrumentation).Assembly.GetName().Version, + instrumentationFactory)); + + return this; + } + + /// + /// Adds given activitysource names to the list of subscribed sources. + /// + /// Activity source names. + /// Returns for chaining. + public override TracerProviderBuilder AddSource(params string[] names) + { + if (names == null) + { + throw new ArgumentNullException(nameof(names)); + } + + foreach (var name in names) + { + if (string.IsNullOrWhiteSpace(name)) + { + throw new ArgumentException($"{nameof(names)} contains null or whitespace string."); + } + + // TODO: We need to fix the listening model. + // Today it ignores version. + this.sources.Add(name); + } + + return this; + } + + /// + /// Sets whether the status of + /// should be set to Status.Error when it ended abnormally due to an unhandled exception. + /// + /// Enabled or not. + /// Returns for chaining. + internal TracerProviderBuilder SetErrorStatusOnException(bool enabled) + { + ExceptionProcessor existingExceptionProcessor = null; + + if (this.processors.Count > 0) + { + existingExceptionProcessor = this.processors[0] as ExceptionProcessor; + } + + if (enabled) + { + if (existingExceptionProcessor == null) + { + try + { + this.processors.Insert(0, new ExceptionProcessor()); + } + catch (Exception ex) + { + throw new NotSupportedException("SetErrorStatusOnException is not supported on this platform.", ex); + } + } + } + else + { + if (existingExceptionProcessor != null) + { + this.processors.RemoveAt(0); + existingExceptionProcessor.Dispose(); + } + } + + return this; + } + + /// + /// Sets sampler. + /// + /// Sampler instance. + /// Returns for chaining. + internal TracerProviderBuilder SetSampler(Sampler sampler) + { + this.sampler = sampler ?? throw new ArgumentNullException(nameof(sampler)); + return this; + } + + /// + /// Sets the from which the Resource associated with + /// this provider is built from. Overwrites currently set ResourceBuilder. + /// + /// from which Resource will be built. + /// Returns for chaining. + internal TracerProviderBuilder SetResourceBuilder(ResourceBuilder resourceBuilder) + { + this.resourceBuilder = resourceBuilder ?? throw new ArgumentNullException(nameof(resourceBuilder)); + return this; + } + + /// + /// Adds processor to the provider. + /// + /// Activity processor to add. + /// Returns for chaining. + internal TracerProviderBuilder AddProcessor(BaseProcessor processor) + { + if (processor == null) + { + throw new ArgumentNullException(nameof(processor)); + } + + this.processors.Add(processor); + + return this; + } + + /// + /// Adds a listener for objects created with the given operation name to the . + /// + /// + /// This is provided to capture legacy objects created without using the API. + /// + /// Operation name of the objects to capture. + /// Returns for chaining. + internal TracerProviderBuilder AddLegacySource(string operationName) + { + if (string.IsNullOrWhiteSpace(operationName)) + { + throw new ArgumentException($"{nameof(operationName)} contains null or whitespace string."); + } + + this.legacyActivityOperationNames[operationName] = true; + + return this; + } + + internal TracerProvider Build() + { + return new TracerProviderSdk( + this.resourceBuilder.Build(), + this.sources, + this.instrumentationFactories, + this.sampler, + this.processors, + this.legacyActivityOperationNames); + } + + protected TracerProviderBuilder AddInstrumentation( + string instrumentationName, + string instrumentationVersion, + Func instrumentationFactory) + { + this.instrumentationFactories.Add( + new InstrumentationFactory(instrumentationName, instrumentationVersion, instrumentationFactory)); + + return this; + } + + internal readonly struct InstrumentationFactory + { + public readonly string Name; + public readonly string Version; + public readonly Func Factory; + + internal InstrumentationFactory(string name, string version, Func factory) + { + this.Name = name; + this.Version = version; + this.Factory = factory; + } + } + } +} diff --git a/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs index 17b6ac026ce..e64f0c6883c 100644 --- a/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs @@ -20,6 +20,9 @@ namespace OpenTelemetry.Trace { + /// + /// Contains extension methods for the class. + /// public static class TracerProviderBuilderExtensions { /// @@ -31,9 +34,9 @@ public static class TracerProviderBuilderExtensions /// Returns for chaining. public static TracerProviderBuilder SetErrorStatusOnException(this TracerProviderBuilder tracerProviderBuilder, bool enabled = true) { - if (tracerProviderBuilder is TracerProviderBuilderSdk tracerProviderBuilderSdk) + if (tracerProviderBuilder is TracerProviderBuilderBase tracerProviderBuilderBase) { - tracerProviderBuilderSdk.SetErrorStatusOnException(enabled); + tracerProviderBuilderBase.SetErrorStatusOnException(enabled); } return tracerProviderBuilder; @@ -47,9 +50,9 @@ public static TracerProviderBuilder SetErrorStatusOnException(this TracerProvide /// Returns for chaining. public static TracerProviderBuilder SetSampler(this TracerProviderBuilder tracerProviderBuilder, Sampler sampler) { - if (tracerProviderBuilder is TracerProviderBuilderSdk tracerProviderBuilderSdk) + if (tracerProviderBuilder is TracerProviderBuilderBase tracerProviderBuilderBase) { - tracerProviderBuilderSdk.SetSampler(sampler); + tracerProviderBuilderBase.SetSampler(sampler); } return tracerProviderBuilder; @@ -64,9 +67,9 @@ public static TracerProviderBuilder SetSampler(this TracerProviderBuilder tracer /// Returns for chaining. public static TracerProviderBuilder SetResourceBuilder(this TracerProviderBuilder tracerProviderBuilder, ResourceBuilder resourceBuilder) { - if (tracerProviderBuilder is TracerProviderBuilderSdk tracerProviderBuilderSdk) + if (tracerProviderBuilder is TracerProviderBuilderBase tracerProviderBuilderBase) { - tracerProviderBuilderSdk.SetResourceBuilder(resourceBuilder); + tracerProviderBuilderBase.SetResourceBuilder(resourceBuilder); } return tracerProviderBuilder; @@ -80,9 +83,9 @@ public static TracerProviderBuilder SetResourceBuilder(this TracerProviderBuilde /// Returns for chaining. public static TracerProviderBuilder AddProcessor(this TracerProviderBuilder tracerProviderBuilder, BaseProcessor processor) { - if (tracerProviderBuilder is TracerProviderBuilderSdk tracerProviderBuilderSdk) + if (tracerProviderBuilder is TracerProviderBuilderBase tracerProviderBuilderBase) { - tracerProviderBuilderSdk.AddProcessor(processor); + tracerProviderBuilderBase.AddProcessor(processor); } return tracerProviderBuilder; @@ -99,19 +102,29 @@ public static TracerProviderBuilder AddProcessor(this TracerProviderBuilder trac /// Returns for chaining. public static TracerProviderBuilder AddLegacySource(this TracerProviderBuilder tracerProviderBuilder, string operationName) { - if (tracerProviderBuilder is TracerProviderBuilderSdk tracerProviderBuilderSdk) + if (tracerProviderBuilder is TracerProviderBuilderBase tracerProviderBuilderBase) { - tracerProviderBuilderSdk.AddLegacySource(operationName); + tracerProviderBuilderBase.AddLegacySource(operationName); } return tracerProviderBuilder; } + /// + /// Run the given actions to initialize the . + /// + /// . + /// . public static TracerProvider Build(this TracerProviderBuilder tracerProviderBuilder) { - if (tracerProviderBuilder is TracerProviderBuilderSdk tracerProviderBuilderSdk) + if (tracerProviderBuilder is IDeferredTracerBuilder) + { + throw new NotSupportedException("DeferredTracerBuilder requires a ServiceProvider to build."); + } + + if (tracerProviderBuilder is TracerProviderBuilderBase tracerProviderBuilderBase) { - return tracerProviderBuilderSdk.Build(); + return tracerProviderBuilderBase.Build(); } return null; diff --git a/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs b/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs index dbff3513b2c..6671496e8e8 100644 --- a/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs +++ b/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs @@ -14,211 +14,9 @@ // limitations under the License. // -using System; -using System.Collections.Generic; -using System.Diagnostics; -using OpenTelemetry.Resources; - namespace OpenTelemetry.Trace { - /// - /// Build TracerProvider with Resource, Sampler, Processors and Instrumentation. - /// - public class TracerProviderBuilderSdk : TracerProviderBuilder + internal class TracerProviderBuilderSdk : TracerProviderBuilderBase { - private readonly List instrumentationFactories = new List(); - private readonly List> processors = new List>(); - private readonly List sources = new List(); - private readonly Dictionary legacyActivityOperationNames = new Dictionary(StringComparer.OrdinalIgnoreCase); - private ResourceBuilder resourceBuilder = ResourceBuilder.CreateDefault(); - private Sampler sampler = new ParentBasedSampler(new AlwaysOnSampler()); - - /// - /// Adds an instrumentation to the provider. - /// - /// Type of instrumentation class. - /// Function that builds instrumentation. - /// Returns for chaining. - public override TracerProviderBuilder AddInstrumentation( - Func instrumentationFactory) - where TInstrumentation : class - { - if (instrumentationFactory == null) - { - throw new ArgumentNullException(nameof(instrumentationFactory)); - } - - this.instrumentationFactories.Add( - new InstrumentationFactory( - typeof(TInstrumentation).Name, - "semver:" + typeof(TInstrumentation).Assembly.GetName().Version, - instrumentationFactory)); - - return this; - } - - /// - /// Adds given activitysource names to the list of subscribed sources. - /// - /// Activity source names. - /// Returns for chaining. - public override TracerProviderBuilder AddSource(params string[] names) - { - if (names == null) - { - throw new ArgumentNullException(nameof(names)); - } - - foreach (var name in names) - { - if (string.IsNullOrWhiteSpace(name)) - { - throw new ArgumentException($"{nameof(names)} contains null or whitespace string."); - } - - // TODO: We need to fix the listening model. - // Today it ignores version. - this.sources.Add(name); - } - - return this; - } - - /// - /// Sets whether the status of - /// should be set to Status.Error when it ended abnormally due to an unhandled exception. - /// - /// Enabled or not. - /// Returns for chaining. - internal TracerProviderBuilder SetErrorStatusOnException(bool enabled) - { - ExceptionProcessor existingExceptionProcessor = null; - - if (this.processors.Count > 0) - { - existingExceptionProcessor = this.processors[0] as ExceptionProcessor; - } - - if (enabled) - { - if (existingExceptionProcessor == null) - { - try - { - this.processors.Insert(0, new ExceptionProcessor()); - } - catch (Exception ex) - { - throw new NotSupportedException("SetErrorStatusOnException is not supported on this platform.", ex); - } - } - } - else - { - if (existingExceptionProcessor != null) - { - this.processors.RemoveAt(0); - existingExceptionProcessor.Dispose(); - } - } - - return this; - } - - /// - /// Sets sampler. - /// - /// Sampler instance. - /// Returns for chaining. - internal TracerProviderBuilder SetSampler(Sampler sampler) - { - this.sampler = sampler ?? throw new ArgumentNullException(nameof(sampler)); - return this; - } - - /// - /// Sets the from which the Resource associated with - /// this provider is built from. Overwrites currently set ResourceBuilder. - /// - /// from which Resource will be built. - /// Returns for chaining. - internal TracerProviderBuilder SetResourceBuilder(ResourceBuilder resourceBuilder) - { - this.resourceBuilder = resourceBuilder ?? throw new ArgumentNullException(nameof(resourceBuilder)); - return this; - } - - /// - /// Adds processor to the provider. - /// - /// Activity processor to add. - /// Returns for chaining. - internal TracerProviderBuilder AddProcessor(BaseProcessor processor) - { - if (processor == null) - { - throw new ArgumentNullException(nameof(processor)); - } - - this.processors.Add(processor); - - return this; - } - - /// - /// Adds a listener for objects created with the given operation name to the . - /// - /// - /// This is provided to capture legacy objects created without using the API. - /// - /// Operation name of the objects to capture. - /// Returns for chaining. - internal TracerProviderBuilder AddLegacySource(string operationName) - { - if (string.IsNullOrWhiteSpace(operationName)) - { - throw new ArgumentException($"{nameof(operationName)} contains null or whitespace string."); - } - - this.legacyActivityOperationNames[operationName] = true; - - return this; - } - - internal TracerProvider Build() - { - return new TracerProviderSdk( - this.resourceBuilder.Build(), - this.sources, - this.instrumentationFactories, - this.sampler, - this.processors, - this.legacyActivityOperationNames); - } - - protected TracerProviderBuilder AddInstrumentation( - string instrumentationName, - string instrumentationVersion, - Func instrumentationFactory) - { - this.instrumentationFactories.Add( - new InstrumentationFactory(instrumentationName, instrumentationVersion, instrumentationFactory)); - - return this; - } - - internal readonly struct InstrumentationFactory - { - public readonly string Name; - public readonly string Version; - public readonly Func Factory; - - internal InstrumentationFactory(string name, string version, Func factory) - { - this.Name = name; - this.Version = version; - this.Factory = factory; - } - } } } diff --git a/src/OpenTelemetry/Trace/TracerProviderSdk.cs b/src/OpenTelemetry/Trace/TracerProviderSdk.cs index 82c2ec18a83..0d6d2e89c18 100644 --- a/src/OpenTelemetry/Trace/TracerProviderSdk.cs +++ b/src/OpenTelemetry/Trace/TracerProviderSdk.cs @@ -40,7 +40,7 @@ internal class TracerProviderSdk : TracerProvider internal TracerProviderSdk( Resource resource, IEnumerable sources, - IEnumerable instrumentationFactories, + IEnumerable instrumentationFactories, Sampler sampler, List> processors, Dictionary legacyActivityOperationNames) From c5cf8da47e2be761761e3e54632f11e3c27b6360 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 17 Mar 2021 18:01:10 -0700 Subject: [PATCH 09/16] Removed build from IDeferredTracerBuilder. --- .../Trace/TracerProviderBuilderExtensions.cs | 4 +- .../Trace/TracerProviderBuilderHosting.cs | 56 +++++++++---------- .../.publicApi/net461/PublicAPI.Unshipped.txt | 1 - .../netstandard2.0/PublicAPI.Unshipped.txt | 1 - .../Trace/IDeferredTracerBuilder.cs | 7 --- 5 files changed, 30 insertions(+), 39 deletions(-) diff --git a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs index d3c66bfae03..dc252cd90bf 100644 --- a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs @@ -99,9 +99,9 @@ public static TracerProviderBuilder Configure(this TracerProviderBuilder tracerP /// . public static TracerProvider Build(this TracerProviderBuilder tracerProviderBuilder, IServiceProvider serviceProvider) { - if (tracerProviderBuilder is IDeferredTracerBuilder deferredTracerBuilder) + if (tracerProviderBuilder is TracerProviderBuilderHosting tracerProviderBuilderHosting) { - return deferredTracerBuilder.Build(serviceProvider); + return tracerProviderBuilderHosting.Build(serviceProvider); } if (tracerProviderBuilder is TracerProviderBuilderBase tracerProviderBuilderBase) diff --git a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderHosting.cs b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderHosting.cs index a76ca52aa01..af80a494241 100644 --- a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderHosting.cs +++ b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderHosting.cs @@ -52,34 +52,6 @@ TracerProviderBuilder IDeferredTracerBuilder.Configure(Action serviceProvider.GetRequiredService(instrumentationFactory.Type)); - } - - foreach (Type processorType in this.processorTypes) - { - this.AddProcessor((BaseProcessor)serviceProvider.GetRequiredService(processorType)); - } - - if (this.samplerType != null) - { - this.SetSampler((Sampler)serviceProvider.GetRequiredService(this.samplerType)); - } - - foreach (Action configureAction in this.configurationActions) - { - configureAction(serviceProvider, this); - } - - return ((TracerProviderBuilderBase)this).Build(); - } - internal TracerProviderBuilder AddInstrumentation( Func instrumentationFactory) where TInstrumentation : class @@ -112,6 +84,34 @@ internal TracerProviderBuilder SetSampler() return this; } + internal TracerProvider Build(IServiceProvider serviceProvider) + { + foreach (InstrumentationFactory instrumentationFactory in this.instrumentationFactories) + { + this.AddInstrumentation( + instrumentationFactory.Name, + instrumentationFactory.Version, + () => serviceProvider.GetRequiredService(instrumentationFactory.Type)); + } + + foreach (Type processorType in this.processorTypes) + { + this.AddProcessor((BaseProcessor)serviceProvider.GetRequiredService(processorType)); + } + + if (this.samplerType != null) + { + this.SetSampler((Sampler)serviceProvider.GetRequiredService(this.samplerType)); + } + + foreach (Action configureAction in this.configurationActions) + { + configureAction(serviceProvider, this); + } + + return ((TracerProviderBuilderBase)this).Build(); + } + internal readonly struct InstrumentationFactory { public readonly string Name; diff --git a/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt index 0d15f643400..74c0d6467b5 100644 --- a/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt @@ -8,7 +8,6 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeScopes.set -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.get -> bool OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.set -> void OpenTelemetry.Trace.IDeferredTracerBuilder -OpenTelemetry.Trace.IDeferredTracerBuilder.Build(System.IServiceProvider serviceProvider) -> OpenTelemetry.Trace.TracerProvider OpenTelemetry.Trace.IDeferredTracerBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void OpenTelemetry.Trace.TracerProviderBuilderBase diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 0d15f643400..74c0d6467b5 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -8,7 +8,6 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeScopes.set -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.get -> bool OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.set -> void OpenTelemetry.Trace.IDeferredTracerBuilder -OpenTelemetry.Trace.IDeferredTracerBuilder.Build(System.IServiceProvider serviceProvider) -> OpenTelemetry.Trace.TracerProvider OpenTelemetry.Trace.IDeferredTracerBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void OpenTelemetry.Trace.TracerProviderBuilderBase diff --git a/src/OpenTelemetry/Trace/IDeferredTracerBuilder.cs b/src/OpenTelemetry/Trace/IDeferredTracerBuilder.cs index 1d99d3a8ff6..5cf9a9d0464 100644 --- a/src/OpenTelemetry/Trace/IDeferredTracerBuilder.cs +++ b/src/OpenTelemetry/Trace/IDeferredTracerBuilder.cs @@ -29,12 +29,5 @@ public interface IDeferredTracerBuilder /// Configuration callback. /// The supplied for chaining. TracerProviderBuilder Configure(Action configure); - - /// - /// Run the configured actions to initialize the . - /// - /// . - /// . - TracerProvider Build(IServiceProvider serviceProvider); } } From f114261bccb5af33eaef9fd5e65be50e6f460eae Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 17 Mar 2021 22:33:35 -0700 Subject: [PATCH 10/16] Code review. --- .../JaegerExporterHelperExtensions.cs | 4 ++-- .../ZipkinExporterHelperExtensions.cs | 4 ++-- .../Trace/TracerProviderBuilderExtensions.cs | 4 ++-- .../Trace/TracerProviderBuilderHosting.cs | 4 ++-- .../.publicApi/net452/PublicAPI.Unshipped.txt | 5 ++--- .../.publicApi/net46/PublicAPI.Unshipped.txt | 5 ++--- .../.publicApi/net461/PublicAPI.Unshipped.txt | 4 ++-- .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 4 ++-- ...TracerBuilder.cs => IDeferredTracerProviderBuilder.cs} | 8 +++++--- .../Trace/TracerProviderBuilderExtensions.cs | 2 +- 10 files changed, 22 insertions(+), 22 deletions(-) rename src/OpenTelemetry/Trace/{IDeferredTracerBuilder.cs => IDeferredTracerProviderBuilder.cs} (78%) diff --git a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs index 464649f3fdd..827b35047b7 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs @@ -38,9 +38,9 @@ public static TracerProviderBuilder AddJaegerExporter(this TracerProviderBuilder throw new ArgumentNullException(nameof(builder)); } - if (builder is IDeferredTracerBuilder deferredTracerBuilder) + if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) { - return deferredTracerBuilder.Configure((sp, builder) => + return deferredTracerProviderBuilder.Configure((sp, builder) => { AddJaegerExporter(builder, sp.GetOptions(), configure); }); diff --git a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs index 5daef5c36d0..78c8ca3adcf 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs @@ -38,9 +38,9 @@ public static TracerProviderBuilder AddZipkinExporter(this TracerProviderBuilder throw new ArgumentNullException(nameof(builder)); } - if (builder is IDeferredTracerBuilder deferredTracerBuilder) + if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) { - return deferredTracerBuilder.Configure((sp, builder) => + return deferredTracerProviderBuilder.Configure((sp, builder) => { AddZipkinExporter(builder, sp.GetOptions(), configure); }); diff --git a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs index dc252cd90bf..16ecfbb43b9 100644 --- a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderExtensions.cs @@ -83,9 +83,9 @@ public static TracerProviderBuilder SetSampler(this TracerProviderBuilder tra /// The supplied for chaining. public static TracerProviderBuilder Configure(this TracerProviderBuilder tracerProviderBuilder, Action configure) { - if (tracerProviderBuilder is IDeferredTracerBuilder deferredTracerBuilder) + if (tracerProviderBuilder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) { - deferredTracerBuilder.Configure(configure); + deferredTracerProviderBuilder.Configure(configure); } return tracerProviderBuilder; diff --git a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderHosting.cs b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderHosting.cs index af80a494241..437f94cb5f2 100644 --- a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderHosting.cs +++ b/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderHosting.cs @@ -24,7 +24,7 @@ namespace OpenTelemetry.Trace /// /// A with support for deferred initialization using for dependency injection. /// - public class TracerProviderBuilderHosting : TracerProviderBuilderBase, IDeferredTracerBuilder + public class TracerProviderBuilderHosting : TracerProviderBuilderBase, IDeferredTracerProviderBuilder { private readonly List instrumentationFactories = new List(); private readonly List processorTypes = new List(); @@ -41,7 +41,7 @@ internal TracerProviderBuilderHosting(IServiceCollection services) /// public IServiceCollection Services { get; } - TracerProviderBuilder IDeferredTracerBuilder.Configure(Action configure) + TracerProviderBuilder IDeferredTracerProviderBuilder.Configure(Action configure) { if (configure == null) { diff --git a/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt index 465965ee5a7..31400f33192 100644 --- a/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt @@ -1,6 +1,5 @@ -OpenTelemetry.Trace.IDeferredTracerBuilder -OpenTelemetry.Trace.IDeferredTracerBuilder.Build(System.IServiceProvider serviceProvider) -> OpenTelemetry.Trace.TracerProvider -OpenTelemetry.Trace.IDeferredTracerBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.IDeferredTracerProviderBuilder +OpenTelemetry.Trace.IDeferredTracerProviderBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void OpenTelemetry.Trace.TracerProviderBuilderBase OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt index 465965ee5a7..31400f33192 100644 --- a/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt @@ -1,6 +1,5 @@ -OpenTelemetry.Trace.IDeferredTracerBuilder -OpenTelemetry.Trace.IDeferredTracerBuilder.Build(System.IServiceProvider serviceProvider) -> OpenTelemetry.Trace.TracerProvider -OpenTelemetry.Trace.IDeferredTracerBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.IDeferredTracerProviderBuilder +OpenTelemetry.Trace.IDeferredTracerProviderBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void OpenTelemetry.Trace.TracerProviderBuilderBase OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt index 74c0d6467b5..113b62bc497 100644 --- a/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt @@ -7,8 +7,8 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeScopes.get -> bool OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeScopes.set -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.get -> bool OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.set -> void -OpenTelemetry.Trace.IDeferredTracerBuilder -OpenTelemetry.Trace.IDeferredTracerBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.IDeferredTracerProviderBuilder +OpenTelemetry.Trace.IDeferredTracerProviderBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void OpenTelemetry.Trace.TracerProviderBuilderBase OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 74c0d6467b5..113b62bc497 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -7,8 +7,8 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeScopes.get -> bool OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeScopes.set -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.get -> bool OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.set -> void -OpenTelemetry.Trace.IDeferredTracerBuilder -OpenTelemetry.Trace.IDeferredTracerBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.IDeferredTracerProviderBuilder +OpenTelemetry.Trace.IDeferredTracerProviderBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void OpenTelemetry.Trace.TracerProviderBuilderBase OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry/Trace/IDeferredTracerBuilder.cs b/src/OpenTelemetry/Trace/IDeferredTracerProviderBuilder.cs similarity index 78% rename from src/OpenTelemetry/Trace/IDeferredTracerBuilder.cs rename to src/OpenTelemetry/Trace/IDeferredTracerProviderBuilder.cs index 5cf9a9d0464..a31d74acda7 100644 --- a/src/OpenTelemetry/Trace/IDeferredTracerBuilder.cs +++ b/src/OpenTelemetry/Trace/IDeferredTracerProviderBuilder.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,9 +19,11 @@ namespace OpenTelemetry.Trace { /// - /// Describes a tracer builder tha support deferred initialization using a to perform dependency injection. + /// Describes a tracer provider builder that supports deferred + /// initialization using an to perform + /// dependency injection. /// - public interface IDeferredTracerBuilder + public interface IDeferredTracerProviderBuilder { /// /// Register a callback action to configure the during initialization. diff --git a/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs index e64f0c6883c..a5e8c13cd06 100644 --- a/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs @@ -117,7 +117,7 @@ public static TracerProviderBuilder AddLegacySource(this TracerProviderBuilder t /// . public static TracerProvider Build(this TracerProviderBuilder tracerProviderBuilder) { - if (tracerProviderBuilder is IDeferredTracerBuilder) + if (tracerProviderBuilder is IDeferredTracerProviderBuilder) { throw new NotSupportedException("DeferredTracerBuilder requires a ServiceProvider to build."); } From beaeb938f1b6e57b7094018c62ba0ceb7d97c559 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 18 Mar 2021 20:01:34 -0700 Subject: [PATCH 11/16] Tweaks. --- .../Trace/TracerProviderBuilder.cs | 2 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 2 - .../CHANGELOG.md | 5 +++ .../TracerProviderBuilderHosting.cs | 41 +++++++++---------- .../.publicApi/net452/PublicAPI.Unshipped.txt | 1 + .../.publicApi/net46/PublicAPI.Unshipped.txt | 1 + .../.publicApi/net461/PublicAPI.Unshipped.txt | 2 + .../netstandard2.0/PublicAPI.Unshipped.txt | 2 + src/OpenTelemetry/CHANGELOG.md | 4 ++ .../Trace/IDeferredTracerProviderBuilder.cs | 7 ++++ .../Trace/TracerProviderBuilderBase.cs | 26 ++++++------ .../HostingExtensionsTests.cs | 16 ++++---- 12 files changed, 65 insertions(+), 44 deletions(-) rename src/OpenTelemetry.Extensions.Hosting/{Trace => Implementation}/TracerProviderBuilderHosting.cs (83%) diff --git a/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs b/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs index ed2c1431dc4..6edeaaaea40 100644 --- a/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs +++ b/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs @@ -23,7 +23,7 @@ namespace OpenTelemetry.Trace public abstract class TracerProviderBuilder { /// - /// Adds an instrumentation to the provider. + /// Adds instrumentation to the provider. /// /// Type of instrumentation class. /// Function that builds instrumentation. diff --git a/src/OpenTelemetry.Extensions.Hosting/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Hosting/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index adda9dee43d..364f10146db 100644 --- a/src/OpenTelemetry.Extensions.Hosting/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Hosting/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,7 +1,5 @@ Microsoft.Extensions.DependencyInjection.OpenTelemetryServicesExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions -OpenTelemetry.Trace.TracerProviderBuilderHosting -OpenTelemetry.Trace.TracerProviderBuilderHosting.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection static Microsoft.Extensions.DependencyInjection.OpenTelemetryServicesExtensions.AddOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection static Microsoft.Extensions.DependencyInjection.OpenTelemetryServicesExtensions.AddOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md index f47b5801ad1..219d0a98aea 100644 --- a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Added `AddInstrumentation`, `AddProcessor`, `SetSampler`, and + `Configure` extensions to support dependency injection through the + OpenTelemetry.Extensions.Hosting `TracerProviderBuilder`. + ([#1889](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1889)) + ## 1.0.0-rc2 Released 2021-Jan-29 diff --git a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderHosting.cs b/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs similarity index 83% rename from src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderHosting.cs rename to src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs index 437f94cb5f2..08d223b76c7 100644 --- a/src/OpenTelemetry.Extensions.Hosting/Trace/TracerProviderBuilderHosting.cs +++ b/src/OpenTelemetry.Extensions.Hosting/Implementation/TracerProviderBuilderHosting.cs @@ -24,35 +24,21 @@ namespace OpenTelemetry.Trace /// /// A with support for deferred initialization using for dependency injection. /// - public class TracerProviderBuilderHosting : TracerProviderBuilderBase, IDeferredTracerProviderBuilder + internal class TracerProviderBuilderHosting : TracerProviderBuilderBase, IDeferredTracerProviderBuilder { private readonly List instrumentationFactories = new List(); private readonly List processorTypes = new List(); private readonly List> configurationActions = new List>(); private Type samplerType; - internal TracerProviderBuilderHosting(IServiceCollection services) + public TracerProviderBuilderHosting(IServiceCollection services) { this.Services = services ?? throw new ArgumentNullException(nameof(services)); } - /// - /// Gets the application services. - /// public IServiceCollection Services { get; } - TracerProviderBuilder IDeferredTracerProviderBuilder.Configure(Action configure) - { - if (configure == null) - { - throw new ArgumentNullException(nameof(configure)); - } - - this.configurationActions.Add(configure); - return this; - } - - internal TracerProviderBuilder AddInstrumentation( + public TracerProviderBuilder AddInstrumentation( Func instrumentationFactory) where TInstrumentation : class { @@ -70,21 +56,32 @@ internal TracerProviderBuilder AddInstrumentation( return this; } - internal TracerProviderBuilder AddProcessor() + public TracerProviderBuilder AddProcessor() where T : BaseProcessor { this.processorTypes.Add(typeof(T)); return this; } - internal TracerProviderBuilder SetSampler() + public TracerProviderBuilder SetSampler() where T : Sampler { this.samplerType = typeof(T); return this; } - internal TracerProvider Build(IServiceProvider serviceProvider) + public TracerProviderBuilder Configure(Action configure) + { + if (configure == null) + { + throw new ArgumentNullException(nameof(configure)); + } + + this.configurationActions.Add(configure); + return this; + } + + public TracerProvider Build(IServiceProvider serviceProvider) { foreach (InstrumentationFactory instrumentationFactory in this.instrumentationFactories) { @@ -109,10 +106,10 @@ internal TracerProvider Build(IServiceProvider serviceProvider) configureAction(serviceProvider, this); } - return ((TracerProviderBuilderBase)this).Build(); + return this.Build(); } - internal readonly struct InstrumentationFactory + private readonly struct InstrumentationFactory { public readonly string Name; public readonly string Version; diff --git a/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt index 31400f33192..67d8b08882c 100644 --- a/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net452/PublicAPI.Unshipped.txt @@ -3,6 +3,7 @@ OpenTelemetry.Trace.IDeferredTracerProviderBuilder.Configure(System.Action void OpenTelemetry.Trace.TracerProviderBuilderBase OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.TracerProvider OpenTelemetry.Trace.TracerProviderBuilderBase.TracerProviderBuilderBase() -> void override OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string[] names) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt index 31400f33192..67d8b08882c 100644 --- a/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net46/PublicAPI.Unshipped.txt @@ -3,6 +3,7 @@ OpenTelemetry.Trace.IDeferredTracerProviderBuilder.Configure(System.Action void OpenTelemetry.Trace.TracerProviderBuilderBase OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.TracerProvider OpenTelemetry.Trace.TracerProviderBuilderBase.TracerProviderBuilderBase() -> void override OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string[] names) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt index 113b62bc497..c53483fc123 100644 --- a/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net461/PublicAPI.Unshipped.txt @@ -9,9 +9,11 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.get -> bool OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.set -> void OpenTelemetry.Trace.IDeferredTracerProviderBuilder OpenTelemetry.Trace.IDeferredTracerProviderBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.IDeferredTracerProviderBuilder.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void OpenTelemetry.Trace.TracerProviderBuilderBase OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.TracerProvider OpenTelemetry.Trace.TracerProviderBuilderBase.TracerProviderBuilderBase() -> void override OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string[] names) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 113b62bc497..c53483fc123 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -9,9 +9,11 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.get -> bool OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ParseStateValues.set -> void OpenTelemetry.Trace.IDeferredTracerProviderBuilder OpenTelemetry.Trace.IDeferredTracerProviderBuilder.Configure(System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.IDeferredTracerProviderBuilder.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection OpenTelemetry.Trace.ParentBasedSampler.ParentBasedSampler(OpenTelemetry.Trace.Sampler rootSampler, OpenTelemetry.Trace.Sampler remoteParentSampled = null, OpenTelemetry.Trace.Sampler remoteParentNotSampled = null, OpenTelemetry.Trace.Sampler localParentSampled = null, OpenTelemetry.Trace.Sampler localParentNotSampled = null) -> void OpenTelemetry.Trace.TracerProviderBuilderBase OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(string instrumentationName, string instrumentationVersion, System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.TracerProvider OpenTelemetry.Trace.TracerProviderBuilderBase.TracerProviderBuilderBase() -> void override OpenTelemetry.Trace.TracerProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string[] names) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 140f163f6de..907a3c32113 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -43,6 +43,10 @@ please check the latest changes `ParentBasedSampler` will no longer explicitly consider Activity links. ([#1851](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1851)) +* Added `IDeferredTracerProviderBuilder` and `TracerProviderBuilderBase` to + support dependency injection through OpenTelemetry.Extensions.Hosting. + ([#1889](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1889)) + ## 1.0.1 Released 2021-Feb-10 diff --git a/src/OpenTelemetry/Trace/IDeferredTracerProviderBuilder.cs b/src/OpenTelemetry/Trace/IDeferredTracerProviderBuilder.cs index a31d74acda7..633f0a09d3b 100644 --- a/src/OpenTelemetry/Trace/IDeferredTracerProviderBuilder.cs +++ b/src/OpenTelemetry/Trace/IDeferredTracerProviderBuilder.cs @@ -15,6 +15,9 @@ // using System; +#if NET461_OR_GREATER || NETSTANDARD2_0 +using Microsoft.Extensions.DependencyInjection; +#endif namespace OpenTelemetry.Trace { @@ -25,6 +28,10 @@ namespace OpenTelemetry.Trace /// public interface IDeferredTracerProviderBuilder { +#if NET461_OR_GREATER || NETSTANDARD2_0 + IServiceCollection Services { get; } +#endif + /// /// Register a callback action to configure the during initialization. /// diff --git a/src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs b/src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs index a2c9dce71a8..3066fe7fb90 100644 --- a/src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs +++ b/src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs @@ -37,12 +37,7 @@ protected TracerProviderBuilderBase() { } - /// - /// Adds an instrumentation to the provider. - /// - /// Type of instrumentation class. - /// Function that builds instrumentation. - /// Returns for chaining. + /// public override TracerProviderBuilder AddInstrumentation( Func instrumentationFactory) where TInstrumentation : class @@ -61,11 +56,7 @@ public override TracerProviderBuilder AddInstrumentation( return this; } - /// - /// Adds given activitysource names to the list of subscribed sources. - /// - /// Activity source names. - /// Returns for chaining. + /// public override TracerProviderBuilder AddSource(params string[] names) { if (names == null) @@ -189,7 +180,11 @@ internal TracerProviderBuilder AddLegacySource(string operationName) return this; } - internal TracerProvider Build() + /// + /// Run the configured actions to initialize the . + /// + /// . + protected TracerProvider Build() { return new TracerProviderSdk( this.resourceBuilder.Build(), @@ -200,6 +195,13 @@ internal TracerProvider Build() this.legacyActivityOperationNames); } + /// + /// Adds instrumentation to the provider. + /// + /// Instrumentation name. + /// Instrumentation version. + /// Function that builds instrumentation. + /// Returns for chaining. protected TracerProviderBuilder AddInstrumentation( string instrumentationName, string instrumentationVersion, diff --git a/test/OpenTelemetry.Extensions.Hosting.Tests/HostingExtensionsTests.cs b/test/OpenTelemetry.Extensions.Hosting.Tests/HostingExtensionsTests.cs index 9a8ff39917e..34952c6086d 100644 --- a/test/OpenTelemetry.Extensions.Hosting.Tests/HostingExtensionsTests.cs +++ b/test/OpenTelemetry.Extensions.Hosting.Tests/HostingExtensionsTests.cs @@ -87,9 +87,10 @@ public void AddOpenTelemetryTracerProvider_ServiceProviderArgument_ServicesRegis var services = new ServiceCollection(); services.AddSingleton(testInstrumentation); - services.AddOpenTelemetryTracing((provider, builder) => + services.AddOpenTelemetryTracing(builder => { - builder.AddInstrumentation(() => provider.GetRequiredService()); + builder.Configure( + (sp, b) => b.AddInstrumentation(() => sp.GetRequiredService())); }); var serviceProvider = services.BuildServiceProvider(); @@ -108,12 +109,13 @@ public void AddOpenTelemetryTracerProvider_ServiceProviderArgument_ServicesRegis public void AddOpenTelemetryTracerProvider_BadArgs_NullServiceCollection() { ServiceCollection services = null; - Assert.Throws(() => services.AddOpenTelemetryTracing()); + Assert.Throws(() => services.AddOpenTelemetryTracing(null)); Assert.Throws(() => - services.AddOpenTelemetryTracing((provider, builder) => - { - builder.AddInstrumentation(() => provider.GetRequiredService()); - })); + services.AddOpenTelemetryTracing(builder => + { + builder.Configure( + (sp, b) => b.AddInstrumentation(() => sp.GetRequiredService())); + })); } internal class TestInstrumentation : IDisposable From 3f264b6c1e5a9e57ef7a6a1003fcde4f8ac11e5f Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 18 Mar 2021 20:10:51 -0700 Subject: [PATCH 12/16] Lint fix. --- src/OpenTelemetry/Internal/ServiceProviderExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry/Internal/ServiceProviderExtensions.cs b/src/OpenTelemetry/Internal/ServiceProviderExtensions.cs index 4506f09e389..d6c53d4ae66 100644 --- a/src/OpenTelemetry/Internal/ServiceProviderExtensions.cs +++ b/src/OpenTelemetry/Internal/ServiceProviderExtensions.cs @@ -21,7 +21,7 @@ namespace System { /// - /// Extension methods for OpenTelemetry depedency injection support. + /// Extension methods for OpenTelemetry dependency injection support. /// internal static class ServiceProviderExtensions { From 415f1339eb76a21ecfdcf25a523d3ec5e292f1a8 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 18 Mar 2021 20:54:25 -0700 Subject: [PATCH 13/16] Bug fixes. --- src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs | 4 ++-- src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs index a5e8c13cd06..9db834cff2e 100644 --- a/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Trace/TracerProviderBuilderExtensions.cs @@ -122,9 +122,9 @@ public static TracerProvider Build(this TracerProviderBuilder tracerProviderBuil throw new NotSupportedException("DeferredTracerBuilder requires a ServiceProvider to build."); } - if (tracerProviderBuilder is TracerProviderBuilderBase tracerProviderBuilderBase) + if (tracerProviderBuilder is TracerProviderBuilderSdk tracerProviderBuilderSdk) { - return tracerProviderBuilderBase.Build(); + return tracerProviderBuilderSdk.BuildSdk(); } return null; diff --git a/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs b/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs index 6671496e8e8..18dae6e2ffe 100644 --- a/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs +++ b/src/OpenTelemetry/Trace/TracerProviderBuilderSdk.cs @@ -18,5 +18,6 @@ namespace OpenTelemetry.Trace { internal class TracerProviderBuilderSdk : TracerProviderBuilderBase { + internal TracerProvider BuildSdk() => this.Build(); } } From 9f28e45053bf28416aa1587bb165a82b1e9be522 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 18 Mar 2021 21:09:34 -0700 Subject: [PATCH 14/16] Put back internal ctor on TracerProviderBuilder. --- src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs b/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs index 6edeaaaea40..cb9cfd4bf7d 100644 --- a/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs +++ b/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs @@ -22,6 +22,10 @@ namespace OpenTelemetry.Trace /// public abstract class TracerProviderBuilder { + internal TracerProviderBuilder() + { + } + /// /// Adds instrumentation to the provider. /// From 3892b5868520f6739b46ccdb671d93904a4901d0 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 18 Mar 2021 21:15:33 -0700 Subject: [PATCH 15/16] Moved build to bottom of file. Fixed up warnings. --- .../.publicApi/net452/PublicAPI.Unshipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 1 + .../Trace/TracerProviderBuilder.cs | 5 +++- .../Trace/TracerProviderBuilderBase.cs | 30 +++++++++---------- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/OpenTelemetry.Api/.publicApi/net452/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Api/.publicApi/net452/PublicAPI.Unshipped.txt index e69de29bb2d..877fcaee8d0 100644 --- a/src/OpenTelemetry.Api/.publicApi/net452/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Api/.publicApi/net452/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +OpenTelemetry.Trace.TracerProviderBuilder.TracerProviderBuilder() -> void \ No newline at end of file diff --git a/src/OpenTelemetry.Api/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Api/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2d..877fcaee8d0 100644 --- a/src/OpenTelemetry.Api/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Api/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +OpenTelemetry.Trace.TracerProviderBuilder.TracerProviderBuilder() -> void \ No newline at end of file diff --git a/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs b/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs index cb9cfd4bf7d..dc8e0d57efb 100644 --- a/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs +++ b/src/OpenTelemetry.Api/Trace/TracerProviderBuilder.cs @@ -22,7 +22,10 @@ namespace OpenTelemetry.Trace /// public abstract class TracerProviderBuilder { - internal TracerProviderBuilder() + /// + /// Initializes a new instance of the class. + /// + protected TracerProviderBuilder() { } diff --git a/src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs b/src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs index 3066fe7fb90..f0e6fc3b50f 100644 --- a/src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs +++ b/src/OpenTelemetry/Trace/TracerProviderBuilderBase.cs @@ -180,21 +180,6 @@ internal TracerProviderBuilder AddLegacySource(string operationName) return this; } - /// - /// Run the configured actions to initialize the . - /// - /// . - protected TracerProvider Build() - { - return new TracerProviderSdk( - this.resourceBuilder.Build(), - this.sources, - this.instrumentationFactories, - this.sampler, - this.processors, - this.legacyActivityOperationNames); - } - /// /// Adds instrumentation to the provider. /// @@ -213,6 +198,21 @@ protected TracerProviderBuilder AddInstrumentation( return this; } + /// + /// Run the configured actions to initialize the . + /// + /// . + protected TracerProvider Build() + { + return new TracerProviderSdk( + this.resourceBuilder.Build(), + this.sources, + this.instrumentationFactories, + this.sampler, + this.processors, + this.legacyActivityOperationNames); + } + internal readonly struct InstrumentationFactory { public readonly string Name; From 0ce3374c8e67818a202e133619bb63c07bff818e Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 25 Mar 2021 09:16:22 -0700 Subject: [PATCH 16/16] Restored changelog text. --- src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md index 01891ca8a08..d9622840be6 100644 --- a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Added `AddInstrumentation`, `AddProcessor`, `SetSampler`, and + `Configure` extensions to support dependency injection through the + OpenTelemetry.Extensions.Hosting `TracerProviderBuilder`. + ([#1889](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1889)) + ## 1.0.0-rc3 Released 2021-Mar-19