From fb6463d25cf21c97af332c5592890e07766021f8 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 8 Sep 2022 12:08:25 -0700 Subject: [PATCH 01/34] [Traces + Logs] Clean up repo exporters to use new DI patterns (#3640) * Clean up trace & log exporters to use new DI patterns. * Doc updates. * Updates. * Updates. --- .../ConsoleExporterHelperExtensions.cs | 21 +++++----- .../ConsoleExporterLoggingExtensions.cs | 16 ++++++-- .../InMemoryExporterHelperExtensions.cs | 9 ----- .../JaegerExporterHelperExtensions.cs | 22 +++++----- .../OpenTelemetry.Exporter.Jaeger.csproj | 1 - .../CHANGELOG.md | 5 +++ .../OtlpLogExporterHelperExtensions.cs | 40 ++++++++++++++++--- .../OtlpTraceExporterHelperExtensions.cs | 19 ++++----- .../README.md | 5 ++- .../OpenTelemetry.Exporter.Zipkin.csproj | 1 - .../ZipkinExporterHelperExtensions.cs | 22 +++++----- .../IntegrationTests.cs | 1 - 12 files changed, 96 insertions(+), 66 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs index 56073eebb0e..2f5ed77ab4d 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs @@ -15,6 +15,8 @@ // using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Exporter; using OpenTelemetry.Internal; @@ -28,26 +30,21 @@ public static class ConsoleExporterHelperExtensions /// builder to use. /// Exporter configuration options. /// The instance of to chain the calls. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The objects should not be disposed.")] public static TracerProviderBuilder AddConsoleExporter(this TracerProviderBuilder builder, Action configure = null) { Guard.ThrowIfNull(builder); - if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + if (configure != null) { - return deferredTracerProviderBuilder.Configure((sp, builder) => - { - AddConsoleExporter(builder, sp.GetOptions(), configure); - }); + builder.ConfigureServices(services => services.Configure(configure)); } - return AddConsoleExporter(builder, new ConsoleExporterOptions(), configure); - } + return builder.ConfigureBuilder((sp, builder) => + { + var options = sp.GetRequiredService>().Value; - private static TracerProviderBuilder AddConsoleExporter(TracerProviderBuilder builder, ConsoleExporterOptions options, Action configure = null) - { - configure?.Invoke(options); - return builder.AddProcessor(new SimpleActivityExportProcessor(new ConsoleActivityExporter(options))); + builder.AddProcessor(new SimpleActivityExportProcessor(new ConsoleActivityExporter(options))); + }); } } } diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs index 6cec91dfed2..5e5de098833 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs @@ -15,6 +15,8 @@ // using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Exporter; using OpenTelemetry.Internal; @@ -32,9 +34,17 @@ public static OpenTelemetryLoggerOptions AddConsoleExporter(this OpenTelemetryLo { Guard.ThrowIfNull(loggerOptions); - var options = new ConsoleExporterOptions(); - configure?.Invoke(options); - return loggerOptions.AddProcessor(new SimpleLogRecordExportProcessor(new ConsoleLogRecordExporter(options))); + if (configure != null) + { + loggerOptions.ConfigureServices(services => services.Configure(configure)); + } + + return loggerOptions.ConfigureProvider((sp, provider) => + { + var options = sp.GetRequiredService>().Value; + + provider.AddProcessor(new SimpleLogRecordExportProcessor(new ConsoleLogRecordExporter(options))); + }); } } } diff --git a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterHelperExtensions.cs index db2de77d32a..ff183fa8dcf 100644 --- a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterHelperExtensions.cs @@ -29,20 +29,11 @@ public static class InMemoryExporterHelperExtensions /// builder to use. /// Collection which will be populated with the exported Activity. /// The instance of to chain the calls. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The objects should not be disposed.")] public static TracerProviderBuilder AddInMemoryExporter(this TracerProviderBuilder builder, ICollection exportedItems) { Guard.ThrowIfNull(builder); Guard.ThrowIfNull(exportedItems); - if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) - { - return deferredTracerProviderBuilder.Configure((sp, builder) => - { - builder.AddProcessor(new SimpleActivityExportProcessor(new InMemoryExporter(exportedItems))); - }); - } - return builder.AddProcessor(new SimpleActivityExportProcessor(new InMemoryExporter(exportedItems))); } } diff --git a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs index 41965dba98f..dec28c8c236 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs @@ -17,6 +17,8 @@ using System; using System.Net.Http; using System.Reflection; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Exporter; using OpenTelemetry.Internal; @@ -37,27 +39,25 @@ public static TracerProviderBuilder AddJaegerExporter(this TracerProviderBuilder { Guard.ThrowIfNull(builder); - if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + if (configure != null) { - return deferredTracerProviderBuilder.Configure((sp, builder) => - { - AddJaegerExporter(builder, sp.GetOptions(), configure, sp); - }); + builder.ConfigureServices(services => services.Configure(configure)); } - return AddJaegerExporter(builder, new JaegerExporterOptions(), configure, serviceProvider: null); + return builder.ConfigureBuilder((sp, builder) => + { + var options = sp.GetRequiredService>().Value; + + AddJaegerExporter(builder, options, sp); + }); } private static TracerProviderBuilder AddJaegerExporter( TracerProviderBuilder builder, JaegerExporterOptions options, - Action configure, IServiceProvider serviceProvider) { - configure?.Invoke(options); - - if (serviceProvider != null - && options.Protocol == JaegerExportProtocol.HttpBinaryThrift + if (options.Protocol == JaegerExportProtocol.HttpBinaryThrift && options.HttpClientFactory == JaegerExporterOptions.DefaultHttpClientFactory) { options.HttpClientFactory = () => diff --git a/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj b/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj index 4229bcc029b..abd411f0df3 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj +++ b/src/OpenTelemetry.Exporter.Jaeger/OpenTelemetry.Exporter.Jaeger.csproj @@ -24,7 +24,6 @@ - diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/CHANGELOG.md index a50f874209d..dc3bdd72318 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* `OtlpExporterOptions` can now be bound to `IConfiguation` and + `HttpClientFactory` may be used to manage the `HttpClient` instance used when + `HttpProtobuf` is configured + ([#3640](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3640)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/OtlpLogExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/OtlpLogExporterHelperExtensions.cs index 354563fabd7..0a5d2fee43f 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/OtlpLogExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/OtlpLogExporterHelperExtensions.cs @@ -15,6 +15,8 @@ // using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Exporter; using OpenTelemetry.Internal; @@ -28,6 +30,12 @@ public static class OtlpLogExporterHelperExtensions /// /// Adds OTLP Exporter as a configuration to the OpenTelemetry ILoggingBuilder. /// + /// + /// Note: automatically sets to . + /// /// options to use. /// Exporter configuration options. /// The instance of to chain the calls. @@ -35,21 +43,41 @@ public static OpenTelemetryLoggerOptions AddOtlpExporter(this OpenTelemetryLogge { Guard.ThrowIfNull(loggerOptions); - return AddOtlpExporter(loggerOptions, new OtlpExporterOptions(), configure); + loggerOptions.ParseStateValues = true; + + if (configure != null) + { + loggerOptions.ConfigureServices(services => services.Configure(configure)); + } + + return loggerOptions.ConfigureProvider((sp, provider) => + { + var options = sp.GetRequiredService>().Value; + + AddOtlpExporter(provider, options, sp); + }); } - private static OpenTelemetryLoggerOptions AddOtlpExporter(OpenTelemetryLoggerOptions loggerOptions, OtlpExporterOptions exporterOptions, Action configure = null) + private static void AddOtlpExporter( + OpenTelemetryLoggerProvider provider, + OtlpExporterOptions exporterOptions, + IServiceProvider serviceProvider) { - configure?.Invoke(exporterOptions); + exporterOptions.TryEnableIHttpClientFactoryIntegration(serviceProvider, "OtlpLogExporter"); + var otlpExporter = new OtlpLogExporter(exporterOptions); - loggerOptions.ParseStateValues = true; + if (exporterOptions.ExportProcessorType == ExportProcessorType.Simple) { - return loggerOptions.AddProcessor(new SimpleLogRecordExportProcessor(otlpExporter)); + provider.AddProcessor(new SimpleLogRecordExportProcessor(otlpExporter)); } else { - return loggerOptions.AddProcessor(new BatchLogRecordExportProcessor( + // TODO: exporterOptions.BatchExportProcessorOptions is + // BatchExportActivityProcessorOptions which is using tracing + // environment variables. There should probably be a dedicated + // setting for logs using BatchExportLogRecordProcessorOptions + provider.AddProcessor(new BatchLogRecordExportProcessor( otlpExporter, exporterOptions.BatchExportProcessorOptions.MaxQueueSize, exporterOptions.BatchExportProcessorOptions.ScheduledDelayMilliseconds, diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs index 6528bf8b02a..829e09525cb 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs @@ -16,6 +16,8 @@ using System; using System.Diagnostics; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Exporter; using OpenTelemetry.Internal; @@ -36,26 +38,25 @@ public static TracerProviderBuilder AddOtlpExporter(this TracerProviderBuilder b { Guard.ThrowIfNull(builder); - if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + if (configure != null) { - return deferredTracerProviderBuilder.Configure((sp, builder) => - { - AddOtlpExporter(builder, sp.GetOptions(), configure, sp); - }); + builder.ConfigureServices(services => services.Configure(configure)); } - return AddOtlpExporter(builder, new OtlpExporterOptions(), configure, serviceProvider: null); + return builder.ConfigureBuilder((sp, builder) => + { + var options = sp.GetRequiredService>().Value; + + AddOtlpExporter(builder, options, sp); + }); } internal static TracerProviderBuilder AddOtlpExporter( TracerProviderBuilder builder, OtlpExporterOptions exporterOptions, - Action configure, IServiceProvider serviceProvider, Func, BaseExporter> configureExporterInstance = null) { - configure?.Invoke(exporterOptions); - exporterOptions.TryEnableIHttpClientFactoryIntegration(serviceProvider, "OtlpTraceExporter"); BaseExporter otlpExporter = new OtlpTraceExporter(exporterOptions); diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md index 2d7588afb56..2564f9b7cd7 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md @@ -123,8 +123,9 @@ services.AddOpenTelemetryTracing((builder) => builder For users using [IHttpClientFactory](https://docs.microsoft.com/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests) -you may also customize the named "OtlpTraceExporter" or "OtlpMetricExporter" -`HttpClient` using the built-in `AddHttpClient` extension: +you may also customize the named "OtlpTraceExporter", "OtlpMetricExporter", +and/or "OtlpLogExporter" `HttpClient` using the built-in `AddHttpClient` +extension: ```csharp services.AddHttpClient( diff --git a/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj b/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj index 3058dfff559..0aee4bd6334 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj +++ b/src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj @@ -19,7 +19,6 @@ - diff --git a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs index ee276e02e31..cccf2c432cd 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs @@ -17,6 +17,8 @@ using System; using System.Net.Http; using System.Reflection; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Exporter; using OpenTelemetry.Internal; @@ -33,31 +35,29 @@ public static class ZipkinExporterHelperExtensions /// builder to use. /// Exporter configuration options. /// The instance of to chain the calls. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The objects should not be disposed.")] public static TracerProviderBuilder AddZipkinExporter(this TracerProviderBuilder builder, Action configure = null) { Guard.ThrowIfNull(builder); - if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + if (configure != null) { - return deferredTracerProviderBuilder.Configure((sp, builder) => - { - AddZipkinExporter(builder, sp.GetOptions(), configure, sp); - }); + builder.ConfigureServices(services => services.Configure(configure)); } - return AddZipkinExporter(builder, new ZipkinExporterOptions(), configure, serviceProvider: null); + return builder.ConfigureBuilder((sp, builder) => + { + var options = sp.GetRequiredService>().Value; + + AddZipkinExporter(builder, options, sp); + }); } private static TracerProviderBuilder AddZipkinExporter( TracerProviderBuilder builder, ZipkinExporterOptions options, - Action configure, IServiceProvider serviceProvider) { - configure?.Invoke(options); - - if (serviceProvider != null && options.HttpClientFactory == ZipkinExporterOptions.DefaultHttpClientFactory) + if (options.HttpClientFactory == ZipkinExporterOptions.DefaultHttpClientFactory) { options.HttpClientFactory = () => { diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTests.cs index 834e77f2732..b3eca6b5d0c 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTests.cs @@ -82,7 +82,6 @@ public void TraceExportResultIsSuccess(OtlpExportProtocol protocol, string endpo OtlpTraceExporterHelperExtensions.AddOtlpExporter( builder, exporterOptions, - configure: null, serviceProvider: null, configureExporterInstance: otlpExporter => { From 872a52f5291804c7af19e90307b5cc097b2da709 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 8 Sep 2022 13:00:40 -0700 Subject: [PATCH 02/34] Instrumentation cleanup. (#3641) --- ...elemetry.Instrumentation.AspNetCore.csproj | 1 - .../TracerProviderBuilderExtensions.cs | 30 +++++-------- .../OpenTelemetry.Instrumentation.Http.csproj | 1 - .../TracerProviderBuilderExtensions.cs | 43 +++++++++---------- 4 files changed, 30 insertions(+), 45 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj index 71361bf191b..b97f1adf0da 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj @@ -10,7 +10,6 @@ - diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs index 2e2e4dfc253..f864c8e659e 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs @@ -17,8 +17,9 @@ using System; #if NET7_0_OR_GREATER using System.Diagnostics; -using Microsoft.Extensions.DependencyInjection; #endif +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.AspNetCore; using OpenTelemetry.Instrumentation.AspNetCore.Implementation; using OpenTelemetry.Internal; @@ -42,15 +43,17 @@ public static TracerProviderBuilder AddAspNetCoreInstrumentation( { Guard.ThrowIfNull(builder); - if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + if (configureAspNetCoreInstrumentationOptions != null) { - return deferredTracerProviderBuilder.Configure((sp, builder) => - { - AddAspNetCoreInstrumentation(builder, sp.GetOptions(), configureAspNetCoreInstrumentationOptions, sp); - }); + builder.ConfigureServices(services => services.Configure(configureAspNetCoreInstrumentationOptions)); } - return AddAspNetCoreInstrumentation(builder, new AspNetCoreInstrumentationOptions(), configureAspNetCoreInstrumentationOptions); + return builder.ConfigureBuilder((sp, builder) => + { + var options = sp.GetRequiredService>().Value; + + AddAspNetCoreInstrumentation(builder, new AspNetCoreInstrumentation(new HttpInListener(options)), sp); + }); } internal static TracerProviderBuilder AddAspNetCoreInstrumentation( @@ -81,18 +84,5 @@ internal static TracerProviderBuilder AddAspNetCoreInstrumentation( return builder.AddInstrumentation(() => instrumentation); } - - private static TracerProviderBuilder AddAspNetCoreInstrumentation( - TracerProviderBuilder builder, - AspNetCoreInstrumentationOptions options, - Action configure = null, - IServiceProvider serviceProvider = null) - { - configure?.Invoke(options); - return AddAspNetCoreInstrumentation( - builder, - new AspNetCoreInstrumentation(new HttpInListener(options)), - serviceProvider); - } } } diff --git a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj index 5fc3bf2d2fd..3665f2c85e0 100644 --- a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj +++ b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj @@ -9,7 +9,6 @@ - diff --git a/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs index a71912a99ae..3a6640c61c1 100644 --- a/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs @@ -15,6 +15,8 @@ // using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.Http; using OpenTelemetry.Instrumentation.Http.Implementation; #if !NETFRAMEWORK @@ -39,15 +41,19 @@ public static TracerProviderBuilder AddHttpClientInstrumentation( this TracerProviderBuilder builder, Action configureHttpWebRequestInstrumentationOptions = null) { - HttpWebRequestInstrumentationOptions options = new HttpWebRequestInstrumentationOptions(); - - configureHttpWebRequestInstrumentationOptions?.Invoke(options); + if (configureHttpWebRequestInstrumentationOptions != null) + { + builder.ConfigureServices(services => services.Configure(configureHttpWebRequestInstrumentationOptions)); + } - HttpWebRequestActivitySource.Options = options; + return builder.ConfigureBuilder((sp, builder) => + { + var options = sp.GetRequiredService>().Value; - builder.AddSource(HttpWebRequestActivitySource.ActivitySourceName); + HttpWebRequestActivitySource.Options = options; - return builder; + builder.AddSource(HttpWebRequestActivitySource.ActivitySourceName); + }); } #else @@ -63,15 +69,17 @@ public static TracerProviderBuilder AddHttpClientInstrumentation( { Guard.ThrowIfNull(builder); - if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + if (configureHttpClientInstrumentationOptions != null) { - return deferredTracerProviderBuilder.Configure((sp, builder) => - { - AddHttpClientInstrumentation(builder, sp.GetOptions(), configureHttpClientInstrumentationOptions); - }); + builder.ConfigureServices(services => services.Configure(configureHttpClientInstrumentationOptions)); } - return AddHttpClientInstrumentation(builder, new HttpClientInstrumentationOptions(), configureHttpClientInstrumentationOptions); + return builder.ConfigureBuilder((sp, builder) => + { + var options = sp.GetRequiredService>().Value; + + AddHttpClientInstrumentation(builder, new HttpClientInstrumentation(options)); + }); } internal static TracerProviderBuilder AddHttpClientInstrumentation( @@ -90,17 +98,6 @@ internal static TracerProviderBuilder AddHttpClientInstrumentation( return builder.AddInstrumentation(() => instrumentation); } - - private static TracerProviderBuilder AddHttpClientInstrumentation( - TracerProviderBuilder builder, - HttpClientInstrumentationOptions options, - Action configure = null) - { - configure?.Invoke(options); - return AddHttpClientInstrumentation( - builder, - new HttpClientInstrumentation(options)); - } #endif } } From cea14d3d3631cd9fccc4e4ea0690e8af0f61f7ba Mon Sep 17 00:00:00 2001 From: Dawid Szmigielski Date: Sun, 11 Sep 2022 06:56:29 +0200 Subject: [PATCH 03/34] Change StatusCode to 200 when no metrics are collected (#3643) --- src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md | 4 ++++ .../PrometheusExporterMiddleware.cs | 2 +- .../CHANGELOG.md | 4 ++++ .../PrometheusHttpListener.cs | 2 +- .../PrometheusExporterMiddlewareTests.cs | 2 +- .../PrometheusHttpListenerTests.cs | 2 +- 6 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md index 7ca283721c9..acd5d5ba488 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Bug fix for Prometheus Exporter reporting StatusCode 204 +instead of 200, when no metrics are collected +([#3643](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3643)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs index d02339706bc..c6148cc8e35 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs @@ -80,7 +80,7 @@ public async Task InvokeAsync(HttpContext httpContext) else { // It's not expected to have no metrics to collect, but it's not necessarily a failure, either. - response.StatusCode = 204; + response.StatusCode = 200; PrometheusExporterEventSource.Log.NoMetrics(); } } diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md index 9f7671595c4..eb1859a39d0 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Bug fix for Prometheus Exporter reporting StatusCode 204 + instead of 200, when no metrics are collected + ([#3643](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3643)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs index 26994830a66..40ab4b93807 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs @@ -166,7 +166,7 @@ private async Task ProcessRequestAsync(HttpListenerContext context) else { // It's not expected to have no metrics to collect, but it's not necessarily a failure, either. - context.Response.StatusCode = 204; + context.Response.StatusCode = 200; PrometheusExporterEventSource.Log.NoMetrics(); } } diff --git a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs index ff8b0bdc484..07db88f7102 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs @@ -281,7 +281,7 @@ private static async Task RunPrometheusExporterMiddlewareIntegrationTest( } else { - Assert.Equal(HttpStatusCode.NoContent, response.StatusCode); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); } validateResponse?.Invoke(response); diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs index fb281a3563f..a35dcf89b26 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs @@ -140,7 +140,7 @@ private async Task RunPrometheusExporterHttpServerIntegrationTest(bool skipMetri } else { - Assert.Equal(HttpStatusCode.NoContent, response.StatusCode); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); } } } From 6ff512cf6020432ec8f4cefbd107ea89428c77bc Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 12 Sep 2022 13:22:51 -0700 Subject: [PATCH 04/34] [Metrics] Improve dependency injection support in meter provider build-up using SDK (#3646) * Mirror TracerProviderBuilder dependency injection API onto MeterProviderBuilder. * Nullable annotations. * Warning cleanup. * Warning cleanup. * Public API updates. * Warning cleanup. * Public API updates. * CHANGELOG updates. * Warning cleanup. * Fixes. * Tests. --- .../netstandard2.0/PublicAPI.Unshipped.txt | 3 - .../CHANGELOG.md | 4 + .../MeterProviderBuilderHosting.cs | 62 ---- .../Metrics/MeterProviderBuilderExtensions.cs | 75 +---- .../OpenTelemetryServicesExtensions.cs | 91 +++--- .../.publicApi/net462/PublicAPI.Shipped.txt | 26 +- .../.publicApi/net462/PublicAPI.Unshipped.txt | 9 +- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 26 +- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 9 +- .../netstandard2.0/PublicAPI.Shipped.txt | 26 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 9 +- .../netstandard2.1/PublicAPI.Shipped.txt | 26 +- .../netstandard2.1/PublicAPI.Unshipped.txt | 9 +- src/OpenTelemetry/CHANGELOG.md | 4 + .../Builder/MeterProviderBuilderBase.cs | 301 ++++++++++++++++++ .../MeterProviderBuilderExtensions.cs | 176 ++++++---- .../{ => Builder}/MeterProviderBuilderSdk.cs | 25 +- ...viderBuilderServiceCollectionExtensions.cs | 77 +++++ ...rProviderBuilderServiceCollectionHelper.cs | 81 +++++ .../Builder/MeterProviderBuilderState.cs | 127 ++++++++ .../Metrics/CompositeMetricReader.cs | 14 +- .../Metrics/CompositeMetricReaderExt.cs | 16 +- .../Metrics/MeterProviderBuilderBase.cs | 169 ---------- src/OpenTelemetry/Metrics/MeterProviderSdk.cs | 115 ++++--- .../Metrics/MetricReaderOptions.cs | 16 +- .../OtlpMetricsExporterTests.cs | 5 +- .../HostingMeterExtensionTests.cs | 44 +-- .../MeterProviderBuilderExtensionsTests.cs | 293 +++++++++++++++++ .../Metrics/MetricAPITest.cs | 12 +- 29 files changed, 1268 insertions(+), 582 deletions(-) delete mode 100644 src/OpenTelemetry.Extensions.Hosting/Implementation/MeterProviderBuilderHosting.cs create mode 100644 src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs rename src/OpenTelemetry/Metrics/{ => Builder}/MeterProviderBuilderExtensions.cs (62%) rename src/OpenTelemetry/Metrics/{ => Builder}/MeterProviderBuilderSdk.cs (80%) create mode 100644 src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionExtensions.cs create mode 100644 src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionHelper.cs create mode 100644 src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderState.cs delete mode 100644 src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs create mode 100644 test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs 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 93835864ab7..63141a61d05 100644 --- a/src/OpenTelemetry.Extensions.Hosting/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Hosting/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -5,9 +5,6 @@ static Microsoft.Extensions.DependencyInjection.OpenTelemetryServicesExtensions. static Microsoft.Extensions.DependencyInjection.OpenTelemetryServicesExtensions.AddOpenTelemetryMetrics(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) -> 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.Metrics.MeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.IServiceProvider serviceProvider) -> OpenTelemetry.Metrics.MeterProvider static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Configure(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.GetServices(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> Microsoft.Extensions.DependencyInjection.IServiceCollection static OpenTelemetry.Trace.TracerProviderBuilderExtensions.Configure(this OpenTelemetry.Trace.TracerProviderBuilder tracerProviderBuilder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md index bb3df948aad..81287c29079 100644 --- a/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Hosting/CHANGELOG.md @@ -6,6 +6,10 @@ `TracerProvider` has been moved into the SDK. ([#3533](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3533)) +* Dependency injection support when configuring + `MeterProvider` has been moved into the SDK. + ([#3646](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3646)) + ## 1.0.0-rc9.6 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Extensions.Hosting/Implementation/MeterProviderBuilderHosting.cs b/src/OpenTelemetry.Extensions.Hosting/Implementation/MeterProviderBuilderHosting.cs deleted file mode 100644 index 583ace09454..00000000000 --- a/src/OpenTelemetry.Extensions.Hosting/Implementation/MeterProviderBuilderHosting.cs +++ /dev/null @@ -1,62 +0,0 @@ -// -// 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 Microsoft.Extensions.DependencyInjection; -using OpenTelemetry.Internal; - -namespace OpenTelemetry.Metrics -{ - /// - /// A with support for deferred initialization using for dependency injection. - /// - internal sealed class MeterProviderBuilderHosting : MeterProviderBuilderBase, IDeferredMeterProviderBuilder - { - private readonly List> configurationActions = new(); - - public MeterProviderBuilderHosting(IServiceCollection services) - { - Guard.ThrowIfNull(services); - - this.Services = services; - } - - public IServiceCollection Services { get; } - - public MeterProviderBuilder Configure(Action configure) - { - Guard.ThrowIfNull(configure); - - this.configurationActions.Add(configure); - return this; - } - - public MeterProvider Build(IServiceProvider serviceProvider) - { - Guard.ThrowIfNull(serviceProvider); - - // Note: Not using a foreach loop because additional actions can be - // added during each call. - for (int i = 0; i < this.configurationActions.Count; i++) - { - this.configurationActions[i](serviceProvider, this); - } - - return this.Build(); - } - } -} diff --git a/src/OpenTelemetry.Extensions.Hosting/Metrics/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/Metrics/MeterProviderBuilderExtensions.cs index 30dd08f4198..d0056b28467 100644 --- a/src/OpenTelemetry.Extensions.Hosting/Metrics/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.Hosting/Metrics/MeterProviderBuilderExtensions.cs @@ -24,42 +24,6 @@ namespace OpenTelemetry.Metrics /// public static class MeterProviderBuilderExtensions { - /// - /// Adds instrumentation to the provider. - /// - /// Instrumentation type. - /// . - /// The supplied for chaining. - public static MeterProviderBuilder AddInstrumentation(this MeterProviderBuilder meterProviderBuilder) - where T : class - { - if (meterProviderBuilder is MeterProviderBuilderHosting meterProviderBuilderHosting) - { - meterProviderBuilderHosting.Configure((sp, builder) => builder - .AddInstrumentation(() => sp.GetRequiredService())); - } - - return meterProviderBuilder; - } - - /// - /// Adds a reader to the provider. - /// - /// Reader type. - /// . - /// The supplied for chaining. - public static MeterProviderBuilder AddReader(this MeterProviderBuilder meterProviderBuilder) - where T : MetricReader - { - if (meterProviderBuilder is MeterProviderBuilderHosting meterProviderBuilderHosting) - { - meterProviderBuilderHosting.Configure((sp, builder) => builder - .AddReader(sp.GetRequiredService())); - } - - return meterProviderBuilder; - } - /// /// Register a callback action to configure the once the application (this MeterProviderBuilder meterP /// . /// Configuration callback. /// The supplied for chaining. + [Obsolete("Call ConfigureBuilder instead this method will be removed in a future version.")] public static MeterProviderBuilder Configure(this MeterProviderBuilder meterProviderBuilder, Action configure) { - if (meterProviderBuilder is IDeferredMeterProviderBuilder deferredMeterProviderBuilder) - { - deferredMeterProviderBuilder.Configure(configure); - } - - return meterProviderBuilder; + return meterProviderBuilder.ConfigureBuilder(configure); } /// @@ -85,35 +45,12 @@ public static MeterProviderBuilder Configure(this MeterProviderBuilder meterProv /// . /// or /// if services are unavailable. + [Obsolete("Call ConfigureServices instead this method will be removed in a future version.")] public static IServiceCollection GetServices(this MeterProviderBuilder meterProviderBuilder) { - if (meterProviderBuilder is MeterProviderBuilderHosting meterProviderBuilderHosting) - { - return meterProviderBuilderHosting.Services; - } - - return null; - } - - /// - /// Run the configured actions to initialize the . - /// - /// . - /// . - /// . - public static MeterProvider Build(this MeterProviderBuilder meterProviderBuilder, IServiceProvider serviceProvider) - { - if (meterProviderBuilder is MeterProviderBuilderHosting meterProviderBuilderHosting) - { - return meterProviderBuilderHosting.Build(serviceProvider); - } - - if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) - { - return meterProviderBuilderBase.Build(); - } - - return null; + IServiceCollection services = null; + meterProviderBuilder.ConfigureServices(s => services = s); + return services; } } } diff --git a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs index 44a41e1e5c2..73b11544d23 100644 --- a/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs +++ b/src/OpenTelemetry.Extensions.Hosting/OpenTelemetryServicesExtensions.cs @@ -15,10 +15,8 @@ // using System; -using System.Diagnostics; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; -using OpenTelemetry; using OpenTelemetry.Extensions.Hosting.Implementation; using OpenTelemetry.Internal; using OpenTelemetry.Metrics; @@ -27,7 +25,8 @@ namespace Microsoft.Extensions.DependencyInjection { /// - /// Extension methods for setting up OpenTelemetry services in an . + /// Extension methods for setting up OpenTelemetry services in an . /// public static class OpenTelemetryServicesExtensions { @@ -37,24 +36,29 @@ public static class OpenTelemetryServicesExtensions /// cref="IServiceCollection" />. /// /// - /// Note: This is safe to be called multiple times and by library authors. - /// Only a single will be created for a given - /// . + /// Note: This is safe to be called multiple times and by library + /// authors. Only a single will be created + /// for a given . /// /// . - /// Supplied for chaining calls. + /// Supplied for chaining + /// calls. public static IServiceCollection AddOpenTelemetryTracing(this IServiceCollection services) - => AddOpenTelemetryTracing(services, (b) => { }); + => AddOpenTelemetryTracing(services, b => { }); /// /// Configure OpenTelemetry and register a /// to automatically start tracing services in the supplied . /// - /// + /// /// . - /// Callback action to configure the . - /// Supplied for chaining calls. + /// Callback action to configure the . + /// Supplied for chaining + /// calls. public static IServiceCollection AddOpenTelemetryTracing(this IServiceCollection services, Action configure) { Guard.ThrowIfNull(services); @@ -67,54 +71,41 @@ public static IServiceCollection AddOpenTelemetryTracing(this IServiceCollection } /// - /// Adds OpenTelemetry MeterProvider to the specified . + /// Configure OpenTelemetry and register a + /// to automatically start metric services in the supplied . /// - /// The to add services to. - /// The so that additional calls can be chained. + /// + /// Note: This is safe to be called multiple times and by library + /// authors. Only a single will be created + /// for a given . + /// + /// . + /// Supplied for chaining + /// calls. public static IServiceCollection AddOpenTelemetryMetrics(this IServiceCollection services) - { - return services.AddOpenTelemetryMetrics(builder => { }); - } + => AddOpenTelemetryMetrics(services, b => { }); /// - /// Adds OpenTelemetry MeterProvider to the specified . + /// Configure OpenTelemetry and register a + /// to automatically start metric services in the supplied . /// - /// The to add services to. - /// Callback action to configure the . - /// The so that additional calls can be chained. + /// + /// . + /// Callback action to configure the . + /// Supplied for chaining + /// calls. public static IServiceCollection AddOpenTelemetryMetrics(this IServiceCollection services, Action configure) { - Guard.ThrowIfNull(configure); - - var builder = new MeterProviderBuilderHosting(services); - configure(builder); - return services.AddOpenTelemetryMetrics(sp => builder.Build(sp)); - } - - /// - /// Adds OpenTelemetry MeterProvider 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 AddOpenTelemetryMetrics(this IServiceCollection services, Func createMeterProvider) - { - Debug.Assert(services != null, $"{nameof(services)} must not be null"); - Debug.Assert(createMeterProvider != null, $"{nameof(createMeterProvider)} must not be null"); + Guard.ThrowIfNull(services); - // Accessing Sdk class is just to trigger its static ctor, - // which sets default Propagators and default Activity Id format - _ = Sdk.SuppressInstrumentation; + services.ConfigureOpenTelemetryMetrics(configure); - try - { - services.TryAddEnumerable(ServiceDescriptor.Singleton()); - return services.AddSingleton(s => createMeterProvider(s)); - } - catch (Exception ex) - { - HostingExtensionsEventSource.Log.FailedInitialize(ex); - } + services.TryAddEnumerable(ServiceDescriptor.Singleton()); return services; } diff --git a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt index 663e45228b0..782248e7e3a 100644 --- a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Shipped.txt @@ -21,15 +21,15 @@ OpenTelemetry.CompositeProcessor.CompositeProcessor(System.Collections.Generi ~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.set -> void ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.get -> System.Func ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.set -> void -~OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider +OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider! ~OpenTelemetry.Metrics.Metric.Description.get -> string ~OpenTelemetry.Metrics.Metric.MeterName.get -> string ~OpenTelemetry.Metrics.Metric.MeterVersion.get -> string ~OpenTelemetry.Metrics.Metric.Name.get -> string ~OpenTelemetry.Metrics.Metric.Unit.get -> string ~OpenTelemetry.Metrics.MetricPoint.GetHistogramBuckets() -> OpenTelemetry.Metrics.HistogramBuckets -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions! +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.get -> string ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Name.get -> string @@ -63,8 +63,8 @@ OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.Tra override OpenTelemetry.BaseExportProcessor.OnEnd(T! data) -> void ~override OpenTelemetry.BatchActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.BatchExportProcessor.OnExport(T! data) -> void -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string[] names) -> OpenTelemetry.Metrics.MeterProviderBuilder +~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder! +override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string![]! names) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~override OpenTelemetry.SimpleActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.SimpleExportProcessor.OnExport(T! data) -> void ~override OpenTelemetry.Trace.SamplingResult.Equals(object obj) -> bool @@ -74,14 +74,14 @@ override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string![ override sealed OpenTelemetry.BaseExportProcessor.OnStart(T! data) -> void readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExporter! ~readonly OpenTelemetry.Metrics.BaseExportingMetricReader.exporter -> OpenTelemetry.BaseExporter -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Metrics.MetricReader reader) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, string name) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Func viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Metrics.MetricReader! reader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration! metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, string! name) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Func! viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider? +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder! resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~static OpenTelemetry.Metrics.MeterProviderExtensions.ForceFlush(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MeterProviderExtensions.Shutdown(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MetricStreamConfiguration.Drop.get -> OpenTelemetry.Metrics.MetricStreamConfiguration diff --git a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt index 5d438fc9dc9..5b0e8c6e33b 100644 --- a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,3 +1,4 @@ +Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions.BatchExportLogRecordProcessorOptions() -> void @@ -31,6 +32,12 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~OpenTelemetry.Trace.SamplingResult.TraceStateString.get -> string ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, string traceStateString) -> void ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes, string traceStateString) -> void @@ -58,7 +65,7 @@ static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTe static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! OpenTelemetry.Metrics.MetricType.LongSumNonMonotonic = 138 -> OpenTelemetry.Metrics.MetricType OpenTelemetry.Metrics.MetricType.DoubleSumNonMonotonic = 141 -> OpenTelemetry.Metrics.MetricType diff --git a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Shipped.txt index 663e45228b0..782248e7e3a 100644 --- a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -21,15 +21,15 @@ OpenTelemetry.CompositeProcessor.CompositeProcessor(System.Collections.Generi ~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.set -> void ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.get -> System.Func ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.set -> void -~OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider +OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider! ~OpenTelemetry.Metrics.Metric.Description.get -> string ~OpenTelemetry.Metrics.Metric.MeterName.get -> string ~OpenTelemetry.Metrics.Metric.MeterVersion.get -> string ~OpenTelemetry.Metrics.Metric.Name.get -> string ~OpenTelemetry.Metrics.Metric.Unit.get -> string ~OpenTelemetry.Metrics.MetricPoint.GetHistogramBuckets() -> OpenTelemetry.Metrics.HistogramBuckets -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions! +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.get -> string ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Name.get -> string @@ -63,8 +63,8 @@ OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.Tra override OpenTelemetry.BaseExportProcessor.OnEnd(T! data) -> void ~override OpenTelemetry.BatchActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.BatchExportProcessor.OnExport(T! data) -> void -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string[] names) -> OpenTelemetry.Metrics.MeterProviderBuilder +~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder! +override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string![]! names) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~override OpenTelemetry.SimpleActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.SimpleExportProcessor.OnExport(T! data) -> void ~override OpenTelemetry.Trace.SamplingResult.Equals(object obj) -> bool @@ -74,14 +74,14 @@ override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string![ override sealed OpenTelemetry.BaseExportProcessor.OnStart(T! data) -> void readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExporter! ~readonly OpenTelemetry.Metrics.BaseExportingMetricReader.exporter -> OpenTelemetry.BaseExporter -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Metrics.MetricReader reader) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, string name) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Func viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Metrics.MetricReader! reader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration! metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, string! name) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Func! viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider? +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder! resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~static OpenTelemetry.Metrics.MeterProviderExtensions.ForceFlush(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MeterProviderExtensions.Shutdown(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MetricStreamConfiguration.Drop.get -> OpenTelemetry.Metrics.MetricStreamConfiguration diff --git a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt index 5d438fc9dc9..5b0e8c6e33b 100644 --- a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,3 +1,4 @@ +Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions.BatchExportLogRecordProcessorOptions() -> void @@ -31,6 +32,12 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~OpenTelemetry.Trace.SamplingResult.TraceStateString.get -> string ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, string traceStateString) -> void ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes, string traceStateString) -> void @@ -58,7 +65,7 @@ static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTe static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! OpenTelemetry.Metrics.MetricType.LongSumNonMonotonic = 138 -> OpenTelemetry.Metrics.MetricType OpenTelemetry.Metrics.MetricType.DoubleSumNonMonotonic = 141 -> OpenTelemetry.Metrics.MetricType diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index 663e45228b0..782248e7e3a 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -21,15 +21,15 @@ OpenTelemetry.CompositeProcessor.CompositeProcessor(System.Collections.Generi ~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.set -> void ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.get -> System.Func ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.set -> void -~OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider +OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider! ~OpenTelemetry.Metrics.Metric.Description.get -> string ~OpenTelemetry.Metrics.Metric.MeterName.get -> string ~OpenTelemetry.Metrics.Metric.MeterVersion.get -> string ~OpenTelemetry.Metrics.Metric.Name.get -> string ~OpenTelemetry.Metrics.Metric.Unit.get -> string ~OpenTelemetry.Metrics.MetricPoint.GetHistogramBuckets() -> OpenTelemetry.Metrics.HistogramBuckets -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions! +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.get -> string ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Name.get -> string @@ -63,8 +63,8 @@ OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.Tra override OpenTelemetry.BaseExportProcessor.OnEnd(T! data) -> void ~override OpenTelemetry.BatchActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.BatchExportProcessor.OnExport(T! data) -> void -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string[] names) -> OpenTelemetry.Metrics.MeterProviderBuilder +~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder! +override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string![]! names) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~override OpenTelemetry.SimpleActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.SimpleExportProcessor.OnExport(T! data) -> void ~override OpenTelemetry.Trace.SamplingResult.Equals(object obj) -> bool @@ -74,14 +74,14 @@ override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string![ override sealed OpenTelemetry.BaseExportProcessor.OnStart(T! data) -> void readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExporter! ~readonly OpenTelemetry.Metrics.BaseExportingMetricReader.exporter -> OpenTelemetry.BaseExporter -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Metrics.MetricReader reader) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, string name) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Func viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Metrics.MetricReader! reader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration! metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, string! name) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Func! viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider? +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder! resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~static OpenTelemetry.Metrics.MeterProviderExtensions.ForceFlush(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MeterProviderExtensions.Shutdown(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MetricStreamConfiguration.Drop.get -> OpenTelemetry.Metrics.MetricStreamConfiguration diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 7f9f3ed4692..54869f362f2 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,3 +1,4 @@ +Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions.BatchExportLogRecordProcessorOptions() -> void @@ -31,6 +32,12 @@ OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BasePr OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureResource(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~OpenTelemetry.Trace.SamplingResult.TraceStateString.get -> string ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, string traceStateString) -> void ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes, string traceStateString) -> void @@ -58,7 +65,7 @@ static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTe static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! OpenTelemetry.Metrics.MetricType.LongSumNonMonotonic = 138 -> OpenTelemetry.Metrics.MetricType OpenTelemetry.Metrics.MetricType.DoubleSumNonMonotonic = 141 -> OpenTelemetry.Metrics.MetricType diff --git a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Shipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Shipped.txt index 663e45228b0..782248e7e3a 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Shipped.txt @@ -21,15 +21,15 @@ OpenTelemetry.CompositeProcessor.CompositeProcessor(System.Collections.Generi ~OpenTelemetry.Metrics.ExplicitBucketHistogramConfiguration.Boundaries.set -> void ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.get -> System.Func ~OpenTelemetry.Metrics.IPullMetricExporter.Collect.set -> void -~OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider +OpenTelemetry.Metrics.MeterProviderBuilderBase.Build() -> OpenTelemetry.Metrics.MeterProvider! ~OpenTelemetry.Metrics.Metric.Description.get -> string ~OpenTelemetry.Metrics.Metric.MeterName.get -> string ~OpenTelemetry.Metrics.Metric.MeterVersion.get -> string ~OpenTelemetry.Metrics.Metric.Name.get -> string ~OpenTelemetry.Metrics.Metric.Unit.get -> string ~OpenTelemetry.Metrics.MetricPoint.GetHistogramBuckets() -> OpenTelemetry.Metrics.HistogramBuckets -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions -~OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.get -> OpenTelemetry.Metrics.PeriodicExportingMetricReaderOptions! +OpenTelemetry.Metrics.MetricReaderOptions.PeriodicExportingMetricReaderOptions.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.get -> string ~OpenTelemetry.Metrics.MetricStreamConfiguration.Description.set -> void ~OpenTelemetry.Metrics.MetricStreamConfiguration.Name.get -> string @@ -63,8 +63,8 @@ OpenTelemetry.Trace.TracerProviderBuilderBase.Build() -> OpenTelemetry.Trace.Tra override OpenTelemetry.BaseExportProcessor.OnEnd(T! data) -> void ~override OpenTelemetry.BatchActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.BatchExportProcessor.OnExport(T! data) -> void -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder -~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string[] names) -> OpenTelemetry.Metrics.MeterProviderBuilder +~override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddInstrumentation(System.Func! instrumentationFactory) -> OpenTelemetry.Metrics.MeterProviderBuilder! +override OpenTelemetry.Metrics.MeterProviderBuilderBase.AddMeter(params string![]! names) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~override OpenTelemetry.SimpleActivityExportProcessor.OnEnd(System.Diagnostics.Activity data) -> void override OpenTelemetry.SimpleExportProcessor.OnExport(T! data) -> void ~override OpenTelemetry.Trace.SamplingResult.Equals(object obj) -> bool @@ -74,14 +74,14 @@ override OpenTelemetry.Trace.TracerProviderBuilderBase.AddSource(params string![ override sealed OpenTelemetry.BaseExportProcessor.OnStart(T! data) -> void readonly OpenTelemetry.BaseExportProcessor.exporter -> OpenTelemetry.BaseExporter! ~readonly OpenTelemetry.Metrics.BaseExportingMetricReader.exporter -> OpenTelemetry.BaseExporter -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Metrics.MetricReader reader) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, string instrumentName, string name) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Func viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Metrics.MetricReader! reader) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, OpenTelemetry.Metrics.MetricStreamConfiguration! metricStreamConfiguration) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, string! instrumentName, string! name) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddView(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Func! viewConfig) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.Build(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProvider? +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricPointsPerMetricStream(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricPointsPerMetricStream) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetMaxMetricStreams(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, int maxMetricStreams) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.SetResourceBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, OpenTelemetry.Resources.ResourceBuilder! resourceBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~static OpenTelemetry.Metrics.MeterProviderExtensions.ForceFlush(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MeterProviderExtensions.Shutdown(this OpenTelemetry.Metrics.MeterProvider provider, int timeoutMilliseconds = -1) -> bool ~static OpenTelemetry.Metrics.MetricStreamConfiguration.Drop.get -> OpenTelemetry.Metrics.MetricStreamConfiguration diff --git a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index 5d438fc9dc9..5b0e8c6e33b 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -1,3 +1,4 @@ +Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions OpenTelemetry.Logs.BatchExportLogRecordProcessorOptions.BatchExportLogRecordProcessorOptions() -> void @@ -31,6 +32,12 @@ OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions OpenTelemetry.Logs.OpenTelemetryLoggerProvider.AddProcessor(OpenTelemetry.BaseProcessor! processor) -> OpenTelemetry.Logs.OpenTelemetryLoggerProvider! OpenTelemetry.Logs.OpenTelemetryLoggerProvider.ForceFlush(int timeoutMilliseconds = -1) -> bool OpenTelemetry.Logs.OpenTelemetryLoggerProvider.OpenTelemetryLoggerProvider() -> void +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.MeterProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryMetrics(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddReader(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! ~OpenTelemetry.Trace.SamplingResult.TraceStateString.get -> string ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, string traceStateString) -> void ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes, string traceStateString) -> void @@ -58,7 +65,7 @@ static OpenTelemetry.Logs.OpenTelemetryLoggerOptionsExtensions.Build(this OpenTe static OpenTelemetry.Sdk.CreateLoggerProviderBuilder() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! static Microsoft.Extensions.DependencyInjection.TracerProviderBuilderServiceCollectionExtensions.ConfigureOpenTelemetryTracing(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -~static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder meterProviderBuilder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureResource(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! OpenTelemetry.Metrics.MetricType.LongSumNonMonotonic = 138 -> OpenTelemetry.Metrics.MetricType OpenTelemetry.Metrics.MetricType.DoubleSumNonMonotonic = 141 -> OpenTelemetry.Metrics.MetricType diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 8090c32012a..2f972e92228 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -15,6 +15,10 @@ the `OpenTelemetryLoggerProvider` dependency injection scenarios ([#3596](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3596)) +* Added support for dependency injection scenarios when configuring + `MeterProvider` + ([#3646](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3646)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs new file mode 100644 index 00000000000..1ddd03dd310 --- /dev/null +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs @@ -0,0 +1,301 @@ +// +// 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. +// + +#nullable enable + +using System; +using System.Diagnostics; +using System.Diagnostics.Metrics; +using System.Text.RegularExpressions; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using OpenTelemetry.Internal; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Metrics +{ + /// + /// Contains methods for building instances. + /// + public abstract class MeterProviderBuilderBase : MeterProviderBuilder, IDeferredMeterProviderBuilder + { + internal readonly MeterProviderBuilderState? State; + + private readonly bool ownsServices; + private IServiceCollection? services; + + // This ctor is for a builder created from MeterProviderBuilderState which + // happens after the service provider has been created. + internal MeterProviderBuilderBase(MeterProviderBuilderState state) + { + Debug.Assert(state != null, "state was null"); + + this.State = state; + } + + // This ctor is for AddOpenTelemetryTracing scenario where the builder + // is bound to an external service collection. + internal MeterProviderBuilderBase(IServiceCollection services) + { + Guard.ThrowIfNull(services); + + services.AddOptions(); + services.TryAddSingleton(sp => new MeterProviderSdk(sp, ownsServiceProvider: false)); + + this.services = services; + this.ownsServices = false; + } + + // This ctor is for Sdk.CreateMeterProviderBuilder where the builder + // owns its services and service provider. + protected MeterProviderBuilderBase() + { + var services = new ServiceCollection(); + + services.AddOptions(); + + this.services = services; + this.ownsServices = true; + } + + /// + public override MeterProviderBuilder AddInstrumentation(Func instrumentationFactory) + { + Guard.ThrowIfNull(instrumentationFactory); + + return this.AddInstrumentation((sp) => instrumentationFactory()); + } + + /// + public override MeterProviderBuilder AddMeter(params string[] names) + { + Guard.ThrowIfNull(names); + + return this.ConfigureState((sp, state) => state.AddMeter(names)); + } + + /// + MeterProviderBuilder IDeferredMeterProviderBuilder.Configure( + Action configure) + { + Guard.ThrowIfNull(configure); + + if (this.State != null) + { + configure(this.State.ServiceProvider, this); + } + else + { + this.ConfigureServices(services + => MeterProviderBuilderServiceCollectionHelper.RegisterConfigureBuilderCallback(services, configure)); + } + + return this; + } + + internal MeterProviderBuilder AddInstrumentation() + where T : class + { + this.TryAddSingleton(); + this.AddInstrumentation((sp) => sp.GetRequiredService()); + + return this; + } + + internal MeterProviderBuilder AddReader() + where T : MetricReader + { + this.TryAddSingleton(); + this.ConfigureState((sp, state) => state.AddReader(sp.GetRequiredService())); + + return this; + } + + internal MeterProviderBuilder AddReader(MetricReader reader) + { + Guard.ThrowIfNull(reader); + + return this.ConfigureState((sp, state) => state.AddReader(reader)); + } + + internal MeterProviderBuilder AddView(string instrumentName, string name) + { + if (!MeterProviderBuilderSdk.IsValidInstrumentName(name)) + { + throw new ArgumentException($"Custom view name {name} is invalid.", nameof(name)); + } + + if (instrumentName.IndexOf('*') != -1) + { + throw new ArgumentException( + $"Instrument selection criteria is invalid. Instrument name '{instrumentName}' " + + $"contains a wildcard character. This is not allowed when using a view to " + + $"rename a metric stream as it would lead to conflicting metric stream names.", + nameof(instrumentName)); + } + + return this.AddView( + instrumentName, + new MetricStreamConfiguration + { + Name = name, + }); + } + + internal MeterProviderBuilder AddView(string instrumentName, MetricStreamConfiguration metricStreamConfiguration) + { + Guard.ThrowIfNullOrWhitespace(instrumentName); + Guard.ThrowIfNull(metricStreamConfiguration); + + if (metricStreamConfiguration.Name != null && instrumentName.IndexOf('*') != -1) + { + throw new ArgumentException( + $"Instrument selection criteria is invalid. Instrument name '{instrumentName}' " + + $"contains a wildcard character. This is not allowed when using a view to " + + $"rename a metric stream as it would lead to conflicting metric stream names.", + nameof(instrumentName)); + } + + if (instrumentName.IndexOf('*') != -1) + { + var pattern = '^' + Regex.Escape(instrumentName).Replace("\\*", ".*"); + var regex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); + return this.AddView(instrument => regex.IsMatch(instrument.Name) ? metricStreamConfiguration : null); + } + else + { + return this.AddView(instrument => instrument.Name.Equals(instrumentName, StringComparison.OrdinalIgnoreCase) ? metricStreamConfiguration : null); + } + } + + internal MeterProviderBuilder AddView(Func viewConfig) + { + Guard.ThrowIfNull(viewConfig); + + this.ConfigureState((sp, state) => state.AddView(viewConfig)); + + return this; + } + + internal MeterProviderBuilder ConfigureResource(Action configure) + { + Guard.ThrowIfNull(configure); + + return this.ConfigureState((sp, state) => state.ConfigureResource(configure)); + } + + internal MeterProviderBuilder ConfigureServices(Action configure) + { + Guard.ThrowIfNull(configure); + + var services = this.services; + + if (services == null) + { + throw new NotSupportedException("Services cannot be configured after ServiceProvider has been created."); + } + + configure(services); + + return this; + } + + internal MeterProvider InvokeBuild() + => this.Build(); + + internal MeterProviderBuilder SetMaxMetricStreams(int maxMetricStreams) + { + Guard.ThrowIfOutOfRange(maxMetricStreams, min: 1); + + return this.ConfigureState((sp, state) => state.MaxMetricStreams = maxMetricStreams); + } + + internal MeterProviderBuilder SetMaxMetricPointsPerMetricStream(int maxMetricPointsPerMetricStream) + { + Guard.ThrowIfOutOfRange(maxMetricPointsPerMetricStream, min: 1); + + return this.ConfigureState((sp, state) => state.MaxMetricPointsPerMetricStream = maxMetricPointsPerMetricStream); + } + + internal MeterProviderBuilder SetResourceBuilder(ResourceBuilder resourceBuilder) + { + Guard.ThrowIfNull(resourceBuilder); + + return this.ConfigureState((sp, state) => state.SetResourceBuilder(resourceBuilder)); + } + + /// + /// Run the configured actions to initialize the . + /// + /// . + protected MeterProvider Build() + { + if (!this.ownsServices || this.State != null) + { + throw new NotSupportedException("Build cannot be called directly on MeterProviderBuilder tied to external services."); + } + + var services = this.services; + + if (services == null) + { + throw new NotSupportedException("MeterProviderBuilder build method cannot be called multiple times."); + } + + this.services = null; + + var serviceProvider = services.BuildServiceProvider(); + + return new MeterProviderSdk(serviceProvider, ownsServiceProvider: true); + } + + private MeterProviderBuilder AddInstrumentation(Func instrumentationFactory) + where T : class + { + this.ConfigureState((sp, state) + => state.AddInstrumentation( + typeof(T).Name, + "semver:" + typeof(T).Assembly.GetName().Version, + instrumentationFactory(sp))); + + return this; + } + + private MeterProviderBuilder ConfigureState(Action configure) + { + Debug.Assert(configure != null, "configure was null"); + + if (this.State != null) + { + configure!(this.State.ServiceProvider, this.State); + } + else + { + this.ConfigureServices(services => MeterProviderBuilderServiceCollectionHelper.RegisterConfigureStateCallback(services, configure!)); + } + + return this; + } + + private void TryAddSingleton() + where T : class + { + var services = this.services; + + services?.TryAddSingleton(); + } + } +} diff --git a/src/OpenTelemetry/Metrics/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs similarity index 62% rename from src/OpenTelemetry/Metrics/MeterProviderBuilderExtensions.cs rename to src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs index cd47974872c..7342a734a07 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderExtensions.cs @@ -14,9 +14,11 @@ // limitations under the License. // +#nullable enable + using System; using System.Diagnostics.Metrics; -using OpenTelemetry.Internal; +using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Resources; namespace OpenTelemetry.Metrics @@ -26,17 +28,59 @@ namespace OpenTelemetry.Metrics /// public static class MeterProviderBuilderExtensions { + /// + /// Adds instrumentation to the provider. + /// + /// + /// Note: The type specified by will be + /// registered as a singleton service into application services. + /// + /// Instrumentation type. + /// . + /// The supplied for chaining. + public static MeterProviderBuilder AddInstrumentation(this MeterProviderBuilder meterProviderBuilder) + where T : class + { + if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) + { + meterProviderBuilderBase.AddInstrumentation(); + } + + return meterProviderBuilder; + } + /// /// Adds a reader to the provider. /// /// . /// . - /// . + /// The supplied for chaining. public static MeterProviderBuilder AddReader(this MeterProviderBuilder meterProviderBuilder, MetricReader reader) { if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) { - return meterProviderBuilderBase.AddReader(reader); + meterProviderBuilderBase.AddReader(reader); + } + + return meterProviderBuilder; + } + + /// + /// Adds a reader to the provider. + /// + /// + /// Note: The type specified by will be + /// registered as a singleton service into application services. + /// + /// Reader type. + /// . + /// The supplied for chaining. + public static MeterProviderBuilder AddReader(this MeterProviderBuilder meterProviderBuilder) + where T : MetricReader + { + if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) + { + meterProviderBuilderBase.AddReader(); } return meterProviderBuilder; @@ -46,30 +90,16 @@ public static MeterProviderBuilder AddReader(this MeterProviderBuilder meterProv /// Add metric view, which can be used to customize the Metrics outputted /// from the SDK. The views are applied in the order they are added. /// + /// See View specification here : https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view. /// . /// Name of the instrument, to be used as part of Instrument selection criteria. /// Name of the view. This will be used as name of resulting metrics stream. - /// . - /// See View specification here : https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view. + /// The supplied for chaining. public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProviderBuilder, string instrumentName, string name) { - if (!MeterProviderBuilderSdk.IsValidInstrumentName(name)) - { - throw new ArgumentException($"Custom view name {name} is invalid.", nameof(name)); - } - - if (instrumentName.IndexOf('*') != -1) - { - throw new ArgumentException( - $"Instrument selection criteria is invalid. Instrument name '{instrumentName}' " + - $"contains a wildcard character. This is not allowed when using a view to " + - $"rename a metric stream as it would lead to conflicting metric stream names.", - nameof(instrumentName)); - } - if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) { - return meterProviderBuilderBase.AddView(instrumentName, name); + meterProviderBuilderBase.AddView(instrumentName, name); } return meterProviderBuilder; @@ -79,27 +109,16 @@ public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProvid /// Add metric view, which can be used to customize the Metrics outputted /// from the SDK. The views are applied in the order they are added. /// + /// See View specification here : https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view. /// . /// Name of the instrument, to be used as part of Instrument selection criteria. /// Aggregation configuration used to produce metrics stream. - /// . - /// See View specification here : https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view. + /// The supplied for chaining. public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProviderBuilder, string instrumentName, MetricStreamConfiguration metricStreamConfiguration) { - Guard.ThrowIfNull(metricStreamConfiguration); - - if (metricStreamConfiguration.Name != null && instrumentName.IndexOf('*') != -1) - { - throw new ArgumentException( - $"Instrument selection criteria is invalid. Instrument name '{instrumentName}' " + - $"contains a wildcard character. This is not allowed when using a view to " + - $"rename a metric stream as it would lead to conflicting metric stream names.", - nameof(instrumentName)); - } - if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) { - return meterProviderBuilderBase.AddView(instrumentName, metricStreamConfiguration); + meterProviderBuilderBase.AddView(instrumentName, metricStreamConfiguration); } return meterProviderBuilder; @@ -109,9 +128,6 @@ public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProvid /// Add metric view, which can be used to customize the Metrics outputted /// from the SDK. The views are applied in the order they are added. /// - /// . - /// Function to configure aggregation based on the instrument. - /// . /// /// /// Note: An invalid @@ -121,13 +137,14 @@ public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProvid /// See View specification here : https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view. /// /// - public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProviderBuilder, Func viewConfig) + /// . + /// Function to configure aggregation based on the instrument. + /// The supplied for chaining. + public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProviderBuilder, Func viewConfig) { - Guard.ThrowIfNull(viewConfig); - if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) { - return meterProviderBuilderBase.AddView(viewConfig); + meterProviderBuilderBase.AddView(viewConfig); } return meterProviderBuilder; @@ -140,13 +157,13 @@ public static MeterProviderBuilder AddView(this MeterProviderBuilder meterProvid /// When Views are configured, a single instrument can result in multiple metric streams, /// so this control the number of streams. /// - /// MeterProviderBuilder instance. - /// Maximum number of metric streams allowed. - /// Returns for chaining. /// /// If an instrument is created, but disposed later, this will still be contributing to the limit. /// This may change in the future. /// + /// . + /// Maximum number of metric streams allowed. + /// The supplied for chaining. public static MeterProviderBuilder SetMaxMetricStreams(this MeterProviderBuilder meterProviderBuilder, int maxMetricStreams) { if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) @@ -162,14 +179,14 @@ public static MeterProviderBuilder SetMaxMetricStreams(this MeterProviderBuilder /// This limits the number of unique combinations of key/value pairs used /// for reporting measurements. /// - /// MeterProviderBuilder instance. - /// Maximum maximum number of metric points allowed per metric stream. - /// Returns for chaining. /// /// If a particular key/value pair combination is used at least once, /// it will contribute to the limit for the life of the process. /// This may change in the future. See: https://github.com/open-telemetry/opentelemetry-dotnet/issues/2360. /// + /// . + /// Maximum maximum number of metric points allowed per metric stream. + /// The supplied for chaining. public static MeterProviderBuilder SetMaxMetricPointsPerMetricStream(this MeterProviderBuilder meterProviderBuilder, int maxMetricPointsPerMetricStream) { if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) @@ -186,14 +203,14 @@ public static MeterProviderBuilder SetMaxMetricPointsPerMetricStream(this MeterP /// You should usually use instead /// (call if desired). /// - /// MeterProviderBuilder instance. + /// . /// from which Resource will be built. - /// Returns for chaining. + /// The supplied for chaining. public static MeterProviderBuilder SetResourceBuilder(this MeterProviderBuilder meterProviderBuilder, ResourceBuilder resourceBuilder) { if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) { - meterProviderBuilderBase.ResourceBuilder = resourceBuilder; + meterProviderBuilderBase.SetResourceBuilder(resourceBuilder); } return meterProviderBuilder; @@ -203,37 +220,72 @@ public static MeterProviderBuilder SetResourceBuilder(this MeterProviderBuilder /// Modify the from which the Resource associated with /// this provider is built from in-place. /// - /// MeterProviderBuilder instance. + /// . /// An action which modifies the provided in-place. - /// Returns for chaining. + /// The supplied for chaining. public static MeterProviderBuilder ConfigureResource(this MeterProviderBuilder meterProviderBuilder, Action configure) { - Guard.ThrowIfNull(meterProviderBuilder, nameof(meterProviderBuilder)); - Guard.ThrowIfNull(configure, nameof(configure)); + if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) + { + meterProviderBuilderBase.ConfigureResource(configure); + } + return meterProviderBuilder; + } + + /// + /// Register a callback action to configure the where metric services are configured. + /// + /// + /// Note: Metric services are only available during the application + /// configuration phase. + /// + /// . + /// Configuration callback. + /// The supplied for chaining. + public static MeterProviderBuilder ConfigureServices( + this MeterProviderBuilder meterProviderBuilder, + Action configure) + { if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) { - configure(meterProviderBuilderBase.ResourceBuilder); + meterProviderBuilderBase.ConfigureServices(configure); } return meterProviderBuilder; } /// - /// Run the given actions to initialize the . + /// Register a callback action to configure the once the application is available. /// /// . - /// . - public static MeterProvider Build(this MeterProviderBuilder meterProviderBuilder) + /// Configuration callback. + /// The supplied for chaining. + public static MeterProviderBuilder ConfigureBuilder( + this MeterProviderBuilder meterProviderBuilder, + Action configure) { - if (meterProviderBuilder is IDeferredMeterProviderBuilder) + if (meterProviderBuilder is IDeferredMeterProviderBuilder deferredMeterProviderBuilder) { - throw new NotSupportedException("DeferredMeterProviderBuilder requires a ServiceProvider to build."); + deferredMeterProviderBuilder.Configure(configure); } - if (meterProviderBuilder is MeterProviderBuilderSdk meterProviderBuilderSdk) + return meterProviderBuilder; + } + + /// + /// Run the given actions to initialize the . + /// + /// . + /// . + public static MeterProvider? Build(this MeterProviderBuilder meterProviderBuilder) + { + if (meterProviderBuilder is MeterProviderBuilderBase meterProviderBuilderBase) { - return meterProviderBuilderSdk.BuildSdk(); + return meterProviderBuilderBase.InvokeBuild(); } return null; diff --git a/src/OpenTelemetry/Metrics/MeterProviderBuilderSdk.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderSdk.cs similarity index 80% rename from src/OpenTelemetry/Metrics/MeterProviderBuilderSdk.cs rename to src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderSdk.cs index 8646e37156c..641b4957242 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderBuilderSdk.cs +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderSdk.cs @@ -14,22 +14,39 @@ // limitations under the License. // +#nullable enable + using System.Text.RegularExpressions; +using Microsoft.Extensions.DependencyInjection; namespace OpenTelemetry.Metrics { - internal class MeterProviderBuilderSdk : MeterProviderBuilderBase + internal sealed class MeterProviderBuilderSdk : MeterProviderBuilderBase { private static readonly Regex InstrumentNameRegex = new( @"^[a-zA-Z][-.\w]{0,62}$", RegexOptions.IgnoreCase | RegexOptions.Compiled); + public MeterProviderBuilderSdk() + { + } + + public MeterProviderBuilderSdk(IServiceCollection services) + : base(services) + { + } + + public MeterProviderBuilderSdk(MeterProviderBuilderState state) + : base(state) + { + } + /// /// Returns whether the given instrument name is valid according to the specification. /// /// See specification: . /// The instrument name. /// Boolean indicating if the instrument is valid. - internal static bool IsValidInstrumentName(string instrumentName) + public static bool IsValidInstrumentName(string instrumentName) { if (string.IsNullOrWhiteSpace(instrumentName)) { @@ -45,7 +62,7 @@ internal static bool IsValidInstrumentName(string instrumentName) /// See specification: . /// The view name. /// Boolean indicating if the instrument is valid. - internal static bool IsValidViewName(string customViewName) + public static bool IsValidViewName(string customViewName) { // Only validate the view name in case it's not null. In case it's null, the view name will be the instrument name as per the spec. if (customViewName == null) @@ -55,7 +72,5 @@ internal static bool IsValidViewName(string customViewName) return InstrumentNameRegex.IsMatch(customViewName); } - - internal MeterProvider BuildSdk() => this.Build(); } } diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionExtensions.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionExtensions.cs new file mode 100644 index 00000000000..8e34bd4b5a3 --- /dev/null +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionExtensions.cs @@ -0,0 +1,77 @@ +// +// 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. +// + +#nullable enable + +using System; +using OpenTelemetry; +using OpenTelemetry.Internal; +using OpenTelemetry.Metrics; + +namespace Microsoft.Extensions.DependencyInjection; + +/// +/// Extension methods for setting up OpenTelemetry Metrics services in an . +/// +public static class MeterProviderBuilderServiceCollectionExtensions +{ + /// + /// Configures OpenTelemetry Metrics services in the supplied . + /// + /// + /// Notes: + /// + /// A will not be created automatically + /// using this method. Either use the + /// IServiceCollection.AddOpenTelemetryMetrics extension in the + /// OpenTelemetry.Extensions.Hosting package or access the through the application to begin collecting traces. + /// This is safe to be called multiple times and by library authors. + /// Only a single will be created for a given + /// . + /// + /// + /// The to add services to. + /// The so that additional calls can be chained. + public static IServiceCollection ConfigureOpenTelemetryMetrics(this IServiceCollection services) + => ConfigureOpenTelemetryMetrics(services, (b) => { }); + + /// + /// Configures OpenTelemetry Metrics services in the supplied . + /// + /// + /// The to add services to. + /// Callback action to configure the . + /// The so that additional calls can be chained. + public static IServiceCollection ConfigureOpenTelemetryMetrics(this IServiceCollection services, Action configure) + { + Guard.ThrowIfNull(services); + Guard.ThrowIfNull(configure); + + // Accessing Sdk class is just to trigger its static ctor, + // which sets default Propagators and default Activity Id format + _ = Sdk.SuppressInstrumentation; + + // Note: We need to create a builder even if there is no configure + // because the builder will register services + var builder = new MeterProviderBuilderSdk(services); + + configure(builder); + + return services; + } +} diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionHelper.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionHelper.cs new file mode 100644 index 00000000000..e53f412828d --- /dev/null +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderServiceCollectionHelper.cs @@ -0,0 +1,81 @@ +// +// 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. +// + +#nullable enable + +using System; +using System.Diagnostics; +using Microsoft.Extensions.DependencyInjection; + +namespace OpenTelemetry.Metrics; + +internal static class MeterProviderBuilderServiceCollectionHelper +{ + internal static IServiceCollection RegisterConfigureBuilderCallback( + IServiceCollection services, + Action configure) + { + Debug.Assert(configure != null, "configure was null"); + + return RegisterConfigureStateCallback( + services, + (sp, state) => configure!(sp, state.Builder)); + } + + internal static IServiceCollection RegisterConfigureStateCallback( + IServiceCollection services, + Action configure) + { + Debug.Assert(services != null, "services was null"); + Debug.Assert(configure != null, "configure was null"); + + return services.AddSingleton(new ConfigureMeterProviderBuilderStateCallbackRegistration(configure!)); + } + + internal static void InvokeRegisteredConfigureStateCallbacks( + IServiceProvider serviceProvider, + MeterProviderBuilderState state) + { + Debug.Assert(serviceProvider != null, "serviceProvider was null"); + Debug.Assert(state != null, "state was null"); + + var callbackRegistrations = serviceProvider.GetServices(); + + foreach (var callbackRegistration in callbackRegistrations) + { + callbackRegistration.Configure(serviceProvider!, state!); + } + } + + private sealed class ConfigureMeterProviderBuilderStateCallbackRegistration + { + private readonly Action configure; + + public ConfigureMeterProviderBuilderStateCallbackRegistration( + Action configure) + { + this.configure = configure; + } + + public void Configure(IServiceProvider serviceProvider, MeterProviderBuilderState state) + { + Debug.Assert(serviceProvider != null, "serviceProvider was null"); + Debug.Assert(state != null, "state was null"); + + this.configure(serviceProvider!, state!); + } + } +} diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderState.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderState.cs new file mode 100644 index 00000000000..5518ae1e9e3 --- /dev/null +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderState.cs @@ -0,0 +1,127 @@ +// +// 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. +// + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.Metrics; +using OpenTelemetry.Internal; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Metrics +{ + /// + /// Stores state used to build a . + /// + internal sealed class MeterProviderBuilderState + { + internal const int MaxMetricsDefault = 1000; + internal const int MaxMetricPointsPerMetricDefault = 2000; + internal readonly IServiceProvider ServiceProvider; + internal readonly List Instrumentation = new(); + internal readonly List Readers = new(); + internal readonly List MeterSources = new(); + internal readonly List> ViewConfigs = new(); + internal ResourceBuilder? ResourceBuilder; + internal int MaxMetricStreams = MaxMetricsDefault; + internal int MaxMetricPointsPerMetricStream = MaxMetricPointsPerMetricDefault; + + private MeterProviderBuilderSdk? builder; + + public MeterProviderBuilderState(IServiceProvider serviceProvider) + { + Debug.Assert(serviceProvider != null, "serviceProvider was null"); + + this.ServiceProvider = serviceProvider!; + } + + public MeterProviderBuilderSdk Builder => this.builder ??= new MeterProviderBuilderSdk(this); + + public void AddInstrumentation( + string instrumentationName, + string instrumentationVersion, + object instrumentation) + { + Debug.Assert(!string.IsNullOrWhiteSpace(instrumentationName), "instrumentationName was null or whitespace"); + Debug.Assert(!string.IsNullOrWhiteSpace(instrumentationVersion), "instrumentationVersion was null or whitespace"); + Debug.Assert(instrumentation != null, "instrumentation was null"); + + this.Instrumentation.Add( + new InstrumentationRegistration( + instrumentationName, + instrumentationVersion, + instrumentation!)); + } + + public void AddMeter(params string[] names) + { + Debug.Assert(names != null, "names was null"); + + foreach (var name in names!) + { + Guard.ThrowIfNullOrWhitespace(name); + + this.MeterSources.Add(name); + } + } + + public void AddReader(MetricReader reader) + { + Debug.Assert(reader != null, "reader was null"); + + this.Readers.Add(reader!); + } + + public void AddView(Func viewConfig) + { + Debug.Assert(viewConfig != null, "viewConfig was null"); + + this.ViewConfigs.Add(viewConfig!); + } + + public void ConfigureResource(Action configure) + { + Debug.Assert(configure != null, "configure was null"); + + var resourceBuilder = this.ResourceBuilder ??= ResourceBuilder.CreateDefault(); + + configure!(resourceBuilder); + } + + public void SetResourceBuilder(ResourceBuilder resourceBuilder) + { + Debug.Assert(resourceBuilder != null, "resourceBuilder was null"); + + this.ResourceBuilder = resourceBuilder; + } + + internal readonly struct InstrumentationRegistration + { + public readonly string Name; + public readonly string Version; + public readonly object Instance; + + internal InstrumentationRegistration(string name, string version, object instance) + { + this.Name = name; + this.Version = version; + this.Instance = instance; + } + } + } +} diff --git a/src/OpenTelemetry/Metrics/CompositeMetricReader.cs b/src/OpenTelemetry/Metrics/CompositeMetricReader.cs index b584001e31f..4e9e5d2597f 100644 --- a/src/OpenTelemetry/Metrics/CompositeMetricReader.cs +++ b/src/OpenTelemetry/Metrics/CompositeMetricReader.cs @@ -27,7 +27,7 @@ namespace OpenTelemetry.Metrics /// internal sealed partial class CompositeMetricReader : MetricReader { - private readonly DoublyLinkedListNode head; + public readonly DoublyLinkedListNode Head; private DoublyLinkedListNode tail; private bool disposed; private int count; @@ -42,8 +42,8 @@ public CompositeMetricReader(IEnumerable readers) throw new ArgumentException($"'{iter}' is null or empty", nameof(iter)); } - this.head = new DoublyLinkedListNode(iter.Current); - this.tail = this.head; + this.Head = new DoublyLinkedListNode(iter.Current); + this.tail = this.Head; this.count++; while (iter.MoveNext()) @@ -67,7 +67,7 @@ public CompositeMetricReader AddReader(MetricReader reader) return this; } - public Enumerator GetEnumerator() => new(this.head); + public Enumerator GetEnumerator() => new(this.Head); /// internal override bool ProcessMetrics(in Batch metrics, int timeoutMilliseconds) @@ -85,7 +85,7 @@ protected override bool OnCollect(int timeoutMilliseconds = Timeout.Infinite) ? null : Stopwatch.StartNew(); - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (sw == null) { @@ -111,7 +111,7 @@ protected override bool OnShutdown(int timeoutMilliseconds) ? null : Stopwatch.StartNew(); - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (sw == null) { @@ -135,7 +135,7 @@ protected override void Dispose(bool disposing) { if (disposing) { - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { try { diff --git a/src/OpenTelemetry/Metrics/CompositeMetricReaderExt.cs b/src/OpenTelemetry/Metrics/CompositeMetricReaderExt.cs index 11693017fb9..20b0b681664 100644 --- a/src/OpenTelemetry/Metrics/CompositeMetricReaderExt.cs +++ b/src/OpenTelemetry/Metrics/CompositeMetricReaderExt.cs @@ -29,7 +29,7 @@ internal sealed partial class CompositeMetricReader internal List AddMetricsWithNoViews(Instrument instrument) { var metrics = new List(this.count); - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { var metric = cur.Value.AddMetricWithNoViews(instrument); metrics.Add(metric); @@ -43,7 +43,7 @@ internal void RecordSingleStreamLongMeasurements(List metrics, long valu Debug.Assert(metrics.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers."); int index = 0; - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (metrics[index] != null) { @@ -59,7 +59,7 @@ internal void RecordSingleStreamDoubleMeasurements(List metrics, double Debug.Assert(metrics.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers."); int index = 0; - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (metrics[index] != null) { @@ -73,7 +73,7 @@ internal void RecordSingleStreamDoubleMeasurements(List metrics, double internal List> AddMetricsSuperListWithViews(Instrument instrument, List metricStreamConfigs) { var metricsSuperList = new List>(this.count); - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { var metrics = cur.Value.AddMetricsListWithViews(instrument, metricStreamConfigs); metricsSuperList.Add(metrics); @@ -87,7 +87,7 @@ internal void RecordLongMeasurements(List> metricsSuperList, long v Debug.Assert(metricsSuperList.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers."); int index = 0; - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (metricsSuperList[index].Count > 0) { @@ -103,7 +103,7 @@ internal void RecordDoubleMeasurements(List> metricsSuperList, doub Debug.Assert(metricsSuperList.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers."); int index = 0; - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (metricsSuperList[index].Count > 0) { @@ -119,7 +119,7 @@ internal void CompleteSingleStreamMeasurements(List metrics) Debug.Assert(metrics.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers."); int index = 0; - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (metrics[index] != null) { @@ -135,7 +135,7 @@ internal void CompleteMesaurements(List> metricsSuperList) Debug.Assert(metricsSuperList.Count == this.count, "The count of metrics to be updated for a CompositeReader must match the number of individual readers."); int index = 0; - for (var cur = this.head; cur != null; cur = cur.Next) + for (var cur = this.Head; cur != null; cur = cur.Next) { if (metricsSuperList[index].Count > 0) { diff --git a/src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs b/src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs deleted file mode 100644 index aa5a5ace8e5..00000000000 --- a/src/OpenTelemetry/Metrics/MeterProviderBuilderBase.cs +++ /dev/null @@ -1,169 +0,0 @@ -// -// 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 System.Diagnostics.Metrics; -using System.Text.RegularExpressions; -using OpenTelemetry.Internal; -using OpenTelemetry.Resources; - -namespace OpenTelemetry.Metrics -{ - /// - /// Build MeterProvider with Instrumentations, Meters, - /// Resource, Readers, and Views. - /// - public abstract class MeterProviderBuilderBase : MeterProviderBuilder - { - internal const int MaxMetricsDefault = 1000; - internal const int MaxMetricPointsPerMetricDefault = 2000; - private readonly List instrumentationFactories = new(); - private readonly List meterSources = new(); - private readonly List> viewConfigs = new(); - private ResourceBuilder resourceBuilder = ResourceBuilder.CreateDefault(); - private int maxMetricStreams = MaxMetricsDefault; - private int maxMetricPointsPerMetricStream = MaxMetricPointsPerMetricDefault; - - protected MeterProviderBuilderBase() - { - } - - internal List MetricReaders { get; } = new List(); - - internal ResourceBuilder ResourceBuilder - { - get => this.resourceBuilder; - set - { - Debug.Assert(value != null, $"{nameof(this.ResourceBuilder)} must not be set to null"); - this.resourceBuilder = value; - } - } - - /// - public override MeterProviderBuilder AddInstrumentation(Func instrumentationFactory) - { - Guard.ThrowIfNull(instrumentationFactory); - - this.instrumentationFactories.Add( - new InstrumentationFactory( - typeof(TInstrumentation).Name, - "semver:" + typeof(TInstrumentation).Assembly.GetName().Version, - instrumentationFactory)); - - return this; - } - - /// - public override MeterProviderBuilder AddMeter(params string[] names) - { - Guard.ThrowIfNull(names); - - foreach (var name in names) - { - Guard.ThrowIfNullOrWhitespace(name); - - this.meterSources.Add(name); - } - - return this; - } - - internal MeterProviderBuilder AddReader(MetricReader reader) - { - this.MetricReaders.Add(reader); - return this; - } - - internal MeterProviderBuilder AddView(string instrumentName, string name) - { - return this.AddView( - instrumentName, - new MetricStreamConfiguration - { - Name = name, - }); - } - - internal MeterProviderBuilder AddView(string instrumentName, MetricStreamConfiguration metricStreamConfiguration) - { - if (instrumentName.IndexOf('*') != -1) - { - var pattern = '^' + Regex.Escape(instrumentName).Replace("\\*", ".*"); - var regex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase); - return this.AddView(instrument => regex.IsMatch(instrument.Name) ? metricStreamConfiguration : null); - } - else - { - return this.AddView(instrument => instrument.Name.Equals(instrumentName, StringComparison.OrdinalIgnoreCase) ? metricStreamConfiguration : null); - } - } - - internal MeterProviderBuilder AddView(Func viewConfig) - { - this.viewConfigs.Add(viewConfig); - return this; - } - - internal MeterProviderBuilder SetMaxMetricStreams(int maxMetricStreams) - { - Guard.ThrowIfOutOfRange(maxMetricStreams, min: 1); - - this.maxMetricStreams = maxMetricStreams; - return this; - } - - internal MeterProviderBuilder SetMaxMetricPointsPerMetricStream(int maxMetricPointsPerMetricStream) - { - Guard.ThrowIfOutOfRange(maxMetricPointsPerMetricStream, min: 1); - - this.maxMetricPointsPerMetricStream = maxMetricPointsPerMetricStream; - return this; - } - - /// - /// Run the configured actions to initialize the . - /// - /// . - protected MeterProvider Build() - { - return new MeterProviderSdk( - this.resourceBuilder.Build(), - this.meterSources, - this.instrumentationFactories, - this.viewConfigs, - this.maxMetricStreams, - this.maxMetricPointsPerMetricStream, - this.MetricReaders.ToArray()); - } - - 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/Metrics/MeterProviderSdk.cs b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs index 437685f32a4..223290a210e 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs +++ b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System; using System.Collections.Generic; using System.Diagnostics; @@ -27,39 +29,48 @@ namespace OpenTelemetry.Metrics { internal sealed class MeterProviderSdk : MeterProvider { + internal readonly IDisposable? OwnedServiceProvider; internal int ShutdownCount; + internal bool Disposed; + private readonly List instrumentations = new(); - private readonly List> viewConfigs; + private readonly List> viewConfigs; private readonly object collectLock = new(); private readonly MeterListener listener; - private readonly MetricReader reader; - private readonly CompositeMetricReader compositeMetricReader; - private bool disposed; + private readonly MetricReader? reader; + private readonly CompositeMetricReader? compositeMetricReader; internal MeterProviderSdk( - Resource resource, - IEnumerable meterSources, - List instrumentationFactories, - List> viewConfigs, - int maxMetricStreams, - int maxMetricPointsPerMetricStream, - IEnumerable readers) + IServiceProvider serviceProvider, + bool ownsServiceProvider) { + if (ownsServiceProvider) + { + this.OwnedServiceProvider = serviceProvider as IDisposable; + Debug.Assert(this.OwnedServiceProvider != null, "serviceProvider was not IDisposable"); + } + OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent("Building MeterProvider."); + var state = new MeterProviderBuilderState(serviceProvider); + + MeterProviderBuilderServiceCollectionHelper.InvokeRegisteredConfigureStateCallbacks( + serviceProvider, + state); + StringBuilder exportersAdded = new StringBuilder(); StringBuilder instrumentationFactoriesAdded = new StringBuilder(); - this.Resource = resource; - this.viewConfigs = viewConfigs; + this.Resource = (state.ResourceBuilder ?? ResourceBuilder.CreateDefault()).Build(); + this.viewConfigs = state.ViewConfigs; - foreach (var reader in readers) + foreach (var reader in state.Readers) { Guard.ThrowIfNull(reader); reader.SetParentProvider(this); - reader.SetMaxMetricStreams(maxMetricStreams); - reader.SetMaxMetricPointsPerMetricStream(maxMetricPointsPerMetricStream); + reader.SetMaxMetricStreams(state.MaxMetricStreams); + reader.SetMaxMetricPointsPerMetricStream(state.MaxMetricPointsPerMetricStream); if (this.reader == null) { @@ -98,12 +109,12 @@ internal MeterProviderSdk( this.compositeMetricReader = this.reader as CompositeMetricReader; - if (instrumentationFactories.Any()) + if (state.Instrumentation.Any()) { - foreach (var instrumentationFactory in instrumentationFactories) + foreach (var instrumentation in state.Instrumentation) { - this.instrumentations.Add(instrumentationFactory.Factory()); - instrumentationFactoriesAdded.Append(instrumentationFactory.Name); + this.instrumentations.Add(instrumentation.Instance); + instrumentationFactoriesAdded.Append(instrumentation.Name); instrumentationFactoriesAdded.Append(';'); } } @@ -116,18 +127,18 @@ internal MeterProviderSdk( // Setup Listener Func shouldListenTo = instrument => false; - if (meterSources.Any(s => WildcardHelper.ContainsWildcard(s))) + if (state.MeterSources.Any(s => WildcardHelper.ContainsWildcard(s))) { - var regex = WildcardHelper.GetWildcardRegex(meterSources); + var regex = WildcardHelper.GetWildcardRegex(state.MeterSources); shouldListenTo = instrument => regex.IsMatch(instrument.Meter.Name); } - else if (meterSources.Any()) + else if (state.MeterSources.Any()) { - var meterSourcesToSubscribe = new HashSet(meterSources, StringComparer.OrdinalIgnoreCase); + var meterSourcesToSubscribe = new HashSet(state.MeterSources, StringComparer.OrdinalIgnoreCase); shouldListenTo = instrument => meterSourcesToSubscribe.Contains(instrument.Meter.Name); } - OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent($"Listening to following meters = \"{string.Join(";", meterSources)}\"."); + OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent($"Listening to following meters = \"{string.Join(";", state.MeterSources)}\"."); this.listener = new MeterListener(); var viewConfigCount = this.viewConfigs.Count; @@ -154,11 +165,11 @@ internal MeterProviderSdk( // possible size, to avoid any array resize/copy internally. // There may be excess space wasted, but it'll eligible for // GC right after this method. - var metricStreamConfigs = new List(viewConfigCount); + var metricStreamConfigs = new List(viewConfigCount); for (var i = 0; i < viewConfigCount; ++i) { var viewConfig = this.viewConfigs[i]; - MetricStreamConfiguration metricStreamConfig = null; + MetricStreamConfiguration? metricStreamConfig = null; try { @@ -320,9 +331,9 @@ internal MeterProviderSdk( internal List Instrumentations => this.instrumentations; - internal MetricReader Reader => this.reader; + internal MetricReader? Reader => this.reader; - internal void MeasurementsCompletedSingleStream(Instrument instrument, object state) + internal void MeasurementsCompletedSingleStream(Instrument instrument, object? state) { Debug.Assert(instrument != null, "instrument must be non-null."); @@ -334,7 +345,7 @@ internal void MeasurementsCompletedSingleStream(Instrument instrument, object st return; } - this.reader.CompleteSingleStreamMeasurement(metric); + this.reader?.CompleteSingleStreamMeasurement(metric); } else { @@ -348,7 +359,7 @@ internal void MeasurementsCompletedSingleStream(Instrument instrument, object st } } - internal void MeasurementsCompleted(Instrument instrument, object state) + internal void MeasurementsCompleted(Instrument instrument, object? state) { Debug.Assert(instrument != null, "instrument must be non-null."); @@ -360,7 +371,7 @@ internal void MeasurementsCompleted(Instrument instrument, object state) return; } - this.reader.CompleteMeasurement(metrics); + this.reader?.CompleteMeasurement(metrics); } else { @@ -374,7 +385,7 @@ internal void MeasurementsCompleted(Instrument instrument, object state) } } - internal void MeasurementRecordedDouble(Instrument instrument, double value, ReadOnlySpan> tagsRos, object state) + internal void MeasurementRecordedDouble(Instrument instrument, double value, ReadOnlySpan> tagsRos, object? state) { Debug.Assert(instrument != null, "instrument must be non-null."); @@ -382,17 +393,17 @@ internal void MeasurementRecordedDouble(Instrument instrument, double value, Rea { if (state is not List metrics) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } - this.reader.RecordDoubleMeasurement(metrics, value, tagsRos); + this.reader?.RecordDoubleMeasurement(metrics, value, tagsRos); } else { if (state is not List> metricsSuperList) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } @@ -400,7 +411,7 @@ internal void MeasurementRecordedDouble(Instrument instrument, double value, Rea } } - internal void MeasurementRecordedLong(Instrument instrument, long value, ReadOnlySpan> tagsRos, object state) + internal void MeasurementRecordedLong(Instrument instrument, long value, ReadOnlySpan> tagsRos, object? state) { Debug.Assert(instrument != null, "instrument must be non-null."); @@ -408,17 +419,17 @@ internal void MeasurementRecordedLong(Instrument instrument, long value, ReadOnl { if (state is not List metrics) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } - this.reader.RecordLongMeasurement(metrics, value, tagsRos); + this.reader?.RecordLongMeasurement(metrics, value, tagsRos); } else { if (state is not List> metricsSuperList) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } @@ -426,7 +437,7 @@ internal void MeasurementRecordedLong(Instrument instrument, long value, ReadOnl } } - internal void MeasurementRecordedLongSingleStream(Instrument instrument, long value, ReadOnlySpan> tagsRos, object state) + internal void MeasurementRecordedLongSingleStream(Instrument instrument, long value, ReadOnlySpan> tagsRos, object? state) { Debug.Assert(instrument != null, "instrument must be non-null."); @@ -434,17 +445,17 @@ internal void MeasurementRecordedLongSingleStream(Instrument instrument, long va { if (state is not Metric metric) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } - this.reader.RecordSingleStreamLongMeasurement(metric, value, tagsRos); + this.reader?.RecordSingleStreamLongMeasurement(metric, value, tagsRos); } else { if (state is not List metrics) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } @@ -452,7 +463,7 @@ internal void MeasurementRecordedLongSingleStream(Instrument instrument, long va } } - internal void MeasurementRecordedDoubleSingleStream(Instrument instrument, double value, ReadOnlySpan> tagsRos, object state) + internal void MeasurementRecordedDoubleSingleStream(Instrument instrument, double value, ReadOnlySpan> tagsRos, object? state) { Debug.Assert(instrument != null, "instrument must be non-null."); @@ -460,17 +471,17 @@ internal void MeasurementRecordedDoubleSingleStream(Instrument instrument, doubl { if (state is not Metric metric) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } - this.reader.RecordSingleStreamDoubleMeasurement(metric, value, tagsRos); + this.reader?.RecordSingleStreamDoubleMeasurement(metric, value, tagsRos); } else { if (state is not List metrics) { - OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument.Name, "SDK internal error occurred.", "Contact SDK owners."); + OpenTelemetrySdkEventSource.Log.MeasurementDropped(instrument!.Name, "SDK internal error occurred.", "Contact SDK owners."); return; } @@ -544,7 +555,7 @@ internal bool OnShutdown(int timeoutMilliseconds) protected override void Dispose(bool disposing) { OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent($"{nameof(MeterProviderSdk)}.{nameof(this.Dispose)} started."); - if (!this.disposed) + if (!this.Disposed) { if (disposing) { @@ -563,10 +574,12 @@ protected override void Dispose(bool disposing) this.reader?.Dispose(); this.compositeMetricReader?.Dispose(); - this.listener.Dispose(); + this.listener?.Dispose(); + + this.OwnedServiceProvider?.Dispose(); } - this.disposed = true; + this.Disposed = true; OpenTelemetrySdkEventSource.Log.ProviderDisposed(nameof(MeterProvider)); } diff --git a/src/OpenTelemetry/Metrics/MetricReaderOptions.cs b/src/OpenTelemetry/Metrics/MetricReaderOptions.cs index 1e1cde9d315..69f9e12dc9b 100644 --- a/src/OpenTelemetry/Metrics/MetricReaderOptions.cs +++ b/src/OpenTelemetry/Metrics/MetricReaderOptions.cs @@ -14,6 +14,10 @@ // limitations under the License. // +#nullable enable + +using OpenTelemetry.Internal; + namespace OpenTelemetry.Metrics; /// @@ -21,6 +25,8 @@ namespace OpenTelemetry.Metrics; /// public class MetricReaderOptions { + private PeriodicExportingMetricReaderOptions? periodicExportingMetricReaderOptions; + /// /// Gets or sets the . /// @@ -29,5 +35,13 @@ public class MetricReaderOptions /// /// Gets or sets the . /// - public PeriodicExportingMetricReaderOptions PeriodicExportingMetricReaderOptions { get; set; } = new PeriodicExportingMetricReaderOptions(); + public PeriodicExportingMetricReaderOptions PeriodicExportingMetricReaderOptions + { + get => this.periodicExportingMetricReaderOptions ??= new(); + set + { + Guard.ThrowIfNull(value); + this.periodicExportingMetricReaderOptions = value; + } + } } diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs index 0830cf71cdd..8553b419dfa 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs @@ -52,10 +52,7 @@ public void TestAddOtlpExporter_SetsCorrectMetricReaderDefaults() meterProvider.Dispose(); meterProvider = Sdk.CreateMeterProviderBuilder() - .AddOtlpExporter((exporterOptions, metricReaderOptions) => - { - metricReaderOptions.PeriodicExportingMetricReaderOptions = null; - }) + .AddOtlpExporter() .Build(); CheckMetricReaderDefaults(); diff --git a/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs b/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs index 9ed9e3a1f75..f4acf44b4e2 100644 --- a/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs +++ b/test/OpenTelemetry.Extensions.Hosting.Tests/HostingMeterExtensionTests.cs @@ -21,6 +21,7 @@ using Microsoft.Extensions.Hosting; using OpenTelemetry.Metrics; using Xunit; +using static OpenTelemetry.Extensions.Hosting.Tests.HostingTracerExtensionTests; namespace OpenTelemetry.Extensions.Hosting.Tests { @@ -90,7 +91,7 @@ public void AddOpenTelemetryMeterProvider_ServiceProviderArgument_ServicesRegist services.AddSingleton(testInstrumentation); services.AddOpenTelemetryMetrics(builder => { - builder.Configure( + builder.ConfigureBuilder( (sp, b) => b.AddInstrumentation(() => sp.GetRequiredService())); }); @@ -114,7 +115,7 @@ public void AddOpenTelemetryMeterProvider_BadArgs_NullServiceCollection() Assert.Throws(() => services.AddOpenTelemetryMetrics(builder => { - builder.Configure( + builder.ConfigureBuilder( (sp, b) => b.AddInstrumentation(() => sp.GetRequiredService())); })); } @@ -138,10 +139,10 @@ public void AddOpenTelemetryMeterProvider_NestedConfigureCallbacks() int configureCalls = 0; var services = new ServiceCollection(); services.AddOpenTelemetryMetrics(builder => builder - .Configure((sp1, builder1) => + .ConfigureBuilder((sp1, builder1) => { configureCalls++; - builder1.Configure((sp2, builder2) => + builder1.ConfigureBuilder((sp2, builder2) => { configureCalls++; }); @@ -163,7 +164,7 @@ public void AddOpenTelemetryMeterProvider_ConfigureCallbacksUsingExtensions() services.AddSingleton(); services.AddOpenTelemetryMetrics(builder => builder - .Configure((sp1, builder1) => + .ConfigureBuilder((sp1, builder1) => { builder1 .AddInstrumentation() @@ -178,40 +179,25 @@ public void AddOpenTelemetryMeterProvider_ConfigureCallbacksUsingExtensions() Assert.True(meterProvider.Reader is TestReader); } - [Fact(Skip = "Known limitation. See issue 1215.")] - public void AddOpenTelemetryMeterProvider_Idempotent() + [Fact] + public void AddOpenTelemetryMetrics_MultipleCallsConfigureSingleProvider() { - var testInstrumentation1 = new TestInstrumentation(); - var testInstrumentation2 = new TestInstrumentation(); - var services = new ServiceCollection(); - services.AddSingleton(testInstrumentation1); - services.AddOpenTelemetryMetrics(builder => - { - builder.AddInstrumentation(() => testInstrumentation1); - }); - services.AddOpenTelemetryMetrics(builder => - { - builder.AddInstrumentation(() => testInstrumentation2); - }); + services.AddOpenTelemetryMetrics(builder => builder.AddMeter("TestSourceBuilder1")); + services.AddOpenTelemetryMetrics(); + services.AddOpenTelemetryMetrics(builder => builder.AddMeter("TestSourceBuilder2")); - var serviceProvider = services.BuildServiceProvider(); + using var serviceProvider = services.BuildServiceProvider(); - var meterFactory = serviceProvider.GetRequiredService(); - Assert.NotNull(meterFactory); + var providers = serviceProvider.GetServices(); - Assert.False(testInstrumentation1.Disposed); - Assert.False(testInstrumentation2.Disposed); - serviceProvider.Dispose(); - Assert.True(testInstrumentation1.Disposed); - Assert.True(testInstrumentation2.Disposed); + Assert.Single(providers); } private static MeterProviderBuilder AddMyFeature(MeterProviderBuilder meterProviderBuilder) { - (meterProviderBuilder.GetServices() ?? throw new NotSupportedException("MyFeature requires a hosting MeterProviderBuilder instance.")) - .AddSingleton(); + meterProviderBuilder.ConfigureServices(services => services.AddSingleton()); return meterProviderBuilder.AddReader(); } diff --git a/test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs b/test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs new file mode 100644 index 00000000000..b4c96f2cc7c --- /dev/null +++ b/test/OpenTelemetry.Tests/Metrics/MeterProviderBuilderExtensionsTests.cs @@ -0,0 +1,293 @@ +// +// 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.Linq; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using OpenTelemetry.Resources; +using Xunit; + +namespace OpenTelemetry.Metrics.Tests +{ + public class MeterProviderBuilderExtensionsTests + { + [Fact] + public void ServiceLifecycleAvailableToSDKBuilderTest() + { + var builder = Sdk.CreateMeterProviderBuilder(); + + builder.ConfigureServices(services => services.AddSingleton()); + + MyInstrumentation myInstrumentation = null; + + RunBuilderServiceLifecycleTest( + builder, + () => + { + var provider = builder.Build() as MeterProviderSdk; + + // Note: Build can only be called once + Assert.Throws(() => builder.Build()); + + Assert.NotNull(provider); + Assert.NotNull(provider.OwnedServiceProvider); + + myInstrumentation = ((IServiceProvider)provider.OwnedServiceProvider).GetRequiredService(); + + return provider; + }, + provider => + { + provider.Dispose(); + }); + + Assert.NotNull(myInstrumentation); + Assert.True(myInstrumentation.Disposed); + } + + [Fact] + public void ServiceLifecycleAvailableToServicesBuilderTest() + { + var services = new ServiceCollection(); + + bool testRun = false; + + ServiceProvider serviceProvider = null; + MeterProviderSdk provider = null; + + services.ConfigureOpenTelemetryMetrics(builder => + { + testRun = true; + + RunBuilderServiceLifecycleTest( + builder, + () => + { + // Note: Build can't be called directly on builder tied to external services + Assert.Throws(() => builder.Build()); + + serviceProvider = services.BuildServiceProvider(); + + provider = serviceProvider.GetRequiredService() as MeterProviderSdk; + + Assert.NotNull(provider); + Assert.Null(provider.OwnedServiceProvider); + + return provider; + }, + (provider) => { }); + }); + + Assert.True(testRun); + + Assert.NotNull(serviceProvider); + Assert.NotNull(provider); + + Assert.False(provider.Disposed); + + serviceProvider.Dispose(); + + Assert.True(provider.Disposed); + } + + [Fact] + public void SingleProviderForServiceCollectionTest() + { + var services = new ServiceCollection(); + + services.ConfigureOpenTelemetryMetrics(builder => + { + builder.AddInstrumentation(() => new()); + }); + + services.ConfigureOpenTelemetryMetrics(builder => + { + builder.AddInstrumentation(() => new()); + }); + + using var serviceProvider = services.BuildServiceProvider(); + + Assert.NotNull(serviceProvider); + + var meterProviders = serviceProvider.GetServices(); + + Assert.Single(meterProviders); + + var provider = meterProviders.First() as MeterProviderSdk; + + Assert.NotNull(provider); + + Assert.Equal(2, provider.Instrumentations.Count); + } + + [Fact] + public void AddReaderUsingDependencyInjectionTest() + { + var builder = Sdk.CreateMeterProviderBuilder(); + + builder.AddReader(); + builder.AddReader(); + + using var provider = builder.Build() as MeterProviderSdk; + + Assert.NotNull(provider); + + var readers = ((IServiceProvider)provider.OwnedServiceProvider).GetServices(); + + // Note: Two "Add" calls but it is a singleton so only a single registration is produced + Assert.Single(readers); + + var reader = provider.Reader as CompositeMetricReader; + + Assert.NotNull(reader); + + // Note: Two "Add" calls due yield two readers added to provider, even though they are the same + Assert.True(reader.Head.Value is MyReader); + Assert.True(reader.Head.Next?.Value is MyReader); + } + + [Fact] + public void SetAndConfigureResourceTest() + { + var builder = Sdk.CreateMeterProviderBuilder(); + + int configureInvocations = 0; + + builder.SetResourceBuilder(ResourceBuilder.CreateEmpty().AddService("Test")); + builder.ConfigureResource(builder => + { + configureInvocations++; + + Assert.Single(builder.Resources); + + builder.AddAttributes(new Dictionary() { ["key1"] = "value1" }); + + Assert.Equal(2, builder.Resources.Count); + }); + builder.SetResourceBuilder(ResourceBuilder.CreateEmpty()); + builder.ConfigureResource(builder => + { + configureInvocations++; + + Assert.Empty(builder.Resources); + + builder.AddAttributes(new Dictionary() { ["key2"] = "value2" }); + + Assert.Single(builder.Resources); + }); + + using var provider = builder.Build() as MeterProviderSdk; + + Assert.Equal(2, configureInvocations); + + Assert.Single(provider.Resource.Attributes); + Assert.Contains(provider.Resource.Attributes, kvp => kvp.Key == "key2" && (string)kvp.Value == "value2"); + } + + private static void RunBuilderServiceLifecycleTest( + MeterProviderBuilder builder, + Func buildFunc, + Action postAction) + { + var baseBuilder = builder as MeterProviderBuilderBase; + Assert.Null(baseBuilder.State); + + builder.AddMeter("TestSource"); + + bool configureServicesCalled = false; + builder.ConfigureServices(services => + { + configureServicesCalled = true; + + Assert.NotNull(services); + + services.TryAddSingleton(); + + services.ConfigureOpenTelemetryMetrics(b => + { + // Note: This is strange to call ConfigureOpenTelemetryMetrics here, but supported + b.AddInstrumentation(); + }); + }); + + int configureBuilderInvocations = 0; + builder.ConfigureBuilder((sp, builder) => + { + configureBuilderInvocations++; + + var baseBuilder = builder as MeterProviderBuilderBase; + Assert.NotNull(baseBuilder?.State); + + builder.AddMeter("TestSource2"); + + Assert.Contains(baseBuilder.State.MeterSources, s => s == "TestSource"); + Assert.Contains(baseBuilder.State.MeterSources, s => s == "TestSource2"); + + // Note: Services can't be configured at this stage + Assert.Throws( + () => builder.ConfigureServices(services => services.TryAddSingleton())); + + builder.AddReader(sp.GetRequiredService()); + + builder.ConfigureBuilder((_, b) => + { + // Note: ConfigureBuilder calls can be nested, this is supported + configureBuilderInvocations++; + + b.ConfigureBuilder((_, _) => + { + configureBuilderInvocations++; + }); + }); + }); + + var provider = buildFunc(); + + Assert.True(configureServicesCalled); + Assert.Equal(3, configureBuilderInvocations); + + Assert.Single(provider.Instrumentations); + Assert.True(provider.Instrumentations[0] is MyInstrumentation); + Assert.True(provider.Reader is MyReader); + + postAction(provider); + } + + private sealed class MyInstrumentation : IDisposable + { + internal bool Disposed; + + public void Dispose() + { + this.Disposed = true; + } + } + + private sealed class MyReader : MetricReader + { + } + + private sealed class MyExporter : BaseExporter + { + public override ExportResult Export(in Batch batch) + { + return ExportResult.Success; + } + } + } +} diff --git a/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs b/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs index 25dc7500087..83d64bd7932 100644 --- a/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs +++ b/test/OpenTelemetry.Tests/Metrics/MetricAPITest.cs @@ -1356,26 +1356,26 @@ int MetricPointCount() // for no tag point! // This may be changed later. counterLong.Add(10); - for (int i = 0; i < MeterProviderBuilderBase.MaxMetricPointsPerMetricDefault + 1; i++) + for (int i = 0; i < MeterProviderBuilderState.MaxMetricPointsPerMetricDefault + 1; i++) { counterLong.Add(10, new KeyValuePair("key", "value" + i)); } meterProvider.ForceFlush(MaxTimeToAllowForFlush); - Assert.Equal(MeterProviderBuilderBase.MaxMetricPointsPerMetricDefault, MetricPointCount()); + Assert.Equal(MeterProviderBuilderState.MaxMetricPointsPerMetricDefault, MetricPointCount()); exportedItems.Clear(); counterLong.Add(10); - for (int i = 0; i < MeterProviderBuilderBase.MaxMetricPointsPerMetricDefault + 1; i++) + for (int i = 0; i < MeterProviderBuilderState.MaxMetricPointsPerMetricDefault + 1; i++) { counterLong.Add(10, new KeyValuePair("key", "value" + i)); } meterProvider.ForceFlush(MaxTimeToAllowForFlush); - Assert.Equal(MeterProviderBuilderBase.MaxMetricPointsPerMetricDefault, MetricPointCount()); + Assert.Equal(MeterProviderBuilderState.MaxMetricPointsPerMetricDefault, MetricPointCount()); counterLong.Add(10); - for (int i = 0; i < MeterProviderBuilderBase.MaxMetricPointsPerMetricDefault + 1; i++) + for (int i = 0; i < MeterProviderBuilderState.MaxMetricPointsPerMetricDefault + 1; i++) { counterLong.Add(10, new KeyValuePair("key", "value" + i)); } @@ -1386,7 +1386,7 @@ int MetricPointCount() counterLong.Add(10, new KeyValuePair("key", "valueC")); exportedItems.Clear(); meterProvider.ForceFlush(MaxTimeToAllowForFlush); - Assert.Equal(MeterProviderBuilderBase.MaxMetricPointsPerMetricDefault, MetricPointCount()); + Assert.Equal(MeterProviderBuilderState.MaxMetricPointsPerMetricDefault, MetricPointCount()); } [Fact] From 79d8714cb30f3019f2a6fc35834a2c22dd1df5a0 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 12 Sep 2022 17:41:51 -0700 Subject: [PATCH 05/34] [Metrics] Clean up repo exporters to use new DI patterns (#3648) * Clean up metric exporters to use new DI patterns. * Support named options with in-memory exporter build-up. * Support named options in ConsoleExporter metrics extensions. * Support named options in OtlpExporter metrics extensions. * Support named options in PrometheusExporter AspNetCore metrics extensions. * Support named options in PrometheusExporter HttpListener metrics extensions. * CHANGELOG updates. * Unit tests. --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 2 + .../netstandard2.0/PublicAPI.Unshipped.txt | 2 + .../CHANGELOG.md | 5 + .../ConsoleExporterMetricsExtensions.cs | 88 +++++++++++------ .../OpenTelemetry.Exporter.Console.csproj | 1 - .../.publicApi/net462/PublicAPI.Unshipped.txt | 2 + .../netstandard2.0/PublicAPI.Unshipped.txt | 2 + .../CHANGELOG.md | 5 + .../InMemoryExporterMetricsExtensions.cs | 98 +++++++++++++------ .../.publicApi/net462/PublicAPI.Unshipped.txt | 2 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 2 + .../netstandard2.0/PublicAPI.Unshipped.txt | 2 + .../netstandard2.1/PublicAPI.Unshipped.txt | 2 + .../CHANGELOG.md | 4 + ...etry.Exporter.OpenTelemetryProtocol.csproj | 1 - .../OtlpMetricExporterExtensions.cs | 87 ++++++++++------ .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 4 +- .../CHANGELOG.md | 5 + ...eusExporterApplicationBuilderExtensions.cs | 3 +- ...sExporterEndpointRouteBuilderExtensions.cs | 4 +- ...sExporterMeterProviderBuilderExtensions.cs | 50 +++++++--- .../.publicApi/net462/PublicAPI.Unshipped.txt | 4 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 4 +- .../CHANGELOG.md | 5 + ...pListenerMeterProviderBuilderExtensions.cs | 48 ++++++--- .../Internal/ServiceProviderExtensions.cs | 47 --------- .../IntegrationTests.cs | 2 - .../OtlpMetricsExporterTests.cs | 27 +++++ ...rterMeterProviderBuilderExtensionsTests.cs | 45 +++++++++ ...enerMeterProviderBuilderExtensionsTests.cs | 45 +++++++++ .../Metrics/MultipleReadersTests.cs | 20 +++- 31 files changed, 448 insertions(+), 170 deletions(-) delete mode 100644 src/OpenTelemetry/Internal/ServiceProviderExtensions.cs create mode 100644 test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMeterProviderBuilderExtensionsTests.cs create mode 100644 test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerMeterProviderBuilderExtensionsTests.cs diff --git a/src/OpenTelemetry.Exporter.Console/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Console/.publicApi/net462/PublicAPI.Unshipped.txt index 91e9fc8830a..0f6bd0c9e9a 100644 --- a/src/OpenTelemetry.Exporter.Console/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Console/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1 +1,3 @@ override OpenTelemetry.Exporter.ConsoleLogRecordExporter.Dispose(bool disposing) -> void +static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Console/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Console/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 91e9fc8830a..0f6bd0c9e9a 100644 --- a/src/OpenTelemetry.Exporter.Console/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Console/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1 +1,3 @@ override OpenTelemetry.Exporter.ConsoleLogRecordExporter.Dispose(bool disposing) -> void +static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md index f28b918564d..1b584dd454a 100644 --- a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md @@ -6,6 +6,11 @@ the data if it is disposed. ([#3578](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3578)) +* Added overloads which accept a name to the `MeterProviderBuilder` + `AddConsoleExporter` extension to allow for more fine-grained options + management + ([#3648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3648)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs index ed22e66e31c..e8250fadf13 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs @@ -16,6 +16,8 @@ using System; using System.Threading; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Exporter; using OpenTelemetry.Internal; @@ -35,70 +37,94 @@ public static class ConsoleExporterMetricsExtensions /// builder to use. /// The instance of to chain the calls. public static MeterProviderBuilder AddConsoleExporter(this MeterProviderBuilder builder) - { - return AddConsoleExporter(builder, options => { }); - } + => AddConsoleExporter(builder, name: null, configureExporter: null); /// /// Adds to the . /// /// builder to use. - /// Exporter configuration options. + /// Callback action for configuring . /// The instance of to chain the calls. public static MeterProviderBuilder AddConsoleExporter(this MeterProviderBuilder builder, Action configureExporter) + => AddConsoleExporter(builder, name: null, configureExporter); + + /// + /// Adds to the . + /// + /// builder to use. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static MeterProviderBuilder AddConsoleExporter( + this MeterProviderBuilder builder, + string name, + Action configureExporter) { Guard.ThrowIfNull(builder); - if (builder is IDeferredMeterProviderBuilder deferredMeterProviderBuilder) + name ??= Options.DefaultName; + + if (configureExporter != null) { - return deferredMeterProviderBuilder.Configure((sp, builder) => - { - AddConsoleExporter(builder, sp.GetOptions(), sp.GetOptions(), configureExporter, null); - }); + builder.ConfigureServices(services => services.Configure(name, configureExporter)); } - return AddConsoleExporter(builder, new ConsoleExporterOptions(), new MetricReaderOptions(), configureExporter, null); + return builder.ConfigureBuilder((sp, builder) => + { + AddConsoleExporter( + builder, + sp.GetRequiredService>().Get(name), + sp.GetRequiredService>().Get(name)); + }); } /// /// Adds to the . /// /// builder to use. - /// Exporter and configuration options. + /// Callback action for + /// configuring and . /// The instance of to chain the calls. public static MeterProviderBuilder AddConsoleExporter( this MeterProviderBuilder builder, Action configureExporterAndMetricReader) + => AddConsoleExporter(builder, name: null, configureExporterAndMetricReader); + + /// + /// Adds to the . + /// + /// builder to use. + /// Name which is used when retrieving options. + /// Callback action for + /// configuring and . + /// The instance of to chain the calls. + public static MeterProviderBuilder AddConsoleExporter( + this MeterProviderBuilder builder, + string name, + Action configureExporterAndMetricReader) { - Guard.ThrowIfNull(builder, nameof(builder)); + Guard.ThrowIfNull(builder); - if (builder is IDeferredMeterProviderBuilder deferredMeterProviderBuilder) + name ??= Options.DefaultName; + + return builder.ConfigureBuilder((sp, builder) => { - return deferredMeterProviderBuilder.Configure((sp, builder) => - { - AddConsoleExporter(builder, sp.GetOptions(), sp.GetOptions(), null, configureExporterAndMetricReader); - }); - } + var exporterOptions = sp.GetRequiredService>().Get(name); + var metricReaderOptions = sp.GetRequiredService>().Get(name); - return AddConsoleExporter(builder, new ConsoleExporterOptions(), new MetricReaderOptions(), null, configureExporterAndMetricReader); + configureExporterAndMetricReader?.Invoke(exporterOptions, metricReaderOptions); + + AddConsoleExporter(builder, exporterOptions, metricReaderOptions); + }); } private static MeterProviderBuilder AddConsoleExporter( MeterProviderBuilder builder, ConsoleExporterOptions exporterOptions, - MetricReaderOptions metricReaderOptions, - Action configureExporter, - Action configureExporterAndMetricReader) + MetricReaderOptions metricReaderOptions) { - if (configureExporterAndMetricReader != null) - { - configureExporterAndMetricReader.Invoke(exporterOptions, metricReaderOptions); - } - else - { - configureExporter?.Invoke(exporterOptions); - } - var metricExporter = new ConsoleMetricExporter(exporterOptions); var metricReader = PeriodicExportingMetricReaderHelper.CreatePeriodicExportingMetricReader( diff --git a/src/OpenTelemetry.Exporter.Console/OpenTelemetry.Exporter.Console.csproj b/src/OpenTelemetry.Exporter.Console/OpenTelemetry.Exporter.Console.csproj index d0f69330b15..e91623caf6b 100644 --- a/src/OpenTelemetry.Exporter.Console/OpenTelemetry.Exporter.Console.csproj +++ b/src/OpenTelemetry.Exporter.Console/OpenTelemetry.Exporter.Console.csproj @@ -24,7 +24,6 @@ - diff --git a/src/OpenTelemetry.Exporter.InMemory/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.InMemory/.publicApi/net462/PublicAPI.Unshipped.txt index fb80e7c3a78..a57d90fc54f 100644 --- a/src/OpenTelemetry.Exporter.InMemory/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.InMemory/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1 +1,3 @@ override OpenTelemetry.Exporter.InMemoryExporter.Dispose(bool disposing) -> void +static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Collections.Generic.ICollection exportedItems, System.Action configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Collections.Generic.ICollection exportedItems, System.Action configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.InMemory/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.InMemory/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index fb80e7c3a78..a57d90fc54f 100644 --- a/src/OpenTelemetry.Exporter.InMemory/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.InMemory/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1 +1,3 @@ override OpenTelemetry.Exporter.InMemoryExporter.Dispose(bool disposing) -> void +static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Collections.Generic.ICollection exportedItems, System.Action configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.InMemoryExporterMetricsExtensions.AddInMemoryExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Collections.Generic.ICollection exportedItems, System.Action configureMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md index e701088e4d2..744052f14ec 100644 --- a/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md @@ -7,6 +7,11 @@ disposed. ([#3607](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3607)) +* Added overloads which accept a name to the `MeterProviderBuilder` + `AddInMemoryExporter` extension to allow for more fine-grained options + management + ([#3648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3648)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs index 613067d5e8a..b72e16f0459 100644 --- a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs +++ b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs @@ -17,6 +17,8 @@ using System; using System.Collections.Generic; using System.Threading; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Exporter; using OpenTelemetry.Internal; @@ -40,9 +42,23 @@ public static class InMemoryExporterMetricsExtensions /// Collection which will be populated with the exported . /// The instance of to chain the calls. public static MeterProviderBuilder AddInMemoryExporter(this MeterProviderBuilder builder, ICollection exportedItems) - { - return builder.AddInMemoryExporter(exportedItems: exportedItems, configureMetricReader: null); - } + => AddInMemoryExporter(builder, name: null, exportedItems, configureMetricReader: null); + + /// + /// Adds InMemory metric exporter to the . + /// + /// + /// Be aware that may continue to be updated after export. + /// + /// builder to use. + /// Collection which will be populated with the exported . + /// Callback action for configuring . + /// The instance of to chain the calls. + public static MeterProviderBuilder AddInMemoryExporter( + this MeterProviderBuilder builder, + ICollection exportedItems, + Action configureMetricReader) + => AddInMemoryExporter(builder, name: null, exportedItems, configureMetricReader); /// /// Adds InMemory metric exporter to the . @@ -51,23 +67,32 @@ public static MeterProviderBuilder AddInMemoryExporter(this MeterProviderBuilder /// Be aware that may continue to be updated after export. /// /// builder to use. + /// Name which is used when retrieving options. /// Collection which will be populated with the exported . - /// configuration options. + /// Callback action for configuring . /// The instance of to chain the calls. - public static MeterProviderBuilder AddInMemoryExporter(this MeterProviderBuilder builder, ICollection exportedItems, Action configureMetricReader) + public static MeterProviderBuilder AddInMemoryExporter( + this MeterProviderBuilder builder, + string name, + ICollection exportedItems, + Action configureMetricReader) { Guard.ThrowIfNull(builder); Guard.ThrowIfNull(exportedItems); - if (builder is IDeferredMeterProviderBuilder deferredMeterProviderBuilder) + name ??= Options.DefaultName; + + if (configureMetricReader != null) { - return deferredMeterProviderBuilder.Configure((sp, builder) => - { - AddInMemoryExporter(builder, exportedItems, sp.GetOptions(), configureMetricReader); - }); + builder.ConfigureServices(services => services.Configure(name, configureMetricReader)); } - return AddInMemoryExporter(builder, exportedItems, new MetricReaderOptions(), configureMetricReader); + return builder.ConfigureBuilder((sp, builder) => + { + var options = sp.GetRequiredService>().Get(name); + + AddInMemoryExporter(builder, exportedItems, options); + }); } /// @@ -83,9 +108,7 @@ public static MeterProviderBuilder AddInMemoryExporter(this MeterProviderBuilder public static MeterProviderBuilder AddInMemoryExporter( this MeterProviderBuilder builder, ICollection exportedItems) - { - return builder.AddInMemoryExporter(exportedItems: exportedItems, configureMetricReader: null); - } + => AddInMemoryExporter(builder, name: null, exportedItems, configureMetricReader: null); /// /// Adds InMemory metric exporter to the . @@ -96,35 +119,55 @@ public static MeterProviderBuilder AddInMemoryExporter( /// /// builder to use. /// Collection which will be populated with the exported represented as . - /// configuration options. + /// Callback action for configuring . /// The instance of to chain the calls. public static MeterProviderBuilder AddInMemoryExporter( this MeterProviderBuilder builder, ICollection exportedItems, Action configureMetricReader) + => AddInMemoryExporter(builder, name: null, exportedItems, configureMetricReader); + + /// + /// Adds InMemory metric exporter to the . + /// The exporter will be setup to export . + /// + /// + /// Use this if you need a copy of that will not be updated after export. + /// + /// builder to use. + /// Name which is used when retrieving options. + /// Collection which will be populated with the exported represented as . + /// Callback action for configuring . + /// The instance of to chain the calls. + public static MeterProviderBuilder AddInMemoryExporter( + this MeterProviderBuilder builder, + string name, + ICollection exportedItems, + Action configureMetricReader) { Guard.ThrowIfNull(builder); Guard.ThrowIfNull(exportedItems); - if (builder is IDeferredMeterProviderBuilder deferredMeterProviderBuilder) + name ??= Options.DefaultName; + + if (configureMetricReader != null) { - return deferredMeterProviderBuilder.Configure((sp, builder) => - { - AddInMemoryExporter(builder, exportedItems, sp.GetOptions(), configureMetricReader); - }); + builder.ConfigureServices(services => services.Configure(name, configureMetricReader)); } - return AddInMemoryExporter(builder, exportedItems, new MetricReaderOptions(), configureMetricReader); + return builder.ConfigureBuilder((sp, builder) => + { + var options = sp.GetRequiredService>().Get(name); + + AddInMemoryExporter(builder, exportedItems, options); + }); } private static MeterProviderBuilder AddInMemoryExporter( MeterProviderBuilder builder, ICollection exportedItems, - MetricReaderOptions metricReaderOptions, - Action configureMetricReader) + MetricReaderOptions metricReaderOptions) { - configureMetricReader?.Invoke(metricReaderOptions); - var metricExporter = new InMemoryExporter(exportedItems); var metricReader = PeriodicExportingMetricReaderHelper.CreatePeriodicExportingMetricReader( @@ -139,11 +182,8 @@ private static MeterProviderBuilder AddInMemoryExporter( private static MeterProviderBuilder AddInMemoryExporter( MeterProviderBuilder builder, ICollection exportedItems, - MetricReaderOptions metricReaderOptions, - Action configureMetricReader) + MetricReaderOptions metricReaderOptions) { - configureMetricReader?.Invoke(metricReaderOptions); - var metricExporter = new InMemoryExporter( exportFunc: (in Batch metricBatch) => ExportMetricSnapshot(in metricBatch, exportedItems)); diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net462/PublicAPI.Unshipped.txt index e69de29bb2d..6ee083d2bf9 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt index e69de29bb2d..6ee083d2bf9 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2d..6ee083d2bf9 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index e69de29bb2d..6ee083d2bf9 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index bab3a72cbf3..9af0873f3c1 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Added overloads which accept a name to the `MeterProviderBuilder` + `AddOtlpExporter` extension to allow for more fine-grained options management + ([#3648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3648)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj index 4c584cbbe99..529e72b586f 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OpenTelemetry.Exporter.OpenTelemetryProtocol.csproj @@ -39,7 +39,6 @@ - diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs index f3c1547f181..ee7f306ca0f 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs @@ -15,6 +15,8 @@ // using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Exporter; using OpenTelemetry.Internal; @@ -31,72 +33,97 @@ public static class OtlpMetricExporterExtensions /// builder to use. /// The instance of to chain the calls. public static MeterProviderBuilder AddOtlpExporter(this MeterProviderBuilder builder) - { - return AddOtlpExporter(builder, options => { }); - } + => AddOtlpExporter(builder, name: null, configureExporter: null); /// /// Adds to the . /// /// builder to use. - /// Exporter configuration options. + /// Callback action for configuring . /// The instance of to chain the calls. public static MeterProviderBuilder AddOtlpExporter(this MeterProviderBuilder builder, Action configureExporter) + => AddOtlpExporter(builder, name: null, configureExporter); + + /// + /// Adds to the . + /// + /// builder to use. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static MeterProviderBuilder AddOtlpExporter( + this MeterProviderBuilder builder, + string name, + Action configureExporter) { Guard.ThrowIfNull(builder); - if (builder is IDeferredMeterProviderBuilder deferredMeterProviderBuilder) + name ??= Options.DefaultName; + + if (configureExporter != null) { - return deferredMeterProviderBuilder.Configure((sp, builder) => - { - AddOtlpExporter(builder, sp.GetOptions(), sp.GetOptions(), configureExporter, null, sp); - }); + builder.ConfigureServices(services => services.Configure(name, configureExporter)); } - return AddOtlpExporter(builder, new OtlpExporterOptions(), new MetricReaderOptions(), configureExporter, null, serviceProvider: null); + return builder.ConfigureBuilder((sp, builder) => + { + AddOtlpExporter( + builder, + sp.GetRequiredService>().Get(name), + sp.GetRequiredService>().Get(name), + sp); + }); } /// /// Adds to the . /// /// builder to use. - /// Exporter and configuration options. + /// Callback action for + /// configuring and . + /// The instance of to chain the calls. + public static MeterProviderBuilder AddOtlpExporter( + this MeterProviderBuilder builder, + Action configureExporterAndMetricReader) + => AddOtlpExporter(builder, name: null, configureExporterAndMetricReader); + + /// + /// Adds to the . + /// + /// builder to use. + /// Name which is used when retrieving options. + /// Callback action for + /// configuring and . /// The instance of to chain the calls. public static MeterProviderBuilder AddOtlpExporter( this MeterProviderBuilder builder, + string name, Action configureExporterAndMetricReader) { - Guard.ThrowIfNull(builder, nameof(builder)); + Guard.ThrowIfNull(builder); + + name ??= Options.DefaultName; - if (builder is IDeferredMeterProviderBuilder deferredMeterProviderBuilder) + return builder.ConfigureBuilder((sp, builder) => { - return deferredMeterProviderBuilder.Configure((sp, builder) => - { - AddOtlpExporter(builder, sp.GetOptions(), sp.GetOptions(), null, configureExporterAndMetricReader, sp); - }); - } + var exporterOptions = sp.GetRequiredService>().Get(name); + var metricReaderOptions = sp.GetRequiredService>().Get(name); + + configureExporterAndMetricReader?.Invoke(exporterOptions, metricReaderOptions); - return AddOtlpExporter(builder, new OtlpExporterOptions(), new MetricReaderOptions(), null, configureExporterAndMetricReader, serviceProvider: null); + AddOtlpExporter(builder, exporterOptions, metricReaderOptions, sp); + }); } internal static MeterProviderBuilder AddOtlpExporter( MeterProviderBuilder builder, OtlpExporterOptions exporterOptions, MetricReaderOptions metricReaderOptions, - Action configureExporter, - Action configureExporterAndMetricReader, IServiceProvider serviceProvider, Func, BaseExporter> configureExporterInstance = null) { - if (configureExporterAndMetricReader != null) - { - configureExporterAndMetricReader.Invoke(exporterOptions, metricReaderOptions); - } - else - { - configureExporter?.Invoke(exporterOptions); - } - exporterOptions.TryEnableIHttpClientFactoryIntegration(serviceProvider, "OtlpMetricExporter"); BaseExporter metricExporter = new OtlpMetricExporter(exporterOptions); diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/net6.0/PublicAPI.Unshipped.txt index 46dbf03b1ed..2fc54a64cb8 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -14,4 +14,6 @@ static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensio static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string path = null, OpenTelemetry.Metrics.MeterProvider meterProvider = null, System.Action configureBranchedPipeline = null) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string path) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder -static OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions.AddPrometheusExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions.AddPrometheusExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions.AddPrometheusExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions.AddPrometheusExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md index acd5d5ba488..151ee398408 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md @@ -6,6 +6,11 @@ instead of 200, when no metrics are collected ([#3643](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3643)) +* Added overloads which accept a name to the `MeterProviderBuilder` + `AddPrometheusExporter` extension to allow for more fine-grained options + management + ([#3648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3648)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterApplicationBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterApplicationBuilderExtensions.cs index 5d8ccce7149..408a1b59b61 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterApplicationBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterApplicationBuilderExtensions.cs @@ -17,6 +17,7 @@ using System; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Exporter; using OpenTelemetry.Internal; using OpenTelemetry.Metrics; @@ -119,7 +120,7 @@ public static IApplicationBuilder UseOpenTelemetryPrometheusScrapingEndpoint( { if (path == null) { - var options = app.ApplicationServices.GetOptions(); + var options = app.ApplicationServices.GetRequiredService>().Value; path = options.ScrapeEndpointPath ?? PrometheusExporterOptions.DefaultScrapeEndpointPath; } diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterEndpointRouteBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterEndpointRouteBuilderExtensions.cs index 77a31b87e6a..732492e0cbf 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterEndpointRouteBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterEndpointRouteBuilderExtensions.cs @@ -18,6 +18,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Exporter; using OpenTelemetry.Internal; using OpenTelemetry.Metrics; @@ -89,7 +90,8 @@ public static IEndpointConventionBuilder MapPrometheusScrapingEndpoint( if (path == null) { - var options = endpoints.ServiceProvider.GetOptions(); + var options = endpoints.ServiceProvider.GetRequiredService>().Value; + path = options.ScrapeEndpointPath ?? PrometheusExporterOptions.DefaultScrapeEndpointPath; } diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMeterProviderBuilderExtensions.cs index 1876433b946..daacd2c66b8 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMeterProviderBuilderExtensions.cs @@ -15,6 +15,8 @@ // using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Exporter; using OpenTelemetry.Exporter.Prometheus; using OpenTelemetry.Internal; @@ -30,28 +32,54 @@ public static class PrometheusExporterMeterProviderBuilderExtensions /// Adds to the . /// /// builder to use. - /// Exporter configuration options. /// The instance of to chain the calls. - public static MeterProviderBuilder AddPrometheusExporter(this MeterProviderBuilder builder, Action configure = null) + public static MeterProviderBuilder AddPrometheusExporter(this MeterProviderBuilder builder) + => AddPrometheusExporter(builder, name: null, configure: null); + + /// + /// Adds to the . + /// + /// builder to use. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static MeterProviderBuilder AddPrometheusExporter( + this MeterProviderBuilder builder, + Action configure) + => AddPrometheusExporter(builder, name: null, configure); + + /// + /// Adds to the . + /// + /// builder to use. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static MeterProviderBuilder AddPrometheusExporter( + this MeterProviderBuilder builder, + string name, + Action configure) { Guard.ThrowIfNull(builder); - if (builder is IDeferredMeterProviderBuilder deferredMeterProviderBuilder) + name ??= Options.DefaultName; + + if (configure != null) { - return deferredMeterProviderBuilder.Configure((sp, builder) => - { - AddPrometheusExporter(builder, sp.GetOptions(), configure); - }); + builder.ConfigureServices(services => services.Configure(name, configure)); } - return AddPrometheusExporter(builder, new PrometheusExporterOptions(), configure); + return builder.ConfigureBuilder((sp, builder) => + { + var options = sp.GetRequiredService>().Get(name); + + AddPrometheusExporter(builder, options); + }); } - private static MeterProviderBuilder AddPrometheusExporter(MeterProviderBuilder builder, PrometheusExporterOptions options, Action configure = null) + private static MeterProviderBuilder AddPrometheusExporter(MeterProviderBuilder builder, PrometheusExporterOptions options) { - configure?.Invoke(options); - var exporter = new PrometheusExporter(scrapeResponseCacheDurationMilliseconds: options.ScrapeResponseCacheDurationMilliseconds); + var reader = new BaseExportingMetricReader(exporter) { TemporalityPreference = MetricReaderTemporalityPreference.Cumulative, diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/net462/PublicAPI.Unshipped.txt index 01bea3492fa..9bc2e72461d 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/net462/PublicAPI.Unshipped.txt @@ -5,4 +5,6 @@ OpenTelemetry.Exporter.PrometheusHttpListenerOptions.PrometheusHttpListenerOptio OpenTelemetry.Exporter.PrometheusHttpListenerOptions.ScrapeEndpointPath.get -> string OpenTelemetry.Exporter.PrometheusHttpListenerOptions.ScrapeEndpointPath.set -> void OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions -static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 48dbc8b011e..cc20c38b13e 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -5,4 +5,6 @@ OpenTelemetry.Exporter.PrometheusHttpListenerOptions.ScrapeEndpointPath.set -> v OpenTelemetry.Exporter.PrometheusHttpListenerOptions.UriPrefixes.get -> System.Collections.Generic.IReadOnlyCollection OpenTelemetry.Exporter.PrometheusHttpListenerOptions.UriPrefixes.set -> void OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions -static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md index eb1859a39d0..f46954288a1 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md @@ -6,6 +6,11 @@ instead of 200, when no metrics are collected ([#3643](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3643)) +* Added overloads which accept a name to the `MeterProviderBuilder` + `AddPrometheusHttpListener` extension to allow for more fine-grained options + management + ([#3648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3648)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs index 41011f95ad2..605aaff6df4 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs @@ -15,6 +15,8 @@ // using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Exporter; using OpenTelemetry.Exporter.Prometheus; using OpenTelemetry.Internal; @@ -30,32 +32,54 @@ public static class PrometheusHttpListenerMeterProviderBuilderExtensions /// Adds PrometheusHttpListener to MeterProviderBuilder. /// /// builder to use. - /// PrometheusHttpListenerOptions options. + /// The instance of to chain calls. + public static MeterProviderBuilder AddPrometheusHttpListener(this MeterProviderBuilder builder) + => AddPrometheusHttpListener(builder, name: null, configure: null); + + /// + /// Adds PrometheusHttpListener to MeterProviderBuilder. + /// + /// builder to use. + /// Callback action for configuring . /// The instance of to chain calls. public static MeterProviderBuilder AddPrometheusHttpListener( this MeterProviderBuilder builder, - Action configure = null) + Action configure) + => AddPrometheusHttpListener(builder, name: null, configure); + + /// + /// Adds PrometheusHttpListener to MeterProviderBuilder. + /// + /// builder to use. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain calls. + public static MeterProviderBuilder AddPrometheusHttpListener( + this MeterProviderBuilder builder, + string name, + Action configure) { Guard.ThrowIfNull(builder); - if (builder is IDeferredMeterProviderBuilder deferredMeterProviderBuilder) + name ??= Options.DefaultName; + + if (configure != null) { - return deferredMeterProviderBuilder.Configure((sp, builder) => - { - AddPrometheusHttpListener(builder, sp.GetOptions(), configure); - }); + builder.ConfigureServices(services => services.Configure(name, configure)); } - return AddPrometheusHttpListener(builder, new PrometheusHttpListenerOptions(), configure); + return builder.ConfigureBuilder((sp, builder) => + { + var options = sp.GetRequiredService>().Get(name); + + AddPrometheusHttpListener(builder, options); + }); } private static MeterProviderBuilder AddPrometheusHttpListener( MeterProviderBuilder builder, - PrometheusHttpListenerOptions options, - Action configure = null) + PrometheusHttpListenerOptions options) { - configure?.Invoke(options); - var exporter = new PrometheusExporter(); var reader = new BaseExportingMetricReader(exporter) diff --git a/src/OpenTelemetry/Internal/ServiceProviderExtensions.cs b/src/OpenTelemetry/Internal/ServiceProviderExtensions.cs deleted file mode 100644 index e594d5034a1..00000000000 --- a/src/OpenTelemetry/Internal/ServiceProviderExtensions.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// 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 NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER || NET6_0_OR_GREATER -using Microsoft.Extensions.Options; -#endif - -namespace System -{ - /// - /// Extension methods for OpenTelemetry dependency 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 NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER || NET6_0_OR_GREATER - 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/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTests.cs index b3eca6b5d0c..85bae563da6 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTests.cs @@ -162,8 +162,6 @@ public void MetricExportResultIsSuccess(OtlpExportProtocol protocol, string endp builder, exporterOptions, readerOptions, - configureExporter: null, - configureExporterAndMetricReader: null, serviceProvider: null, configureExporterInstance: otlpExporter => { diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs index 8553b419dfa..e501446e595 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpMetricsExporterTests.cs @@ -79,6 +79,33 @@ void CheckMetricReaderDefaults() } } + [Fact] + public void TestAddOtlpExporter_NamedOptions() + { + int defaultExporterOptionsConfigureOptionsInvocations = 0; + int namedExporterOptionsConfigureOptionsInvocations = 0; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureServices(services => + { + services.Configure(o => defaultExporterOptionsConfigureOptionsInvocations++); + services.Configure(o => defaultExporterOptionsConfigureOptionsInvocations++); + + services.Configure("Exporter2", o => namedExporterOptionsConfigureOptionsInvocations++); + services.Configure("Exporter2", o => namedExporterOptionsConfigureOptionsInvocations++); + + services.Configure("Exporter3", o => namedExporterOptionsConfigureOptionsInvocations++); + services.Configure("Exporter3", o => namedExporterOptionsConfigureOptionsInvocations++); + }) + .AddOtlpExporter() + .AddOtlpExporter("Exporter2", o => { }) + .AddOtlpExporter("Exporter3", (eo, ro) => { }) + .Build(); + + Assert.Equal(2, defaultExporterOptionsConfigureOptionsInvocations); + Assert.Equal(4, namedExporterOptionsConfigureOptionsInvocations); + } + [Fact] public void UserHttpFactoryCalled() { diff --git a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMeterProviderBuilderExtensionsTests.cs b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMeterProviderBuilderExtensionsTests.cs new file mode 100644 index 00000000000..f4212ad5d5b --- /dev/null +++ b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMeterProviderBuilderExtensionsTests.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 Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Metrics; +using Xunit; + +namespace OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests; + +public sealed class PrometheusExporterMeterProviderBuilderExtensionsTests +{ + [Fact] + public void TestAddPrometheusExporter_NamedOptions() + { + int defaultExporterOptionsConfigureOptionsInvocations = 0; + int namedExporterOptionsConfigureOptionsInvocations = 0; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureServices(services => + { + services.Configure(o => defaultExporterOptionsConfigureOptionsInvocations++); + + services.Configure("Exporter2", o => namedExporterOptionsConfigureOptionsInvocations++); + }) + .AddPrometheusExporter() + .AddPrometheusExporter("Exporter2", o => { }) + .Build(); + + Assert.Equal(1, defaultExporterOptionsConfigureOptionsInvocations); + Assert.Equal(1, namedExporterOptionsConfigureOptionsInvocations); + } +} diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerMeterProviderBuilderExtensionsTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerMeterProviderBuilderExtensionsTests.cs new file mode 100644 index 00000000000..eb7832b4856 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerMeterProviderBuilderExtensionsTests.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 Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Metrics; +using Xunit; + +namespace OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests; + +public sealed class PrometheusHttpListenerMeterProviderBuilderExtensionsTests +{ + [Fact] + public void TestAddPrometheusHttpListener_NamedOptions() + { + int defaultExporterOptionsConfigureOptionsInvocations = 0; + int namedExporterOptionsConfigureOptionsInvocations = 0; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureServices(services => + { + services.Configure(o => defaultExporterOptionsConfigureOptionsInvocations++); + + services.Configure("Exporter2", o => namedExporterOptionsConfigureOptionsInvocations++); + }) + .AddPrometheusHttpListener() + .AddPrometheusHttpListener("Exporter2", o => { }) + .Build(); + + Assert.Equal(1, defaultExporterOptionsConfigureOptionsInvocations); + Assert.Equal(1, namedExporterOptionsConfigureOptionsInvocations); + } +} diff --git a/test/OpenTelemetry.Tests/Metrics/MultipleReadersTests.cs b/test/OpenTelemetry.Tests/Metrics/MultipleReadersTests.cs index 142ed9371f9..f6604a44902 100644 --- a/test/OpenTelemetry.Tests/Metrics/MultipleReadersTests.cs +++ b/test/OpenTelemetry.Tests/Metrics/MultipleReadersTests.cs @@ -16,6 +16,7 @@ using System.Collections.Generic; using System.Diagnostics.Metrics; +using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Tests; using Xunit; @@ -47,13 +48,27 @@ public void SdkSupportsMultipleReaders(MetricReaderTemporalityPreference aggrega long GetSum() => valuesSum[indexSum++]; var observableCounter = meter.CreateObservableCounter("obs-counter", () => GetSum()); + bool defaultNamedOptionsConfigureCalled = false; + bool namedOptionsConfigureCalled = false; + var meterProviderBuilder = Sdk.CreateMeterProviderBuilder() + .ConfigureServices(services => + { + services.Configure(o => + { + defaultNamedOptionsConfigureCalled = true; + }); + services.Configure("Exporter2", o => + { + namedOptionsConfigureCalled = true; + }); + }) .AddMeter(meter.Name) .AddInMemoryExporter(exportedItems1, metricReaderOptions => { metricReaderOptions.TemporalityPreference = MetricReaderTemporalityPreference.Delta; }) - .AddInMemoryExporter(exportedItems2, metricReaderOptions => + .AddInMemoryExporter("Exporter2", exportedItems2, metricReaderOptions => { metricReaderOptions.TemporalityPreference = aggregationTemporality; }); @@ -67,6 +82,9 @@ public void SdkSupportsMultipleReaders(MetricReaderTemporalityPreference aggrega using var meterProvider = meterProviderBuilder.Build(); + Assert.True(defaultNamedOptionsConfigureCalled); + Assert.True(namedOptionsConfigureCalled); + counter.Add(10, new KeyValuePair("key", "value")); meterProvider.ForceFlush(); From de98eb77258a35b900c20940fd23ac4f591bc766 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 13 Sep 2022 10:19:15 -0700 Subject: [PATCH 06/34] [Logs] Add named options support to OtlpLogExporter builder extensions. (#3652) * Add named options support to otlp log provider builder extensions. * CHANGELOG update. --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 4 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 4 +- .../netstandard2.1/PublicAPI.Unshipped.txt | 4 +- .../CHANGELOG.md | 4 ++ .../OtlpLogExporterHelperExtensions.cs | 38 ++++++++++++++++--- .../OtlpLogExporterTests.cs | 26 +++++++++++++ 6 files changed, 71 insertions(+), 9 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/.publicApi/net462/PublicAPI.Unshipped.txt index 78927f7a9cc..408e03e7470 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,2 +1,4 @@ OpenTelemetry.Logs.OtlpLogExporterHelperExtensions -static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Action configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, string name, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 78927f7a9cc..408e03e7470 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,2 +1,4 @@ OpenTelemetry.Logs.OtlpLogExporterHelperExtensions -static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Action configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, string name, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index 78927f7a9cc..408e03e7470 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -1,2 +1,4 @@ OpenTelemetry.Logs.OtlpLogExporterHelperExtensions -static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Action configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, string name, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.OtlpLogExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/CHANGELOG.md index dc3bdd72318..b84dd91f35b 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/CHANGELOG.md @@ -7,6 +7,10 @@ `HttpProtobuf` is configured ([#3640](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3640)) +* Added overloads which accept a name to the `OpenTelemetryLoggerOptions` + `AddOtlpExporter` extension to allow for more fine-grained options management + ([#3652](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3652)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/OtlpLogExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/OtlpLogExporterHelperExtensions.cs index 0a5d2fee43f..4339e1e088e 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/OtlpLogExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/OtlpLogExporterHelperExtensions.cs @@ -27,32 +27,58 @@ namespace OpenTelemetry.Logs /// public static class OtlpLogExporterHelperExtensions { + /// + /// Adds OTLP Exporter as a configuration to the OpenTelemetry ILoggingBuilder. + /// + /// + /// options to use. + /// The instance of to chain the calls. + public static OpenTelemetryLoggerOptions AddOtlpExporter(this OpenTelemetryLoggerOptions loggerOptions) + => AddOtlpExporter(loggerOptions, name: null, configure: null); + + /// + /// Adds OTLP Exporter as a configuration to the OpenTelemetry ILoggingBuilder. + /// + /// + /// options to use. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static OpenTelemetryLoggerOptions AddOtlpExporter( + this OpenTelemetryLoggerOptions loggerOptions, + Action configure) + => AddOtlpExporter(loggerOptions, name: null, configure); + /// /// Adds OTLP Exporter as a configuration to the OpenTelemetry ILoggingBuilder. /// /// - /// Note: automatically sets to . /// /// options to use. - /// Exporter configuration options. + /// Name which is used when retrieving options. + /// Callback action for configuring . /// The instance of to chain the calls. - public static OpenTelemetryLoggerOptions AddOtlpExporter(this OpenTelemetryLoggerOptions loggerOptions, Action configure = null) + public static OpenTelemetryLoggerOptions AddOtlpExporter( + this OpenTelemetryLoggerOptions loggerOptions, + string name, + Action configure) { Guard.ThrowIfNull(loggerOptions); loggerOptions.ParseStateValues = true; + name ??= Options.DefaultName; + if (configure != null) { - loggerOptions.ConfigureServices(services => services.Configure(configure)); + loggerOptions.ConfigureServices(services => services.Configure(name, configure)); } return loggerOptions.ConfigureProvider((sp, provider) => { - var options = sp.GetRequiredService>().Value; + var options = sp.GetRequiredService>().Get(name); AddOtlpExporter(provider, options, sp); }); diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs index 8feab03e185..cfe27e80bed 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpLogExporterTests.cs @@ -113,6 +113,32 @@ public void AddOtlpLogExporterParseStateValueCanBeTurnedOffHosting() Assert.Null(logRecord.StateValues); } + [Fact] + public void AddOtlpLogExporterNamedOptionsSupported() + { + int defaultExporterOptionsConfigureOptionsInvocations = 0; + int namedExporterOptionsConfigureOptionsInvocations = 0; + + using var loggerFactory = LoggerFactory.Create(builder => + { + builder.AddOpenTelemetry(options => + { + options + .ConfigureServices(services => + { + services.Configure(o => defaultExporterOptionsConfigureOptionsInvocations++); + + services.Configure("Exporter2", o => namedExporterOptionsConfigureOptionsInvocations++); + }) + .AddOtlpExporter() + .AddOtlpExporter("Exporter2", o => { }); + }); + }); + + Assert.Equal(1, defaultExporterOptionsConfigureOptionsInvocations); + Assert.Equal(1, namedExporterOptionsConfigureOptionsInvocations); + } + [Fact] public void OtlpLogRecordTestWhenStateValuesArePopulated() { From 6ea078ea2dc97d36c52951e64bf1b2daf3a778d4 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Tue, 13 Sep 2022 11:25:24 -0700 Subject: [PATCH 07/34] Support Prometheus UNIT metadata (#3651) * support Prometheus UNIT metadata * changelog --- .../CHANGELOG.md | 6 +-- .../CHANGELOG.md | 5 +-- .../Internal/PrometheusSerializer.cs | 43 ++++++++++++++++++- .../Internal/PrometheusSerializerExt.cs | 9 ++-- .../PrometheusSerializerTests.cs | 30 ++++++++++++- 5 files changed, 77 insertions(+), 16 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md index 151ee398408..f2fd26ccd5a 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md @@ -5,11 +5,12 @@ * Bug fix for Prometheus Exporter reporting StatusCode 204 instead of 200, when no metrics are collected ([#3643](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3643)) - * Added overloads which accept a name to the `MeterProviderBuilder` `AddPrometheusExporter` extension to allow for more fine-grained options management ([#3648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3648)) +* Added support for OpenMetrics UNIT metadata + ([#3651](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3651)) ## 1.4.0-alpha.2 @@ -21,7 +22,6 @@ Released 2022-Aug-18 ([#3430](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3430) [#3503](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3503) [#3507](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3507)) - * Added `IEndpointRouteBuilder` extension methods to help with Prometheus middleware configuration on ASP.NET Core ([#3295](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3295)) @@ -41,10 +41,8 @@ Released 2022-Apr-15 * Added `IApplicationBuilder` extension methods to help with Prometheus middleware configuration on ASP.NET Core ([#3029](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3029)) - * Changed Prometheus exporter to return 204 No Content and log a warning event if there are no metrics to collect. - * Removes .NET Framework 4.6.1. The minimum .NET Framework version supported is .NET 4.6.2. ([#3190](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3190)) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md index f46954288a1..9ab03e4de81 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md @@ -5,11 +5,12 @@ * Bug fix for Prometheus Exporter reporting StatusCode 204 instead of 200, when no metrics are collected ([#3643](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3643)) - * Added overloads which accept a name to the `MeterProviderBuilder` `AddPrometheusHttpListener` extension to allow for more fine-grained options management ([#3648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3648)) +* Added support for OpenMetrics UNIT metadata + ([#3651](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3651)) ## 1.4.0-alpha.2 @@ -41,10 +42,8 @@ Released 2022-Apr-15 * Added `IApplicationBuilder` extension methods to help with Prometheus middleware configuration on ASP.NET Core ([#3029](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3029)) - * Changed Prometheus exporter to return 204 No Content and log a warning event if there are no metrics to collect. - * Removes .NET Framework 4.6.1. The minimum .NET Framework version supported is .NET 4.6.2. ([#3190](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3190)) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs index 18a22caaec2..5c38be07a77 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs @@ -271,8 +271,13 @@ public static int WriteMetricName(byte[] buffer, int cursor, string metricName, } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteHelpText(byte[] buffer, int cursor, string metricName, string metricUnit = null, string metricDescription = null) + public static int WriteHelpMetadata(byte[] buffer, int cursor, string metricName, string metricUnit, string metricDescription) { + if (string.IsNullOrEmpty(metricDescription)) + { + return cursor; + } + cursor = WriteAsciiStringNoEscape(buffer, cursor, "# HELP "); cursor = WriteMetricName(buffer, cursor, metricName, metricUnit); @@ -288,7 +293,7 @@ public static int WriteHelpText(byte[] buffer, int cursor, string metricName, st } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteTypeInfo(byte[] buffer, int cursor, string metricName, string metricUnit, string metricType) + public static int WriteTypeMetadata(byte[] buffer, int cursor, string metricName, string metricUnit, string metricType) { Debug.Assert(!string.IsNullOrEmpty(metricType), $"{nameof(metricType)} should not be null or empty."); @@ -301,5 +306,39 @@ public static int WriteTypeInfo(byte[] buffer, int cursor, string metricName, st return cursor; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteUnitMetadata(byte[] buffer, int cursor, string metricName, string metricUnit) + { + if (string.IsNullOrEmpty(metricUnit)) + { + return cursor; + } + + cursor = WriteAsciiStringNoEscape(buffer, cursor, "# UNIT "); + cursor = WriteMetricName(buffer, cursor, metricName, metricUnit); + + buffer[cursor++] = unchecked((byte)' '); + + for (int i = 0; i < metricUnit.Length; i++) + { + var ordinal = (ushort)metricUnit[i]; + + if ((ordinal >= (ushort)'A' && ordinal <= (ushort)'Z') || + (ordinal >= (ushort)'a' && ordinal <= (ushort)'z') || + (ordinal >= (ushort)'0' && ordinal <= (ushort)'9')) + { + buffer[cursor++] = unchecked((byte)ordinal); + } + else + { + buffer[cursor++] = unchecked((byte)'_'); + } + } + + buffer[cursor++] = ASCII_LINEFEED; + + return cursor; + } } } diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializerExt.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializerExt.cs index 8ae48797dfa..445e0410c81 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializerExt.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializerExt.cs @@ -36,13 +36,10 @@ UpDownCounter becomes gauge public static int WriteMetric(byte[] buffer, int cursor, Metric metric) { - if (!string.IsNullOrWhiteSpace(metric.Description)) - { - cursor = WriteHelpText(buffer, cursor, metric.Name, metric.Unit, metric.Description); - } - int metricType = (int)metric.MetricType >> 4; - cursor = WriteTypeInfo(buffer, cursor, metric.Name, metric.Unit, MetricTypes[metricType]); + cursor = WriteTypeMetadata(buffer, cursor, metric.Name, metric.Unit, MetricTypes[metricType]); + cursor = WriteUnitMetadata(buffer, cursor, metric.Name, metric.Unit); + cursor = WriteHelpMetadata(buffer, cursor, metric.Name, metric.Unit, metric.Description); if (!metric.MetricType.IsHistogram()) { diff --git a/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusSerializerTests.cs b/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusSerializerTests.cs index ba57d0bb511..24472e0e645 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusSerializerTests.cs @@ -69,8 +69,8 @@ public void GaugeZeroDimensionWithDescription() var cursor = PrometheusSerializer.WriteMetric(buffer, 0, metrics[0]); Assert.Matches( ("^" - + "# HELP test_gauge Hello, world!\n" + "# TYPE test_gauge gauge\n" + + "# HELP test_gauge Hello, world!\n" + "test_gauge 123 \\d+\n" + "$").Replace('\'', '"'), Encoding.UTF8.GetString(buffer, 0, cursor)); @@ -96,6 +96,34 @@ public void GaugeZeroDimensionWithUnit() Assert.Matches( ("^" + "# TYPE test_gauge_seconds gauge\n" + + "# UNIT test_gauge_seconds seconds\n" + + "test_gauge_seconds 123 \\d+\n" + + "$").Replace('\'', '"'), + Encoding.UTF8.GetString(buffer, 0, cursor)); + } + + [Fact] + public void GaugeZeroDimensionWithDescriptionAndUnit() + { + var buffer = new byte[85000]; + var metrics = new List(); + + using var meter = new Meter(Utils.GetCurrentMethodName()); + using var provider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddInMemoryExporter(metrics) + .Build(); + + meter.CreateObservableGauge("test_gauge", () => 123, unit: "seconds", description: "Hello, world!"); + + provider.ForceFlush(); + + var cursor = PrometheusSerializer.WriteMetric(buffer, 0, metrics[0]); + Assert.Matches( + ("^" + + "# TYPE test_gauge_seconds gauge\n" + + "# UNIT test_gauge_seconds seconds\n" + + "# HELP test_gauge_seconds Hello, world!\n" + "test_gauge_seconds 123 \\d+\n" + "$").Replace('\'', '"'), Encoding.UTF8.GetString(buffer, 0, cursor)); From b4ade26eae8cfb45b44bccabade52adaf0b7c146 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 13 Sep 2022 13:22:05 -0700 Subject: [PATCH 08/34] [Traces] Add named options support to OtlpTraceExporter builder extensions (#3653) * Add named options support to otlp trace provider builder extensions. * CHANGELOG update. --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 6 +++- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 6 +++- .../netstandard2.0/PublicAPI.Unshipped.txt | 6 +++- .../netstandard2.1/PublicAPI.Unshipped.txt | 6 +++- .../CHANGELOG.md | 4 +++ .../OtlpTraceExporterHelperExtensions.cs | 31 ++++++++++++++++--- .../OtlpTraceExporterTests.cs | 21 +++++++++++++ 7 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net462/PublicAPI.Unshipped.txt index 6ee083d2bf9..d54151c394a 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,2 +1,6 @@ static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder \ No newline at end of file +static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder +*REMOVED*static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt index 6ee083d2bf9..d54151c394a 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,2 +1,6 @@ static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder \ No newline at end of file +static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder +*REMOVED*static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 6ee083d2bf9..d54151c394a 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,2 +1,6 @@ static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder \ No newline at end of file +static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder +*REMOVED*static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index 6ee083d2bf9..d54151c394a 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -1,2 +1,6 @@ static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder \ No newline at end of file +static OpenTelemetry.Metrics.OtlpMetricExporterExtensions.AddOtlpExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder +*REMOVED*static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index 9af0873f3c1..6b96dfa8588 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -6,6 +6,10 @@ `AddOtlpExporter` extension to allow for more fine-grained options management ([#3648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3648)) +* Added overloads which accept a name to the `TracerProviderBuilder` + `AddOtlpExporter` extension to allow for more fine-grained options management + ([#3653](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3653)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs index 829e09525cb..2667a25554f 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs @@ -32,20 +32,43 @@ public static class OtlpTraceExporterHelperExtensions /// Adds OpenTelemetry Protocol (OTLP) exporter to the TracerProvider. /// /// builder to use. - /// Exporter configuration options. /// The instance of to chain the calls. - public static TracerProviderBuilder AddOtlpExporter(this TracerProviderBuilder builder, Action configure = null) + public static TracerProviderBuilder AddOtlpExporter(this TracerProviderBuilder builder) + => AddOtlpExporter(builder, name: null, configure: null); + + /// + /// Adds OpenTelemetry Protocol (OTLP) exporter to the TracerProvider. + /// + /// builder to use. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddOtlpExporter(this TracerProviderBuilder builder, Action configure) + => AddOtlpExporter(builder, name: null, configure); + + /// + /// Adds OpenTelemetry Protocol (OTLP) exporter to the TracerProvider. + /// + /// builder to use. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddOtlpExporter( + this TracerProviderBuilder builder, + string name, + Action configure) { Guard.ThrowIfNull(builder); + name ??= Options.DefaultName; + if (configure != null) { - builder.ConfigureServices(services => services.Configure(configure)); + builder.ConfigureServices(services => services.Configure(name, configure)); } return builder.ConfigureBuilder((sp, builder) => { - var options = sp.GetRequiredService>().Value; + var options = sp.GetRequiredService>().Get(name); AddOtlpExporter(builder, options, sp); }); diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs index 6e7bc8ef8ab..835d464dc44 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTraceExporterTests.cs @@ -52,6 +52,27 @@ static OtlpTraceExporterTests() ActivitySource.AddActivityListener(listener); } + [Fact] + public void AddOtlpTraceExporterNamedOptionsSupported() + { + int defaultExporterOptionsConfigureOptionsInvocations = 0; + int namedExporterOptionsConfigureOptionsInvocations = 0; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => + { + services.Configure(o => defaultExporterOptionsConfigureOptionsInvocations++); + + services.Configure("Exporter2", o => namedExporterOptionsConfigureOptionsInvocations++); + }) + .AddOtlpExporter() + .AddOtlpExporter("Exporter2", o => { }) + .Build(); + + Assert.Equal(1, defaultExporterOptionsConfigureOptionsInvocations); + Assert.Equal(1, namedExporterOptionsConfigureOptionsInvocations); + } + [Fact] public void OtlpExporter_BadArgs() { From a87f8f7373b13dad994e5a9414aed356ec712f67 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 13 Sep 2022 14:22:04 -0700 Subject: [PATCH 09/34] [Traces] Add named options support to ZipkinExporter builder extensions (#3655) * Add named options support to zipkin provider builder extensions. * CHANGELOG update. --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 4 +++ .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 4 +++ .../netstandard2.0/PublicAPI.Unshipped.txt | 4 +++ .../CHANGELOG.md | 5 +++ .../ZipkinExporterHelperExtensions.cs | 31 ++++++++++++++++--- .../ZipkinExporterTests.cs | 21 +++++++++++++ 6 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Zipkin/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Zipkin/.publicApi/net462/PublicAPI.Unshipped.txt index e69de29bb2d..62aa18b630b 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Zipkin/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +*REMOVED*static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Zipkin/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Zipkin/.publicApi/net6.0/PublicAPI.Unshipped.txt index e69de29bb2d..62aa18b630b 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Zipkin/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +*REMOVED*static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Zipkin/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Zipkin/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2d..62aa18b630b 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Zipkin/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +*REMOVED*static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ZipkinExporterHelperExtensions.AddZipkinExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md index a25f7cd903c..cfed2ec4145 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Added overloads which accept a name to the `TracerProviderBuilder` + `AddZipkinExporter` extension to allow for more fine-grained options + management + ([#3655](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3655)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs index cccf2c432cd..484254c68e2 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs @@ -33,20 +33,43 @@ public static class ZipkinExporterHelperExtensions /// Adds Zipkin exporter to the TracerProvider. /// /// builder to use. - /// Exporter configuration options. /// The instance of to chain the calls. - public static TracerProviderBuilder AddZipkinExporter(this TracerProviderBuilder builder, Action configure = null) + public static TracerProviderBuilder AddZipkinExporter(this TracerProviderBuilder builder) + => AddZipkinExporter(builder, name: null, configure: null); + + /// + /// Adds Zipkin exporter to the TracerProvider. + /// + /// builder to use. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddZipkinExporter(this TracerProviderBuilder builder, Action configure) + => AddZipkinExporter(builder, name: null, configure); + + /// + /// Adds Zipkin exporter to the TracerProvider. + /// + /// builder to use. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddZipkinExporter( + this TracerProviderBuilder builder, + string name, + Action configure) { Guard.ThrowIfNull(builder); + name ??= Options.DefaultName; + if (configure != null) { - builder.ConfigureServices(services => services.Configure(configure)); + builder.ConfigureServices(services => services.Configure(name, configure)); } return builder.ConfigureBuilder((sp, builder) => { - var options = sp.GetRequiredService>().Value; + var options = sp.GetRequiredService>().Get(name); AddZipkinExporter(builder, options, sp); }); diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs b/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs index 37b715501a6..4cd2d97d2e5 100644 --- a/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs @@ -84,6 +84,27 @@ public void Dispose() GC.SuppressFinalize(this); } + [Fact] + public void AddAddZipkinExporterNamedOptionsSupported() + { + int defaultExporterOptionsConfigureOptionsInvocations = 0; + int namedExporterOptionsConfigureOptionsInvocations = 0; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => + { + services.Configure(o => defaultExporterOptionsConfigureOptionsInvocations++); + + services.Configure("Exporter2", o => namedExporterOptionsConfigureOptionsInvocations++); + }) + .AddZipkinExporter() + .AddZipkinExporter("Exporter2", o => { }) + .Build(); + + Assert.Equal(1, defaultExporterOptionsConfigureOptionsInvocations); + Assert.Equal(1, namedExporterOptionsConfigureOptionsInvocations); + } + [Fact] public void BadArgs() { From cb2eeb5621face21a4706bf440dd2484f66213ad Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 13 Sep 2022 14:51:58 -0700 Subject: [PATCH 10/34] [Traces] Add named options support to JaegerExporter builder extensions (#3656) * Add named options support to jaeger provider builder extensions. * CHANGELOG update. * Code review. --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 4 +++ .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 4 +++ .../netstandard2.0/PublicAPI.Unshipped.txt | 4 +++ .../netstandard2.1/PublicAPI.Unshipped.txt | 4 +++ .../CHANGELOG.md | 5 +++ .../JaegerExporterHelperExtensions.cs | 31 ++++++++++++++++--- .../JaegerExporterTests.cs | 21 +++++++++++++ 7 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Jaeger/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Jaeger/.publicApi/net462/PublicAPI.Unshipped.txt index e69de29bb2d..a387a9ca5e5 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Jaeger/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +*REMOVED*static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Jaeger/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Jaeger/.publicApi/net6.0/PublicAPI.Unshipped.txt index e69de29bb2d..a387a9ca5e5 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Jaeger/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +*REMOVED*static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Jaeger/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Jaeger/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2d..a387a9ca5e5 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Jaeger/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +*REMOVED*static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Jaeger/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Jaeger/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index e69de29bb2d..a387a9ca5e5 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Jaeger/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +*REMOVED*static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.JaegerExporterHelperExtensions.AddJaegerExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md b/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md index 659e0791b24..b040029c49a 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Added overloads which accept a name to the `TracerProviderBuilder` + `AddJaegerExporter` extension to allow for more fine-grained options + management + ([#3656](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3656)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs index dec28c8c236..db1b770d31d 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs @@ -33,20 +33,43 @@ public static class JaegerExporterHelperExtensions /// Adds Jaeger exporter to the TracerProvider. /// /// builder to use. - /// Exporter configuration options. /// The instance of to chain the calls. - public static TracerProviderBuilder AddJaegerExporter(this TracerProviderBuilder builder, Action configure = null) + public static TracerProviderBuilder AddJaegerExporter(this TracerProviderBuilder builder) + => AddJaegerExporter(builder, name: null, configure: null); + + /// + /// Adds Jaeger exporter to the TracerProvider. + /// + /// builder to use. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddJaegerExporter(this TracerProviderBuilder builder, Action configure) + => AddJaegerExporter(builder, name: null, configure); + + /// + /// Adds Jaeger exporter to the TracerProvider. + /// + /// builder to use. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddJaegerExporter( + this TracerProviderBuilder builder, + string name, + Action configure) { Guard.ThrowIfNull(builder); + name ??= Options.DefaultName; + if (configure != null) { - builder.ConfigureServices(services => services.Configure(configure)); + builder.ConfigureServices(services => services.Configure(name, configure)); } return builder.ConfigureBuilder((sp, builder) => { - var options = sp.GetRequiredService>().Value; + var options = sp.GetRequiredService>().Get(name); AddJaegerExporter(builder, options, sp); }); diff --git a/test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterTests.cs b/test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterTests.cs index 5d018bcf8c1..28baef09e66 100644 --- a/test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterTests.cs @@ -33,6 +33,27 @@ namespace OpenTelemetry.Exporter.Jaeger.Tests { public class JaegerExporterTests { + [Fact] + public void AddJaegerExporterNamedOptionsSupported() + { + int defaultExporterOptionsConfigureOptionsInvocations = 0; + int namedExporterOptionsConfigureOptionsInvocations = 0; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => + { + services.Configure(o => defaultExporterOptionsConfigureOptionsInvocations++); + + services.Configure("Exporter2", o => namedExporterOptionsConfigureOptionsInvocations++); + }) + .AddJaegerExporter() + .AddJaegerExporter("Exporter2", o => { }) + .Build(); + + Assert.Equal(1, defaultExporterOptionsConfigureOptionsInvocations); + Assert.Equal(1, namedExporterOptionsConfigureOptionsInvocations); + } + [Fact] public void JaegerExporter_BadArgs() { From 11c804ac6825b9fe39ae1ae73af27434e1a891e1 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 13 Sep 2022 15:19:22 -0700 Subject: [PATCH 11/34] [Logs + Traces] Add named options support to ConsoleExporter builder extensions (#3657) * Add named options support to console exporter tracer & logger provider builder extensions. * CHANGELOG update. --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 8 +++++ .../netstandard2.0/PublicAPI.Unshipped.txt | 8 +++++ .../CHANGELOG.md | 10 ++++++ .../ConsoleExporterHelperExtensions.cs | 31 ++++++++++++++++--- .../ConsoleExporterLoggingExtensions.cs | 31 ++++++++++++++++--- 5 files changed, 80 insertions(+), 8 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Console/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Console/.publicApi/net462/PublicAPI.Unshipped.txt index 0f6bd0c9e9a..427104a7a52 100644 --- a/src/OpenTelemetry.Exporter.Console/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Console/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,3 +1,11 @@ override OpenTelemetry.Exporter.ConsoleLogRecordExporter.Dispose(bool disposing) -> void +*REMOVED*static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Action configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, string name, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder +*REMOVED*static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Console/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Console/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 0f6bd0c9e9a..427104a7a52 100644 --- a/src/OpenTelemetry.Exporter.Console/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Console/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,3 +1,11 @@ override OpenTelemetry.Exporter.ConsoleLogRecordExporter.Dispose(bool disposing) -> void +*REMOVED*static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Action configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, string name, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Logs.ConsoleExporterLoggingExtensions.AddConsoleExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions loggerOptions, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporterAndMetricReader) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.ConsoleExporterMetricsExtensions.AddConsoleExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Metrics.MeterProviderBuilder +*REMOVED*static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md index 1b584dd454a..535977e3b31 100644 --- a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md @@ -11,6 +11,16 @@ management ([#3648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3648)) +* Added overloads which accept a name to the `OpenTelemetryLoggerOptions` + `AddConsoleExporter` extension to allow for more fine-grained options + management + ([#3657](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3657)) + +* Added overloads which accept a name to the `TracerProviderBuilder` + `AddConsoleExporter` extension to allow for more fine-grained options + management + ([#3657](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3657)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs index 2f5ed77ab4d..2bb84b49c8b 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs @@ -28,20 +28,43 @@ public static class ConsoleExporterHelperExtensions /// Adds Console exporter to the TracerProvider. /// /// builder to use. - /// Exporter configuration options. /// The instance of to chain the calls. - public static TracerProviderBuilder AddConsoleExporter(this TracerProviderBuilder builder, Action configure = null) + public static TracerProviderBuilder AddConsoleExporter(this TracerProviderBuilder builder) + => AddConsoleExporter(builder, name: null, configure: null); + + /// + /// Adds Console exporter to the TracerProvider. + /// + /// builder to use. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddConsoleExporter(this TracerProviderBuilder builder, Action configure) + => AddConsoleExporter(builder, name: null, configure); + + /// + /// Adds Console exporter to the TracerProvider. + /// + /// builder to use. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddConsoleExporter( + this TracerProviderBuilder builder, + string name, + Action configure) { Guard.ThrowIfNull(builder); + name ??= Options.DefaultName; + if (configure != null) { - builder.ConfigureServices(services => services.Configure(configure)); + builder.ConfigureServices(services => services.Configure(name, configure)); } return builder.ConfigureBuilder((sp, builder) => { - var options = sp.GetRequiredService>().Value; + var options = sp.GetRequiredService>().Get(name); builder.AddProcessor(new SimpleActivityExportProcessor(new ConsoleActivityExporter(options))); }); diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs index 5e5de098833..7e85c968cb5 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs @@ -28,20 +28,43 @@ public static class ConsoleExporterLoggingExtensions /// Adds Console exporter with OpenTelemetryLoggerOptions. /// /// options to use. - /// Exporter configuration options. /// The instance of to chain the calls. - public static OpenTelemetryLoggerOptions AddConsoleExporter(this OpenTelemetryLoggerOptions loggerOptions, Action configure = null) + public static OpenTelemetryLoggerOptions AddConsoleExporter(this OpenTelemetryLoggerOptions loggerOptions) + => AddConsoleExporter(loggerOptions, name: null, configure: null); + + /// + /// Adds Console exporter with OpenTelemetryLoggerOptions. + /// + /// options to use. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static OpenTelemetryLoggerOptions AddConsoleExporter(this OpenTelemetryLoggerOptions loggerOptions, Action configure) + => AddConsoleExporter(loggerOptions, name: null, configure); + + /// + /// Adds Console exporter with OpenTelemetryLoggerOptions. + /// + /// options to use. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static OpenTelemetryLoggerOptions AddConsoleExporter( + this OpenTelemetryLoggerOptions loggerOptions, + string name, + Action configure) { Guard.ThrowIfNull(loggerOptions); + name ??= Options.DefaultName; + if (configure != null) { - loggerOptions.ConfigureServices(services => services.Configure(configure)); + loggerOptions.ConfigureServices(services => services.Configure(name, configure)); } return loggerOptions.ConfigureProvider((sp, provider) => { - var options = sp.GetRequiredService>().Value; + var options = sp.GetRequiredService>().Get(name); provider.AddProcessor(new SimpleLogRecordExportProcessor(new ConsoleLogRecordExporter(options))); }); From bc82fdc7322babcb4b664f3aa101b085ffb63196 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 13 Sep 2022 16:00:04 -0700 Subject: [PATCH 12/34] XML comment cleanup for in-memory exporter extensions. (#3658) --- .../InMemoryExporterHelperExtensions.cs | 2 +- .../InMemoryExporterLoggingExtensions.cs | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterHelperExtensions.cs index ff183fa8dcf..199ca33db42 100644 --- a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterHelperExtensions.cs @@ -27,7 +27,7 @@ public static class InMemoryExporterHelperExtensions /// Adds InMemory exporter to the TracerProvider. /// /// builder to use. - /// Collection which will be populated with the exported Activity. + /// Collection which will be populated with the exported . /// The instance of to chain the calls. public static TracerProviderBuilder AddInMemoryExporter(this TracerProviderBuilder builder, ICollection exportedItems) { diff --git a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterLoggingExtensions.cs b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterLoggingExtensions.cs index 6e10e5bd668..c0cea4de63d 100644 --- a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterLoggingExtensions.cs @@ -22,6 +22,12 @@ namespace OpenTelemetry.Logs { public static class InMemoryExporterLoggingExtensions { + /// + /// Adds InMemory exporter to the OpenTelemetryLoggerOptions. + /// + /// options to use. + /// Collection which will be populated with the exported . + /// The instance of to chain the calls. public static OpenTelemetryLoggerOptions AddInMemoryExporter(this OpenTelemetryLoggerOptions loggerOptions, ICollection exportedItems) { Guard.ThrowIfNull(loggerOptions); From d99307da34eb48c2b7df8d79a7109895772281e3 Mon Sep 17 00:00:00 2001 From: blouflashdb <45914736+blouflashdb@users.noreply.github.com> Date: Wed, 14 Sep 2022 02:19:36 +0200 Subject: [PATCH 13/34] Improve internal logging of LoggerProvider configuration (#3647) --- .../Internal/OpenTelemetrySdkEventSource.cs | 12 +++++++++ .../Logs/OpenTelemetryLoggerProvider.cs | 27 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs b/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs index 1dcd65fd94b..27520b4d943 100644 --- a/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs +++ b/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs @@ -396,6 +396,18 @@ public void ProcessorForceFlushInvoked(string processorType, bool result) this.WriteEvent(43, processorType, result); } + [Event(44, Message = "OpenTelemetryLoggerProvider event: '{0}'", Level = EventLevel.Verbose)] + public void OpenTelemetryLoggerProviderEvent(string message) + { + this.WriteEvent(44, message); + } + + [Event(45, Message = "ForceFlush invoked for OpenTelemetryLoggerProvider with timeoutMilliseconds = '{0}'.", Level = EventLevel.Verbose)] + public void OpenTelemetryLoggerProviderForceFlushInvoked(int timeoutMilliseconds) + { + this.WriteEvent(45, timeoutMilliseconds); + } + #if DEBUG public class OpenTelemetryEventListener : EventListener { diff --git a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs index 0017f26a258..7b050b5aa3b 100644 --- a/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs +++ b/src/OpenTelemetry/Logs/OpenTelemetryLoggerProvider.cs @@ -19,6 +19,7 @@ using System; using System.Collections; using System.Diagnostics; +using System.Text; using System.Threading; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -72,6 +73,8 @@ public OpenTelemetryLoggerProvider() internal OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options, IServiceProvider? serviceProvider, bool ownsServiceProvider) { + OpenTelemetrySdkEventSource.Log.OpenTelemetryLoggerProviderEvent("Building OpenTelemetryLoggerProvider."); + Guard.ThrowIfNull(options); this.IncludeScopes = options.IncludeScopes; @@ -102,11 +105,14 @@ internal OpenTelemetryLoggerProvider(OpenTelemetryLoggerOptions options, IServic configurationActions[i](serviceProvider, this); } + OpenTelemetrySdkEventSource.Log.OpenTelemetryLoggerProviderEvent($"Number of actions configured = {configurationActions.Count}."); options.ConfigurationActions = null; } this.Resource = this.ResourceBuilder.Build(); this.ResourceBuilder = null; + + OpenTelemetrySdkEventSource.Log.OpenTelemetryLoggerProviderEvent("OpenTelemetryLoggerProvider built successfully."); } internal IExternalScopeProvider? ScopeProvider { get; private set; } @@ -173,6 +179,7 @@ public ILogger CreateLogger(string categoryName) /// public bool ForceFlush(int timeoutMilliseconds = Timeout.Infinite) { + OpenTelemetrySdkEventSource.Log.OpenTelemetryLoggerProviderForceFlushInvoked(timeoutMilliseconds); return this.Processor?.ForceFlush(timeoutMilliseconds) ?? true; } @@ -188,25 +195,43 @@ public bool ForceFlush(int timeoutMilliseconds = Timeout.Infinite) /// The supplied for chaining. public OpenTelemetryLoggerProvider AddProcessor(BaseProcessor processor) { + OpenTelemetrySdkEventSource.Log.OpenTelemetryLoggerProviderEvent("Started adding processor."); + Guard.ThrowIfNull(processor); processor.SetParentProvider(this); + StringBuilder processorAdded = new StringBuilder(); + if (this.threadStaticPool != null && this.ContainsBatchProcessor(processor)) { + OpenTelemetrySdkEventSource.Log.OpenTelemetryLoggerProviderEvent("Using shared thread pool."); + this.threadStaticPool = null; } if (this.Processor == null) { + processorAdded.Append("Setting processor to "); + processorAdded.Append(processor); + this.Processor = processor; } else if (this.Processor is CompositeProcessor compositeProcessor) { + processorAdded.Append("Adding processor "); + processorAdded.Append(processor); + processorAdded.Append(" to composite processor"); + compositeProcessor.AddProcessor(processor); } else { + processorAdded.Append("Creating new composite processor with processor "); + processorAdded.Append(this.Processor); + processorAdded.Append(" and adding new processor "); + processorAdded.Append(processor); + var newCompositeProcessor = new CompositeProcessor(new[] { this.Processor, @@ -216,6 +241,8 @@ public OpenTelemetryLoggerProvider AddProcessor(BaseProcessor process this.Processor = newCompositeProcessor; } + OpenTelemetrySdkEventSource.Log.OpenTelemetryLoggerProviderEvent($"Completed adding processor = \"{processorAdded}\"."); + return this; } From 3a8f139e8e7d9e32c1fcbe9cc2762907633dc23b Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 14 Sep 2022 09:35:49 -0700 Subject: [PATCH 14/34] Support named options in the tracer provider builder AddExporter API. (#3659) --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 2 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 2 + .../netstandard2.0/PublicAPI.Unshipped.txt | 2 + .../netstandard2.1/PublicAPI.Unshipped.txt | 2 + .../Builder/TracerProviderBuilderBase.cs | 25 ++++----- .../TracerProviderBuilderExtensions.cs | 52 +++++++++++++++++-- .../TracerProviderBuilderExtensionsTest.cs | 28 ++++++++++ 7 files changed, 95 insertions(+), 18 deletions(-) diff --git a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt index 5b0e8c6e33b..515a4fb8299 100644 --- a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt @@ -38,6 +38,8 @@ static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddExporter(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddExporter(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, OpenTelemetry.ExportProcessorType exportProcessorType, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! ~OpenTelemetry.Trace.SamplingResult.TraceStateString.get -> string ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, string traceStateString) -> void ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes, string traceStateString) -> void diff --git a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt index 5b0e8c6e33b..515a4fb8299 100644 --- a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -38,6 +38,8 @@ static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddExporter(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddExporter(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, OpenTelemetry.ExportProcessorType exportProcessorType, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! ~OpenTelemetry.Trace.SamplingResult.TraceStateString.get -> string ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, string traceStateString) -> void ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes, string traceStateString) -> void diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 54869f362f2..bdfe79411db 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -38,6 +38,8 @@ static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddExporter(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddExporter(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, OpenTelemetry.ExportProcessorType exportProcessorType, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! ~OpenTelemetry.Trace.SamplingResult.TraceStateString.get -> string ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, string traceStateString) -> void ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes, string traceStateString) -> void diff --git a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index 5b0e8c6e33b..515a4fb8299 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -38,6 +38,8 @@ static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureBuilder(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.ConfigureServices(this OpenTelemetry.Metrics.MeterProviderBuilder! meterProviderBuilder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddExporter(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddExporter(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, OpenTelemetry.ExportProcessorType exportProcessorType, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! ~OpenTelemetry.Trace.SamplingResult.TraceStateString.get -> string ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, string traceStateString) -> void ~OpenTelemetry.Trace.SamplingResult.SamplingResult(OpenTelemetry.Trace.SamplingDecision decision, System.Collections.Generic.IEnumerable> attributes, string traceStateString) -> void diff --git a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs index 0fd85d2a37d..aa842df7b28 100644 --- a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs +++ b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs @@ -115,27 +115,24 @@ TracerProviderBuilder IDeferredTracerProviderBuilder.Configure( return this; } - internal TracerProviderBuilder AddExporter(ExportProcessorType exportProcessorType, Action configure) + internal TracerProviderBuilder AddExporter(ExportProcessorType exportProcessorType, string? name, Action? configure) where T : BaseExporter { - Guard.ThrowIfNull(configure); - this.TryAddSingleton(); this.ConfigureState((sp, state) => state.AddProcessor( - BuildExportProcessor(state.ServiceProvider, exportProcessorType, sp.GetRequiredService(), configure))); + BuildExportProcessor(state.ServiceProvider, exportProcessorType, sp.GetRequiredService(), name, configure))); return this; } - internal TracerProviderBuilder AddExporter(ExportProcessorType exportProcessorType, BaseExporter exporter, Action configure) + internal TracerProviderBuilder AddExporter(ExportProcessorType exportProcessorType, BaseExporter exporter, string? name, Action? configure) { Guard.ThrowIfNull(exporter); - Guard.ThrowIfNull(configure); this.ConfigureState((sp, state) => state.AddProcessor( - BuildExportProcessor(state.ServiceProvider, exportProcessorType, exporter, configure))); + BuildExportProcessor(state.ServiceProvider, exportProcessorType, exporter, name, configure))); return this; } @@ -271,8 +268,11 @@ private static BaseProcessor BuildExportProcessor( IServiceProvider serviceProvider, ExportProcessorType exportProcessorType, BaseExporter exporter, - Action configure) + string? name, + Action? configure) { + name ??= Options.DefaultName; + switch (exportProcessorType) { case ExportProcessorType.Simple: @@ -281,10 +281,10 @@ private static BaseProcessor BuildExportProcessor( var options = new ExportActivityProcessorOptions { ExportProcessorType = ExportProcessorType.Batch, - BatchExportProcessorOptions = serviceProvider.GetRequiredService>().Value, + BatchExportProcessorOptions = serviceProvider.GetRequiredService>().Get(name), }; - configure(options); + configure?.Invoke(options); var batchOptions = options.BatchExportProcessorOptions; @@ -332,10 +332,7 @@ private void TryAddSingleton() { var services = this.services; - if (services != null) - { - services.TryAddSingleton(); - } + services?.TryAddSingleton(); } } } diff --git a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs index d431c521fc5..5811078f0cc 100644 --- a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs @@ -166,7 +166,7 @@ public static TracerProviderBuilder AddExporter( this TracerProviderBuilder tracerProviderBuilder, ExportProcessorType exportProcessorType, BaseExporter exporter) - => AddExporter(tracerProviderBuilder, exportProcessorType, exporter, o => { }); + => AddExporter(tracerProviderBuilder, exportProcessorType, exporter, name: null, configure: null); /// /// Adds an exporter to the provider. @@ -184,10 +184,30 @@ public static TracerProviderBuilder AddExporter( ExportProcessorType exportProcessorType, BaseExporter exporter, Action configure) + => AddExporter(tracerProviderBuilder, exportProcessorType, exporter, name: null, configure); + + /// + /// Adds an exporter to the provider. + /// + /// . + /// . + /// Activity exporter to add. + /// Name which is used when retrieving options. + /// Callback action to configure . Only invoked when is . + /// Returns for chaining. + public static TracerProviderBuilder AddExporter( + this TracerProviderBuilder tracerProviderBuilder, + ExportProcessorType exportProcessorType, + BaseExporter exporter, + string? name, + Action? configure) { if (tracerProviderBuilder is TracerProviderBuilderBase tracerProviderBuilderBase) { - tracerProviderBuilderBase.AddExporter(exportProcessorType, exporter, configure); + tracerProviderBuilderBase.AddExporter(exportProcessorType, exporter, name, configure); } return tracerProviderBuilder; @@ -208,7 +228,7 @@ public static TracerProviderBuilder AddExporter( this TracerProviderBuilder tracerProviderBuilder, ExportProcessorType exportProcessorType) where T : BaseExporter - => AddExporter(tracerProviderBuilder, exportProcessorType, o => { }); + => AddExporter(tracerProviderBuilder, exportProcessorType, name: null, configure: null); /// /// Adds an exporter to the provider which will be retrieved using dependency injection. @@ -230,10 +250,34 @@ public static TracerProviderBuilder AddExporter( ExportProcessorType exportProcessorType, Action configure) where T : BaseExporter + => AddExporter(tracerProviderBuilder, exportProcessorType, name: null, configure); + + /// + /// Adds an exporter to the provider which will be retrieved using dependency injection. + /// + /// + /// Note: The type specified by will be + /// registered as a singleton service into application services. + /// + /// Exporter type. + /// . + /// . + /// Name which is used when retrieving options. + /// Callback action to configure . Only invoked when is . + /// The supplied for chaining. + public static TracerProviderBuilder AddExporter( + this TracerProviderBuilder tracerProviderBuilder, + ExportProcessorType exportProcessorType, + string? name, + Action? configure) + where T : BaseExporter { if (tracerProviderBuilder is TracerProviderBuilderBase tracerProviderBuilderBase) { - tracerProviderBuilderBase.AddExporter(exportProcessorType, configure); + tracerProviderBuilderBase.AddExporter(exportProcessorType, name, configure); } return tracerProviderBuilder; diff --git a/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs b/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs index cbb6dd9afa2..5f3d5b95bb5 100644 --- a/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs +++ b/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs @@ -365,6 +365,34 @@ public void AddExporterWithOptionsTest() && batchProcessor.MaxExportBatchSize == 100); } + [Fact] + public void AddExporterNamedOptionsTest() + { + var builder = Sdk.CreateTracerProviderBuilder(); + + int defaultOptionsConfigureInvocations = 0; + int namedOptionsConfigureInvocations = 0; + + builder.ConfigureServices(services => + { + services.Configure(o => defaultOptionsConfigureInvocations++); + + services.Configure("Exporter2", o => namedOptionsConfigureInvocations++); + }); + + builder.AddExporter(ExportProcessorType.Batch, new MyExporter()); + builder.AddExporter(ExportProcessorType.Batch, new MyExporter(), name: "Exporter2", configure: null); + builder.AddExporter(ExportProcessorType.Batch); + builder.AddExporter(ExportProcessorType.Batch, name: "Exporter2", configure: null); + + using var provider = builder.Build() as TracerProviderSdk; + + Assert.NotNull(provider); + + Assert.Equal(1, defaultOptionsConfigureInvocations); + Assert.Equal(1, namedOptionsConfigureInvocations); + } + private static void RunBuilderServiceLifecycleTest( TracerProviderBuilder builder, Func buildFunc, From e68abc81363b2dd52f439b3aadd7dc7360274dad Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Wed, 14 Sep 2022 10:08:42 -0700 Subject: [PATCH 15/34] Output EOF following the OpenMetrics exposition recommendation (#3654) * Output EOF following the OpenMetrics exposition recommendation * update test case * changelog --- .../CHANGELOG.md | 3 ++ .../CHANGELOG.md | 3 ++ .../Internal/PrometheusCollectionManager.cs | 52 ++++++++++++++----- .../Internal/PrometheusSerializer.cs | 9 ++++ .../PrometheusExporterMiddlewareTests.cs | 24 ++++----- .../PrometheusHttpListenerTests.cs | 2 +- 6 files changed, 66 insertions(+), 27 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md index f2fd26ccd5a..23bb14d6e0a 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md @@ -11,6 +11,9 @@ instead of 200, when no metrics are collected ([#3648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3648)) * Added support for OpenMetrics UNIT metadata ([#3651](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3651)) +* Added `"# EOF\n"` ending following the [OpenMetrics + specification](https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md) + ([#3654](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3654)) ## 1.4.0-alpha.2 diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md index 9ab03e4de81..448bb0891a3 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md @@ -11,6 +11,9 @@ ([#3648](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3648)) * Added support for OpenMetrics UNIT metadata ([#3651](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3651)) +* Added `"# EOF\n"` ending following the [OpenMetrics + specification](https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md) + ([#3654](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3654)) ## 1.4.0-alpha.2 diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusCollectionManager.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusCollectionManager.cs index 265031eefcf..583c223491a 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusCollectionManager.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusCollectionManager.cs @@ -191,27 +191,37 @@ private ExportResult OnCollect(Batch metrics) } catch (IndexOutOfRangeException) { - var bufferSize = this.buffer.Length * 2; - - // there are two cases we might run into the following condition: - // 1. we have many metrics to be exported - in this case we probably want - // to put some upper limit and allow the user to configure it. - // 2. we got an IndexOutOfRangeException which was triggered by some other - // code instead of the buffer[cursor++] - in this case we should give up - // at certain point rather than allocating like crazy. - if (bufferSize > 100 * 1024 * 1024) + if (!this.IncreaseBufferSize()) { + // there are two cases we might run into the following condition: + // 1. we have many metrics to be exported - in this case we probably want + // to put some upper limit and allow the user to configure it. + // 2. we got an IndexOutOfRangeException which was triggered by some other + // code instead of the buffer[cursor++] - in this case we should give up + // at certain point rather than allocating like crazy. throw; } + } + } + } - var newBuffer = new byte[bufferSize]; - this.buffer.CopyTo(newBuffer, 0); - this.buffer = newBuffer; + while (true) + { + try + { + cursor = PrometheusSerializer.WriteEof(this.buffer, cursor); + break; + } + catch (IndexOutOfRangeException) + { + if (!this.IncreaseBufferSize()) + { + throw; } } } - this.previousDataView = new ArraySegment(this.buffer, 0, Math.Max(cursor - 1, 0)); + this.previousDataView = new ArraySegment(this.buffer, 0, cursor); return ExportResult.Success; } catch (Exception) @@ -221,6 +231,22 @@ private ExportResult OnCollect(Batch metrics) } } + private bool IncreaseBufferSize() + { + var newBufferSize = this.buffer.Length * 2; + + if (newBufferSize > 100 * 1024 * 1024) + { + return false; + } + + var newBuffer = new byte[newBufferSize]; + this.buffer.CopyTo(newBuffer, 0); + this.buffer = newBuffer; + + return true; + } + public readonly struct CollectionResponse { public CollectionResponse(ArraySegment view, DateTime generatedAtUtc, bool fromCache) diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs index 5c38be07a77..2e81582c083 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusSerializer.cs @@ -270,6 +270,15 @@ public static int WriteMetricName(byte[] buffer, int cursor, string metricName, return cursor; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteEof(byte[] buffer, int cursor) + { + cursor = WriteAsciiStringNoEscape(buffer, cursor, "# EOF"); + buffer[cursor++] = ASCII_LINEFEED; + + return cursor; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteHelpMetadata(byte[] buffer, int cursor, string metricName, string metricUnit, string metricDescription) { diff --git a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs index 07db88f7102..23cda76865b 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs @@ -21,6 +21,7 @@ using System.Linq; using System.Net; using System.Net.Http; +using System.Text.RegularExpressions; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; @@ -261,21 +262,18 @@ private static async Task RunPrometheusExporterMiddlewareIntegrationTest( string content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - string[] lines = content.Split('\n'); + var matches = Regex.Matches( + content, + ("^" + + "# TYPE counter_double counter\n" + + "counter_double{key1='value1',key2='value2'} 101.17 (\\d+)\n" + + "\n" + + "# EOF\n" + + "$").Replace('\'', '"')); - Assert.Equal( - $"# TYPE counter_double counter", - lines[0]); + Assert.Single(matches); - Assert.Contains( - $"counter_double{{key1=\"value1\",key2=\"value2\"}} 101.17", - lines[1]); - - var index = content.LastIndexOf(' '); - - Assert.Equal('\n', content[^1]); - - var timestamp = long.Parse(content.Substring(index, content.Length - index - 1)); + var timestamp = long.Parse(matches[0].Groups[1].Value); Assert.True(beginTimestamp <= timestamp && timestamp <= endTimestamp); } diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs index a35dcf89b26..b5710a1d1e3 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs @@ -135,7 +135,7 @@ private async Task RunPrometheusExporterHttpServerIntegrationTest(bool skipMetri Assert.Equal("text/plain; charset=utf-8; version=0.0.4", response.Content.Headers.ContentType.ToString()); Assert.Matches( - "^# TYPE counter_double counter\ncounter_double{key1='value1',key2='value2'} 101.17 \\d+\n$".Replace('\'', '"'), + "^# TYPE counter_double counter\ncounter_double{key1='value1',key2='value2'} 101.17 \\d+\n\n# EOF\n$".Replace('\'', '"'), await response.Content.ReadAsStringAsync().ConfigureAwait(false)); } else From faf5bb5dfba3528f5adb2c3c9ae5bf5d77e10fd5 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 14 Sep 2022 10:42:10 -0700 Subject: [PATCH 16/34] Update aspnetcore instrumentation benchmarks (#3642) --- test/Benchmarks/Helper/ValuesController.cs | 34 ++++++ .../AspNetCoreInstrumentationBenchmarks.cs | 112 ++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 test/Benchmarks/Helper/ValuesController.cs create mode 100644 test/Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs diff --git a/test/Benchmarks/Helper/ValuesController.cs b/test/Benchmarks/Helper/ValuesController.cs new file mode 100644 index 00000000000..41da05856f1 --- /dev/null +++ b/test/Benchmarks/Helper/ValuesController.cs @@ -0,0 +1,34 @@ +// +// 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 !NETFRAMEWORK +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; + +namespace Benchmark.Helper +{ + [Route("api/[controller]")] + public class ValuesController : Controller + { + // GET api/values + [HttpGet] + public IEnumerable Get() + { + return new string[] { "value1", "value2" }; + } + } +} +#endif diff --git a/test/Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs b/test/Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs new file mode 100644 index 00000000000..b6b31f7dbfd --- /dev/null +++ b/test/Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs @@ -0,0 +1,112 @@ +// +// 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 !NETFRAMEWORK +using System.Net.Http; +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using OpenTelemetry; +using OpenTelemetry.Trace; + +/* +// * Summary * + +BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000 +Intel Core i7-8850H CPU 2.60GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores +.NET SDK=7.0.100-preview.6.22275.1 + [Host] : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT + +Job=InProcess Toolchain=InProcessEmitToolchain + +| Method | Mean | Error | StdDev | Gen 0 | Allocated | +|-------------------------------------------- |---------:|--------:|--------:|-------:|----------:| +| UninstrumentedAspNetCoreApp | 155.6 us | 2.63 us | 2.33 us | 0.9766 | 5 KB | +| InstrumentedAspNetCoreAppWithDefaultOptions | 176.8 us | 3.24 us | 2.70 us | 1.2207 | 7 KB | +*/ + +namespace Benchmarks.Instrumentation +{ + [InProcess] + public class AspNetCoreInstrumentationBenchmarks + { + private HttpClient httpClient; + private WebApplication app; + private TracerProvider tracerProvider; + + [GlobalSetup(Target = nameof(UninstrumentedAspNetCoreApp))] + public void UninstrumentedAspNetCoreAppGlobalSetup() + { + this.StartWebApplication(); + this.httpClient = new HttpClient(); + } + + [GlobalSetup(Target = nameof(InstrumentedAspNetCoreAppWithDefaultOptions))] + public void InstrumentedAspNetCoreAppWithDefaultOptionsGlobalSetup() + { + this.StartWebApplication(); + this.httpClient = new HttpClient(); + + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation() + .Build(); + } + + [GlobalCleanup(Target = nameof(UninstrumentedAspNetCoreApp))] + public async Task GlobalCleanupUninstrumentedAspNetCoreAppAsync() + { + this.httpClient.Dispose(); + await this.app.DisposeAsync(); + } + + [GlobalCleanup(Target = nameof(InstrumentedAspNetCoreAppWithDefaultOptions))] + public async Task GlobalCleanupInstrumentedAspNetCoreAppWithDefaultOptionsAsync() + { + this.httpClient.Dispose(); + await this.app.DisposeAsync(); + this.tracerProvider.Dispose(); + } + + [Benchmark] + public async Task UninstrumentedAspNetCoreApp() + { + var httpResponse = await this.httpClient.GetAsync("http://localhost:5000/api/values"); + httpResponse.EnsureSuccessStatusCode(); + } + + [Benchmark] + public async Task InstrumentedAspNetCoreAppWithDefaultOptions() + { + var httpResponse = await this.httpClient.GetAsync("http://localhost:5000/api/values"); + httpResponse.EnsureSuccessStatusCode(); + } + + private void StartWebApplication() + { + var builder = WebApplication.CreateBuilder(); + builder.Services.AddControllers(); + builder.Logging.ClearProviders(); + var app = builder.Build(); + app.MapControllers(); + app.RunAsync(); + + this.app = app; + } + } +} +#endif From ef46e827a7ca44b48ed64080f72a7502bd9d6b1d Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 14 Sep 2022 11:02:13 -0700 Subject: [PATCH 17/34] Support named options in the logger provider builder AddExporter API. (#3660) --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 2 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 2 + .../netstandard2.0/PublicAPI.Unshipped.txt | 2 + .../netstandard2.1/PublicAPI.Unshipped.txt | 2 + .../Options/OpenTelemetryLoggerOptions.cs | 74 ++++++++++++------- .../Builder/TracerProviderBuilderBase.cs | 8 +- .../TracerProviderBuilderExtensions.cs | 25 ++----- .../OpenTelemetryLoggingExtensionsTests.cs | 32 +++++++- .../TracerProviderBuilderExtensionsTest.cs | 8 +- 9 files changed, 97 insertions(+), 58 deletions(-) diff --git a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt index 515a4fb8299..c9fd94087df 100644 --- a/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt @@ -18,8 +18,10 @@ OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void OpenTelemetry.Logs.LogRecord.TraceId.set -> void OpenTelemetry.Logs.LogRecord.TraceState.set -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter, string? name, System.Action? configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, string? name, System.Action? configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureProvider(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt index 515a4fb8299..c9fd94087df 100644 --- a/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -18,8 +18,10 @@ OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void OpenTelemetry.Logs.LogRecord.TraceId.set -> void OpenTelemetry.Logs.LogRecord.TraceState.set -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter, string? name, System.Action? configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, string? name, System.Action? configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureProvider(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index bdfe79411db..171b82d8e49 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -18,8 +18,10 @@ OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void OpenTelemetry.Logs.LogRecord.TraceId.set -> void OpenTelemetry.Logs.LogRecord.TraceState.set -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter, string? name, System.Action? configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, string? name, System.Action? configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureProvider(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index 515a4fb8299..c9fd94087df 100644 --- a/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -18,8 +18,10 @@ OpenTelemetry.Logs.LogRecord.TraceFlags.set -> void OpenTelemetry.Logs.LogRecord.TraceId.set -> void OpenTelemetry.Logs.LogRecord.TraceState.set -> void OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter, string? name, System.Action? configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, OpenTelemetry.BaseExporter! exporter, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, string? name, System.Action? configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddExporter(OpenTelemetry.ExportProcessorType exportProcessorType, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.AddProcessor() -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! OpenTelemetry.Logs.OpenTelemetryLoggerOptions.ConfigureProvider(System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs index 30575914e04..f54c277013f 100644 --- a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs @@ -141,26 +141,37 @@ public OpenTelemetryLoggerOptions AddProcessor() /// LogRecord exporter to add. /// Returns for chaining. public OpenTelemetryLoggerOptions AddExporter(ExportProcessorType exportProcessorType, BaseExporter exporter) - => this.AddExporter(exportProcessorType, exporter, o => { }); + => this.AddExporter(exportProcessorType, exporter, name: null, configure: null); /// /// Adds an exporter to the provider. /// /// . /// LogRecord exporter to add. - /// Callback action to configure . Only invoked when is . + /// /// Returns for chaining. public OpenTelemetryLoggerOptions AddExporter(ExportProcessorType exportProcessorType, BaseExporter exporter, Action configure) + => this.AddExporter(exportProcessorType, exporter, name: null, configure); + + /// + /// Adds an exporter to the provider. + /// + /// . + /// LogRecord exporter to add. + /// Name which is used when retrieving options. + /// + /// Returns for chaining. + public OpenTelemetryLoggerOptions AddExporter( + ExportProcessorType exportProcessorType, + BaseExporter exporter, + string? name, + Action? configure) { Guard.ThrowIfNull(exporter); - Guard.ThrowIfNull(configure); this.ConfigureProvider((sp, provider) => provider.AddProcessor( - BuildExportProcessor(sp, exportProcessorType, exporter, configure))); + BuildExportProcessor(sp, exportProcessorType, exporter, name, configure))); return this; } @@ -168,16 +179,25 @@ public OpenTelemetryLoggerOptions AddExporter(ExportProcessorType exportProcesso /// /// Adds an exporter to the provider which will be retrieved using dependency injection. /// - /// - /// Note: The type specified by will be - /// registered as a singleton service into application services. - /// + /// /// Exporter type. /// . /// Returns for chaining. public OpenTelemetryLoggerOptions AddExporter(ExportProcessorType exportProcessorType) where T : BaseExporter - => this.AddExporter(exportProcessorType, o => { }); + => this.AddExporter(exportProcessorType, name: null, configure: null); + + /// + /// Adds an exporter to the provider which will be retrieved using dependency injection. + /// + /// + /// Exporter type. + /// . + /// + /// Returns for chaining. + public OpenTelemetryLoggerOptions AddExporter(ExportProcessorType exportProcessorType, Action configure) + where T : BaseExporter + => this.AddExporter(exportProcessorType, name: null, configure); /// /// Adds an exporter to the provider which will be retrieved using dependency injection. @@ -188,20 +208,22 @@ public OpenTelemetryLoggerOptions AddExporter(ExportProcessorType exportProce /// /// Exporter type. /// . + /// Name which is used when retrieving options. /// Callback action to configure . Only invoked when is . /// Returns for chaining. - public OpenTelemetryLoggerOptions AddExporter(ExportProcessorType exportProcessorType, Action configure) + public OpenTelemetryLoggerOptions AddExporter( + ExportProcessorType exportProcessorType, + string? name, + Action? configure) where T : BaseExporter { - Guard.ThrowIfNull(configure); - this.TryAddSingleton(); this.ConfigureProvider((sp, provider) => provider.AddProcessor( - BuildExportProcessor(sp, exportProcessorType, sp.GetRequiredService(), configure))); + BuildExportProcessor(sp, exportProcessorType, sp.GetRequiredService(), name, configure))); return this; } @@ -393,20 +415,21 @@ private static BaseProcessor BuildExportProcessor( IServiceProvider serviceProvider, ExportProcessorType exportProcessorType, BaseExporter exporter, - Action configure) + string? name, + Action? configure) { + name ??= Options.DefaultName; + switch (exportProcessorType) { case ExportProcessorType.Simple: return new SimpleLogRecordExportProcessor(exporter); case ExportProcessorType.Batch: - var options = new ExportLogRecordProcessorOptions - { - ExportProcessorType = ExportProcessorType.Batch, - BatchExportProcessorOptions = serviceProvider.GetRequiredService>().Value, - }; + var options = serviceProvider.GetRequiredService>().Get(name); + + options.ExportProcessorType = ExportProcessorType.Batch; - configure(options); + configure?.Invoke(options); var batchOptions = options.BatchExportProcessorOptions; @@ -426,10 +449,7 @@ private void TryAddSingleton() { var services = this.services; - if (services != null) - { - services.TryAddSingleton(); - } + services?.TryAddSingleton(); } } } diff --git a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs index aa842df7b28..c8710813446 100644 --- a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs +++ b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs @@ -278,11 +278,9 @@ private static BaseProcessor BuildExportProcessor( case ExportProcessorType.Simple: return new SimpleActivityExportProcessor(exporter); case ExportProcessorType.Batch: - var options = new ExportActivityProcessorOptions - { - ExportProcessorType = ExportProcessorType.Batch, - BatchExportProcessorOptions = serviceProvider.GetRequiredService>().Get(name), - }; + var options = serviceProvider.GetRequiredService>().Get(name); + + options.ExportProcessorType = ExportProcessorType.Batch; configure?.Invoke(options); diff --git a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs index 5811078f0cc..94caf0e16da 100644 --- a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderExtensions.cs @@ -174,10 +174,7 @@ public static TracerProviderBuilder AddExporter( /// . /// . /// Activity exporter to add. - /// Callback action to configure . Only invoked when is . + /// /// Returns for chaining. public static TracerProviderBuilder AddExporter( this TracerProviderBuilder tracerProviderBuilder, @@ -193,10 +190,7 @@ public static TracerProviderBuilder AddExporter( /// . /// Activity exporter to add. /// Name which is used when retrieving options. - /// Callback action to configure . Only invoked when is . + /// /// Returns for chaining. public static TracerProviderBuilder AddExporter( this TracerProviderBuilder tracerProviderBuilder, @@ -216,10 +210,7 @@ public static TracerProviderBuilder AddExporter( /// /// Adds an exporter to the provider which will be retrieved using dependency injection. /// - /// - /// Note: The type specified by will be - /// registered as a singleton service into application services. - /// + /// /// Exporter type. /// . /// . @@ -233,17 +224,11 @@ public static TracerProviderBuilder AddExporter( /// /// Adds an exporter to the provider which will be retrieved using dependency injection. /// - /// - /// Note: The type specified by will be - /// registered as a singleton service into application services. - /// + /// /// Exporter type. /// . /// . - /// Callback action to configure . Only invoked when is . + /// /// The supplied for chaining. public static TracerProviderBuilder AddExporter( this TracerProviderBuilder tracerProviderBuilder, diff --git a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs index 0d141abd4ad..87211995098 100644 --- a/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs +++ b/test/OpenTelemetry.Tests/Logs/OpenTelemetryLoggingExtensionsTests.cs @@ -502,13 +502,13 @@ public void LoggingBuilderAddOpenTelemetryAddExporterWithOptionsTest() builder.ConfigureServices(services => { - services.Configure(options => + services.Configure(options => { // Note: This is testing options integration optionsInvocations++; - options.MaxExportBatchSize = 18; + options.BatchExportProcessorOptions.MaxExportBatchSize = 18; }); }); @@ -550,6 +550,34 @@ public void LoggingBuilderAddOpenTelemetryAddExporterWithOptionsTest() && batchProcessor.MaxExportBatchSize == 100); } + [Fact] + public void LoggingBuilderAddOpenTelemetryAddExporterNamedOptionsTest() + { + var builder = Sdk.CreateLoggerProviderBuilder(); + + int defaultOptionsConfigureInvocations = 0; + int namedOptionsConfigureInvocations = 0; + + builder.ConfigureServices(services => + { + services.Configure(o => defaultOptionsConfigureInvocations++); + + services.Configure("Exporter2", o => namedOptionsConfigureInvocations++); + }); + + builder.AddExporter(ExportProcessorType.Batch, new CustomExporter()); + builder.AddExporter(ExportProcessorType.Batch, new CustomExporter(), name: "Exporter2", configure: null); + builder.AddExporter(ExportProcessorType.Batch); + builder.AddExporter(ExportProcessorType.Batch, name: "Exporter2", configure: null); + + using var provider = builder.Build(); + + Assert.NotNull(provider); + + Assert.Equal(1, defaultOptionsConfigureInvocations); + Assert.Equal(1, namedOptionsConfigureInvocations); + } + private sealed class WrappedOpenTelemetryLoggerProvider : OpenTelemetryLoggerProvider { public bool Disposed { get; private set; } diff --git a/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs b/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs index 5f3d5b95bb5..383e691d358 100644 --- a/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs +++ b/test/OpenTelemetry.Tests/Trace/TracerProviderBuilderExtensionsTest.cs @@ -317,13 +317,13 @@ public void AddExporterWithOptionsTest() builder.ConfigureServices(services => { - services.Configure(options => + services.Configure(options => { // Note: This is testing options integration optionsInvocations++; - options.MaxExportBatchSize = 18; + options.BatchExportProcessorOptions.MaxExportBatchSize = 18; }); }); @@ -375,9 +375,9 @@ public void AddExporterNamedOptionsTest() builder.ConfigureServices(services => { - services.Configure(o => defaultOptionsConfigureInvocations++); + services.Configure(o => defaultOptionsConfigureInvocations++); - services.Configure("Exporter2", o => namedOptionsConfigureInvocations++); + services.Configure("Exporter2", o => namedOptionsConfigureInvocations++); }); builder.AddExporter(ExportProcessorType.Batch, new MyExporter()); From 97e5021c73e64478c5b9df0bc8469e9f81109813 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 14 Sep 2022 13:14:33 -0700 Subject: [PATCH 18/34] [Traces] Support named options in AspNetCore instrumentation (#3661) * Support named options in aspnetcore instrumentation. * CHANGELOG update. --- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 4 ++- .../.publicApi/net7.0/PublicAPI.Unshipped.txt | 4 ++- .../CHANGELOG.md | 5 +++ .../TracerProviderBuilderExtensions.cs | 31 ++++++++++++++++--- .../DependencyInjectionConfigTests.cs | 16 +++++----- 5 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net6.0/PublicAPI.Unshipped.txt index 87d29939cca..0327c2bb195 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -11,4 +11,6 @@ OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreInstrumentationOptions.Record OpenTelemetry.Metrics.MeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureAspNetCoreInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configureAspNetCoreInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureAspNetCoreInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net7.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net7.0/PublicAPI.Unshipped.txt index 87d29939cca..0327c2bb195 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net7.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net7.0/PublicAPI.Unshipped.txt @@ -11,4 +11,6 @@ OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreInstrumentationOptions.Record OpenTelemetry.Metrics.MeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureAspNetCoreInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configureAspNetCoreInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureAspNetCoreInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index 4cd25682683..69fbffefb9c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -6,6 +6,11 @@ wouldn't be collected. ([#3475](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3475)) +* Added overloads which accept a name to the `TracerProviderBuilder` + `AddAspNetCoreInstrumentation` extension to allow for more fine-grained + options management + ([#3661](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3661)) + ## 1.0.0-rc9.6 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs index f864c8e659e..47b20857d78 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs @@ -35,22 +35,45 @@ public static class TracerProviderBuilderExtensions /// Enables the incoming requests automatic data collection for ASP.NET Core. /// /// being configured. - /// ASP.NET Core Request configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddAspNetCoreInstrumentation(this TracerProviderBuilder builder) + => AddAspNetCoreInstrumentation(builder, name: null, configureAspNetCoreInstrumentationOptions: null); + + /// + /// Enables the incoming requests automatic data collection for ASP.NET Core. + /// + /// being configured. + /// Callback action for configuring . /// The instance of to chain the calls. public static TracerProviderBuilder AddAspNetCoreInstrumentation( this TracerProviderBuilder builder, - Action configureAspNetCoreInstrumentationOptions = null) + Action configureAspNetCoreInstrumentationOptions) + => AddAspNetCoreInstrumentation(builder, name: null, configureAspNetCoreInstrumentationOptions); + + /// + /// Enables the incoming requests automatic data collection for ASP.NET Core. + /// + /// being configured. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddAspNetCoreInstrumentation( + this TracerProviderBuilder builder, + string name, + Action configureAspNetCoreInstrumentationOptions) { Guard.ThrowIfNull(builder); + name ??= Options.DefaultName; + if (configureAspNetCoreInstrumentationOptions != null) { - builder.ConfigureServices(services => services.Configure(configureAspNetCoreInstrumentationOptions)); + builder.ConfigureServices(services => services.Configure(name, configureAspNetCoreInstrumentationOptions)); } return builder.ConfigureBuilder((sp, builder) => { - var options = sp.GetRequiredService>().Value; + var options = sp.GetRequiredService>().Get(name); AddAspNetCoreInstrumentation(builder, new AspNetCoreInstrumentation(new HttpInListener(options)), sp); }); diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs index f8b237ae197..32fa500d0a4 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs @@ -17,6 +17,7 @@ using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Trace; using Xunit; @@ -32,19 +33,20 @@ public DependencyInjectionConfigTests(WebApplicationFactory factory) this.factory = factory; } - [Fact] - public void TestDIConfig() + [Theory] + [InlineData(null)] + [InlineData("CustomName")] + public void TestDIConfig(string name) { + name ??= Options.DefaultName; + bool optionsPickedFromDI = false; void ConfigureTestServices(IServiceCollection services) { services.AddOpenTelemetryTracing( - builder => - { - builder.AddAspNetCoreInstrumentation(); - }); + builder => builder.AddAspNetCoreInstrumentation(name, configureAspNetCoreInstrumentationOptions: null)); - services.Configure(options => + services.Configure(name, options => { optionsPickedFromDI = true; }); From 928d77056c1d353d8ba72ad3b4b565398117b352 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 14 Sep 2022 14:25:37 -0700 Subject: [PATCH 19/34] Use IOptionsMonitor instead of IOptionsSnapshot. (#3662) --- .../ConsoleExporterHelperExtensions.cs | 2 +- .../ConsoleExporterLoggingExtensions.cs | 2 +- .../ConsoleExporterMetricsExtensions.cs | 8 ++++---- .../InMemoryExporterMetricsExtensions.cs | 4 ++-- .../JaegerExporterHelperExtensions.cs | 2 +- .../OtlpLogExporterHelperExtensions.cs | 2 +- .../OtlpMetricExporterExtensions.cs | 8 ++++---- .../OtlpTraceExporterHelperExtensions.cs | 2 +- .../PrometheusExporterMeterProviderBuilderExtensions.cs | 2 +- ...ometheusHttpListenerMeterProviderBuilderExtensions.cs | 2 +- .../ZipkinExporterHelperExtensions.cs | 2 +- .../Logs/Options/OpenTelemetryLoggerOptions.cs | 9 +++++++-- .../Metrics/Builder/MeterProviderBuilderBase.cs | 7 ++++++- .../Trace/Builder/TracerProviderBuilderBase.cs | 9 +++++++-- 14 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs index 2bb84b49c8b..850533edf42 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporterHelperExtensions.cs @@ -64,7 +64,7 @@ public static TracerProviderBuilder AddConsoleExporter( return builder.ConfigureBuilder((sp, builder) => { - var options = sp.GetRequiredService>().Get(name); + var options = sp.GetRequiredService>().Get(name); builder.AddProcessor(new SimpleActivityExportProcessor(new ConsoleActivityExporter(options))); }); diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs index 7e85c968cb5..e59788e004f 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporterLoggingExtensions.cs @@ -64,7 +64,7 @@ public static OpenTelemetryLoggerOptions AddConsoleExporter( return loggerOptions.ConfigureProvider((sp, provider) => { - var options = sp.GetRequiredService>().Get(name); + var options = sp.GetRequiredService>().Get(name); provider.AddProcessor(new SimpleLogRecordExportProcessor(new ConsoleLogRecordExporter(options))); }); diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs index e8250fadf13..e0c84632f51 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporterMetricsExtensions.cs @@ -73,8 +73,8 @@ public static MeterProviderBuilder AddConsoleExporter( { AddConsoleExporter( builder, - sp.GetRequiredService>().Get(name), - sp.GetRequiredService>().Get(name)); + sp.GetRequiredService>().Get(name), + sp.GetRequiredService>().Get(name)); }); } @@ -111,8 +111,8 @@ public static MeterProviderBuilder AddConsoleExporter( return builder.ConfigureBuilder((sp, builder) => { - var exporterOptions = sp.GetRequiredService>().Get(name); - var metricReaderOptions = sp.GetRequiredService>().Get(name); + var exporterOptions = sp.GetRequiredService>().Get(name); + var metricReaderOptions = sp.GetRequiredService>().Get(name); configureExporterAndMetricReader?.Invoke(exporterOptions, metricReaderOptions); diff --git a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs index b72e16f0459..56335d6a088 100644 --- a/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs +++ b/src/OpenTelemetry.Exporter.InMemory/InMemoryExporterMetricsExtensions.cs @@ -89,7 +89,7 @@ public static MeterProviderBuilder AddInMemoryExporter( return builder.ConfigureBuilder((sp, builder) => { - var options = sp.GetRequiredService>().Get(name); + var options = sp.GetRequiredService>().Get(name); AddInMemoryExporter(builder, exportedItems, options); }); @@ -157,7 +157,7 @@ public static MeterProviderBuilder AddInMemoryExporter( return builder.ConfigureBuilder((sp, builder) => { - var options = sp.GetRequiredService>().Get(name); + var options = sp.GetRequiredService>().Get(name); AddInMemoryExporter(builder, exportedItems, options); }); diff --git a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs index db1b770d31d..c9da743562d 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterHelperExtensions.cs @@ -69,7 +69,7 @@ public static TracerProviderBuilder AddJaegerExporter( return builder.ConfigureBuilder((sp, builder) => { - var options = sp.GetRequiredService>().Get(name); + var options = sp.GetRequiredService>().Get(name); AddJaegerExporter(builder, options, sp); }); diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/OtlpLogExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/OtlpLogExporterHelperExtensions.cs index 4339e1e088e..65e0c0a2503 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/OtlpLogExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs/OtlpLogExporterHelperExtensions.cs @@ -78,7 +78,7 @@ public static OpenTelemetryLoggerOptions AddOtlpExporter( return loggerOptions.ConfigureProvider((sp, provider) => { - var options = sp.GetRequiredService>().Get(name); + var options = sp.GetRequiredService>().Get(name); AddOtlpExporter(provider, options, sp); }); diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs index ee7f306ca0f..d3d45402c19 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpMetricExporterExtensions.cs @@ -69,8 +69,8 @@ public static MeterProviderBuilder AddOtlpExporter( { AddOtlpExporter( builder, - sp.GetRequiredService>().Get(name), - sp.GetRequiredService>().Get(name), + sp.GetRequiredService>().Get(name), + sp.GetRequiredService>().Get(name), sp); }); } @@ -108,8 +108,8 @@ public static MeterProviderBuilder AddOtlpExporter( return builder.ConfigureBuilder((sp, builder) => { - var exporterOptions = sp.GetRequiredService>().Get(name); - var metricReaderOptions = sp.GetRequiredService>().Get(name); + var exporterOptions = sp.GetRequiredService>().Get(name); + var metricReaderOptions = sp.GetRequiredService>().Get(name); configureExporterAndMetricReader?.Invoke(exporterOptions, metricReaderOptions); diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs index 2667a25554f..807b7633f2a 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs @@ -68,7 +68,7 @@ public static TracerProviderBuilder AddOtlpExporter( return builder.ConfigureBuilder((sp, builder) => { - var options = sp.GetRequiredService>().Get(name); + var options = sp.GetRequiredService>().Get(name); AddOtlpExporter(builder, options, sp); }); diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMeterProviderBuilderExtensions.cs index daacd2c66b8..3494f272ae4 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMeterProviderBuilderExtensions.cs @@ -70,7 +70,7 @@ public static MeterProviderBuilder AddPrometheusExporter( return builder.ConfigureBuilder((sp, builder) => { - var options = sp.GetRequiredService>().Get(name); + var options = sp.GetRequiredService>().Get(name); AddPrometheusExporter(builder, options); }); diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs index 605aaff6df4..cb8a9af732b 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs @@ -70,7 +70,7 @@ public static MeterProviderBuilder AddPrometheusHttpListener( return builder.ConfigureBuilder((sp, builder) => { - var options = sp.GetRequiredService>().Get(name); + var options = sp.GetRequiredService>().Get(name); AddPrometheusHttpListener(builder, options); }); diff --git a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs index 484254c68e2..261cecd1a64 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporterHelperExtensions.cs @@ -69,7 +69,7 @@ public static TracerProviderBuilder AddZipkinExporter( return builder.ConfigureBuilder((sp, builder) => { - var options = sp.GetRequiredService>().Get(name); + var options = sp.GetRequiredService>().Get(name); AddZipkinExporter(builder, options, sp); }); diff --git a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs index f54c277013f..265e79e7fa4 100644 --- a/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs +++ b/src/OpenTelemetry/Logs/Options/OpenTelemetryLoggerOptions.cs @@ -368,7 +368,12 @@ internal OpenTelemetryLoggerProvider Build() this.services = null; - var serviceProvider = services.BuildServiceProvider(); +#if DEBUG + bool validateScopes = true; +#else + bool validateScopes = false; +#endif + var serviceProvider = services.BuildServiceProvider(validateScopes); var finalOptions = serviceProvider.GetRequiredService>().CurrentValue; @@ -425,7 +430,7 @@ private static BaseProcessor BuildExportProcessor( case ExportProcessorType.Simple: return new SimpleLogRecordExportProcessor(exporter); case ExportProcessorType.Batch: - var options = serviceProvider.GetRequiredService>().Get(name); + var options = serviceProvider.GetRequiredService>().Get(name); options.ExportProcessorType = ExportProcessorType.Batch; diff --git a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs index 1ddd03dd310..186926a5799 100644 --- a/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs +++ b/src/OpenTelemetry/Metrics/Builder/MeterProviderBuilderBase.cs @@ -257,7 +257,12 @@ protected MeterProvider Build() this.services = null; - var serviceProvider = services.BuildServiceProvider(); +#if DEBUG + bool validateScopes = true; +#else + bool validateScopes = false; +#endif + var serviceProvider = services.BuildServiceProvider(validateScopes); return new MeterProviderSdk(serviceProvider, ownsServiceProvider: true); } diff --git a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs index c8710813446..a747395308c 100644 --- a/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs +++ b/src/OpenTelemetry/Trace/Builder/TracerProviderBuilderBase.cs @@ -259,7 +259,12 @@ protected TracerProvider Build() this.services = null; - var serviceProvider = services.BuildServiceProvider(); +#if DEBUG + bool validateScopes = true; +#else + bool validateScopes = false; +#endif + var serviceProvider = services.BuildServiceProvider(validateScopes); return new TracerProviderSdk(serviceProvider, ownsServiceProvider: true); } @@ -278,7 +283,7 @@ private static BaseProcessor BuildExportProcessor( case ExportProcessorType.Simple: return new SimpleActivityExportProcessor(exporter); case ExportProcessorType.Batch: - var options = serviceProvider.GetRequiredService>().Get(name); + var options = serviceProvider.GetRequiredService>().Get(name); options.ExportProcessorType = ExportProcessorType.Batch; From 960908cb6924d18766ee39a034c787216269d3e0 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 14 Sep 2022 17:40:53 -0700 Subject: [PATCH 20/34] [Traces] Support named options in gRPC instrumentation (#3665) * Support named options in grpc instrumentation. * CHANGELOG update. --- .../netstandard2.0/PublicAPI.Unshipped.txt | 4 +- .../netstandard2.1/PublicAPI.Unshipped.txt | 4 +- .../CHANGELOG.md | 5 ++ .../TracerProviderBuilderExtensions.cs | 50 +++++++++++++++---- .../GrpcTests.client.cs | 22 ++++++++ 5 files changed, 73 insertions(+), 12 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index bab9f248015..82eecf60816 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -5,4 +5,6 @@ OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientInstrumentationOptions.Grp OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index bab9f248015..82eecf60816 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -5,4 +5,6 @@ OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientInstrumentationOptions.Grp OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md index cfb66948c7b..678b62d6d17 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Added overloads which accept a name to the `TracerProviderBuilder` + `AddGrpcClientInstrumentation` extension to allow for more fine-grained + options management + ([#3665](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3665)) + ## 1.0.0-rc9.6 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/TracerProviderBuilderExtensions.cs index 33c51475ca8..d53c1421910 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/TracerProviderBuilderExtensions.cs @@ -15,6 +15,8 @@ // using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.GrpcNetClient; using OpenTelemetry.Instrumentation.GrpcNetClient.Implementation; using OpenTelemetry.Internal; @@ -22,31 +24,59 @@ namespace OpenTelemetry.Trace { /// - /// Extension methods to simplify registering of gRPClient + /// Extension methods to simplify registering of gRPC client /// instrumentation. /// public static class TracerProviderBuilderExtensions { /// - /// Enables gRPClient Instrumentation. + /// Enables gRPC client instrumentation. /// /// being configured. - /// GrpcClient configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddGrpcClientInstrumentation(this TracerProviderBuilder builder) + => AddGrpcClientInstrumentation(builder, name: null, configure: null); + + /// + /// Enables gRPC client instrumentation. + /// + /// being configured. + /// Callback action for configuring . /// The instance of to chain the calls. public static TracerProviderBuilder AddGrpcClientInstrumentation( this TracerProviderBuilder builder, - Action configure = null) + Action configure) + => AddGrpcClientInstrumentation(builder, name: null, configure); + + /// + /// Enables gRPC client instrumentation. + /// + /// being configured. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddGrpcClientInstrumentation( + this TracerProviderBuilder builder, + string name, + Action configure) { Guard.ThrowIfNull(builder); - var grpcOptions = new GrpcClientInstrumentationOptions(); - configure?.Invoke(grpcOptions); + name ??= Options.DefaultName; + + if (configure != null) + { + builder.ConfigureServices(services => services.Configure(name, configure)); + } - builder.AddInstrumentation(() => new GrpcClientInstrumentation(grpcOptions)); - builder.AddSource(GrpcClientDiagnosticListener.ActivitySourceName); - builder.AddLegacySource("Grpc.Net.Client.GrpcOut"); + return builder.ConfigureBuilder((sp, builder) => + { + var options = sp.GetRequiredService>().Get(name); - return builder; + builder.AddInstrumentation(() => new GrpcClientInstrumentation(options)); + builder.AddSource(GrpcClientDiagnosticListener.ActivitySourceName); + builder.AddLegacySource("Grpc.Net.Client.GrpcOut"); + }); } } } diff --git a/test/OpenTelemetry.Instrumentation.Grpc.Tests/GrpcTests.client.cs b/test/OpenTelemetry.Instrumentation.Grpc.Tests/GrpcTests.client.cs index 5e7b244860f..e011eead53c 100644 --- a/test/OpenTelemetry.Instrumentation.Grpc.Tests/GrpcTests.client.cs +++ b/test/OpenTelemetry.Instrumentation.Grpc.Tests/GrpcTests.client.cs @@ -23,6 +23,7 @@ using Greet; using Grpc.Core; using Grpc.Net.Client; +using Microsoft.Extensions.DependencyInjection; #if NET6_0_OR_GREATER using Microsoft.AspNetCore.Http; #endif @@ -442,6 +443,27 @@ public void GrpcClientInstrumentationRespectsSdkSuppressInstrumentation() } #endif + [Fact] + public void AddGrpcClientInstrumentationNamedOptionsSupported() + { + int defaultExporterOptionsConfigureOptionsInvocations = 0; + int namedExporterOptionsConfigureOptionsInvocations = 0; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => + { + services.Configure(o => defaultExporterOptionsConfigureOptionsInvocations++); + + services.Configure("Instrumentation2", o => namedExporterOptionsConfigureOptionsInvocations++); + }) + .AddGrpcClientInstrumentation() + .AddGrpcClientInstrumentation("Instrumentation2", configure: null) + .Build(); + + Assert.Equal(1, defaultExporterOptionsConfigureOptionsInvocations); + Assert.Equal(1, namedExporterOptionsConfigureOptionsInvocations); + } + [Fact] public void Grpc_BadArgs() { From 215f58bad5fd019b6fab425561f2f238c472d658 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 15 Sep 2022 10:56:13 -0700 Subject: [PATCH 21/34] [Traces] Support named options in HttpClient instrumentation (#3664) * Enabled named options in httpclient instrumentation. * Tests. * CHANGELOG update. Co-authored-by: Cijo Thomas --- .../PublicAPI.Shipped.txt | 0 .../PublicAPI.Unshipped.txt | 4 ++- .../CHANGELOG.md | 8 +++++ .../OpenTelemetry.Instrumentation.Http.csproj | 7 ++++- .../TracerProviderBuilderExtensions.cs | 31 ++++++++++++++++--- .../HttpClientTests.Basic.cs | 22 +++++++++++++ 6 files changed, 66 insertions(+), 6 deletions(-) rename src/OpenTelemetry.Instrumentation.Http/.publicApi/{netstandard2.0 => net6.0}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.Http/.publicApi/{netstandard2.0 => net6.0}/PublicAPI.Unshipped.txt (70%) diff --git a/src/OpenTelemetry.Instrumentation.Http/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Http/.publicApi/net6.0/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.Http/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.Http/.publicApi/net6.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Http/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Http/.publicApi/net6.0/PublicAPI.Unshipped.txt similarity index 70% rename from src/OpenTelemetry.Instrumentation.Http/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.Http/.publicApi/net6.0/PublicAPI.Unshipped.txt index 8ac18d7a6e1..0224a11a2e5 100644 --- a/src/OpenTelemetry.Instrumentation.Http/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Http/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -9,4 +9,6 @@ OpenTelemetry.Instrumentation.Http.HttpClientInstrumentationOptions.RecordExcept OpenTelemetry.Metrics.MeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureHttpClientInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configureHttpClientInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureHttpClientInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index c7ce6fdac9b..4777e306a67 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +* Dropped `netstandard2.0` target and added `net6.0` + ([#3664](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3664)) + +* Added overloads which accept a name to the `TracerProviderBuilder` + `AddHttpClientInstrumentation` extension to allow for more fine-grained + options management + ([#3664](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3664)) + ## 1.0.0-rc9.6 Released 2022-Aug-18 diff --git a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj index 3665f2c85e0..621422a822b 100644 --- a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj +++ b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj @@ -2,12 +2,17 @@ - netstandard2.0;net462 + net6.0;net462 Http instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing true + + + false + + diff --git a/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs index 3a6640c61c1..619035e82bc 100644 --- a/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs @@ -61,22 +61,45 @@ public static TracerProviderBuilder AddHttpClientInstrumentation( /// Enables HttpClient instrumentation. /// /// being configured. - /// HttpClient configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddHttpClientInstrumentation(this TracerProviderBuilder builder) + => AddHttpClientInstrumentation(builder, name: null, configureHttpClientInstrumentationOptions: null); + + /// + /// Enables HttpClient instrumentation. + /// + /// being configured. + /// Callback action for configuring . /// The instance of to chain the calls. public static TracerProviderBuilder AddHttpClientInstrumentation( this TracerProviderBuilder builder, - Action configureHttpClientInstrumentationOptions = null) + Action configureHttpClientInstrumentationOptions) + => AddHttpClientInstrumentation(builder, name: null, configureHttpClientInstrumentationOptions); + + /// + /// Enables HttpClient instrumentation. + /// + /// being configured. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddHttpClientInstrumentation( + this TracerProviderBuilder builder, + string name, + Action configureHttpClientInstrumentationOptions) { Guard.ThrowIfNull(builder); + name ??= Options.DefaultName; + if (configureHttpClientInstrumentationOptions != null) { - builder.ConfigureServices(services => services.Configure(configureHttpClientInstrumentationOptions)); + builder.ConfigureServices(services => services.Configure(name, configureHttpClientInstrumentationOptions)); } return builder.ConfigureBuilder((sp, builder) => { - var options = sp.GetRequiredService>().Value; + var options = sp.GetRequiredService>().Get(name); AddHttpClientInstrumentation(builder, new HttpClientInstrumentation(options)); }); diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs index c06a18bc89f..3b49cac0348 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs @@ -19,6 +19,7 @@ using System.Linq; using System.Net.Http; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Moq; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Instrumentation.Http.Implementation; @@ -47,6 +48,27 @@ public HttpClientTests() this.url = $"http://{host}:{port}/"; } + [Fact] + public void AddHttpClientInstrumentation_NamedOptions() + { + int defaultExporterOptionsConfigureOptionsInvocations = 0; + int namedExporterOptionsConfigureOptionsInvocations = 0; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => + { + services.Configure(o => defaultExporterOptionsConfigureOptionsInvocations++); + + services.Configure("Instrumentation2", o => namedExporterOptionsConfigureOptionsInvocations++); + }) + .AddHttpClientInstrumentation() + .AddHttpClientInstrumentation("Instrumentation2", configureHttpClientInstrumentationOptions: null) + .Build(); + + Assert.Equal(1, defaultExporterOptionsConfigureOptionsInvocations); + Assert.Equal(1, namedExporterOptionsConfigureOptionsInvocations); + } + [Fact] public void AddHttpClientInstrumentation_BadArgs() { From d72a94f3ba72875f7abab19bc75298a0280385f9 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 15 Sep 2022 11:54:35 -0700 Subject: [PATCH 22/34] [Traces] Support named options in HttpWebRequest instrumentation (#3667) * Added support for named options in the HttpWebRequest builder extensions. * CHANGELOG update. --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 4 ++- .../CHANGELOG.md | 3 +- .../TracerProviderBuilderExtensions.cs | 31 ++++++++++++++++--- .../HttpWebRequestTests.Basic.netfx.cs | 20 ++++++++++-- 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Http/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Http/.publicApi/net462/PublicAPI.Unshipped.txt index f303cf77aae..2a3aa89a04a 100644 --- a/src/OpenTelemetry.Instrumentation.Http/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Http/.publicApi/net462/PublicAPI.Unshipped.txt @@ -17,4 +17,6 @@ OpenTelemetry.Instrumentation.Http.HttpWebRequestInstrumentationOptions.RecordEx OpenTelemetry.Metrics.MeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureHttpWebRequestInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configureHttpWebRequestInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureHttpWebRequestInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index 4777e306a67..d387533a70e 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -8,7 +8,8 @@ * Added overloads which accept a name to the `TracerProviderBuilder` `AddHttpClientInstrumentation` extension to allow for more fine-grained options management - ([#3664](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3664)) + ([#3664](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3664), + [#3667](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3667)) ## 1.0.0-rc9.6 diff --git a/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs index 619035e82bc..17dc4c29ebf 100644 --- a/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Http/TracerProviderBuilderExtensions.cs @@ -35,20 +35,43 @@ public static class TracerProviderBuilderExtensions /// Enables HttpClient and HttpWebRequest instrumentation. /// /// being configured. - /// HttpWebRequest configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddHttpClientInstrumentation(this TracerProviderBuilder builder) + => AddHttpClientInstrumentation(builder, name: null, configureHttpWebRequestInstrumentationOptions: null); + + /// + /// Enables HttpClient and HttpWebRequest instrumentation. + /// + /// being configured. + /// Callback action for configuring . /// The instance of to chain the calls. public static TracerProviderBuilder AddHttpClientInstrumentation( this TracerProviderBuilder builder, - Action configureHttpWebRequestInstrumentationOptions = null) + Action configureHttpWebRequestInstrumentationOptions) + => AddHttpClientInstrumentation(builder, name: null, configureHttpWebRequestInstrumentationOptions); + + /// + /// Enables HttpClient and HttpWebRequest instrumentation. + /// + /// being configured. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddHttpClientInstrumentation( + this TracerProviderBuilder builder, + string name, + Action configureHttpWebRequestInstrumentationOptions) { + name ??= Options.DefaultName; + if (configureHttpWebRequestInstrumentationOptions != null) { - builder.ConfigureServices(services => services.Configure(configureHttpWebRequestInstrumentationOptions)); + builder.ConfigureServices(services => services.Configure(name, configureHttpWebRequestInstrumentationOptions)); } return builder.ConfigureBuilder((sp, builder) => { - var options = sp.GetRequiredService>().Value; + var options = sp.GetRequiredService>().Get(name); HttpWebRequestActivitySource.Options = options; diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.netfx.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.netfx.cs index 620438e262e..382a1016343 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.netfx.cs @@ -20,6 +20,8 @@ using System.Net; using System.Net.Http; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Moq; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Instrumentation.Http.Implementation; @@ -252,17 +254,29 @@ public async Task RequestNotCollectedWhenInstrumentationFilterThrowsException() } } - [Fact] - public void AddHttpClientInstrumentationUsesHttpWebRequestInstrumentationOptions() + [Theory] + [InlineData(null)] + [InlineData("CustomName")] + public void AddHttpClientInstrumentationUsesHttpWebRequestInstrumentationOptions(string name) { + name ??= Options.DefaultName; + + int configurationDelegateInvocations = 0; + var activityProcessor = new Mock>(); using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => + { + services.Configure(name, o => configurationDelegateInvocations++); + }) .AddProcessor(activityProcessor.Object) - .AddHttpClientInstrumentation(options => + .AddHttpClientInstrumentation(name, options => { Assert.IsType(options); }) .Build(); + + Assert.Equal(1, configurationDelegateInvocations); } [Fact] From 78e38423d7b8cf04447a94e5c4bcea383515fabb Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Fri, 16 Sep 2022 16:22:22 -0700 Subject: [PATCH 23/34] improve eventsource tests - part 1 (#3586) --- .../Internal/OpenTelemetrySdkEventSource.cs | 2 +- .../EventSourceTest.cs | 29 +++++++++++++++++++ ...Telemetry.Exporter.Prometheus.Tests.csproj | 2 ++ .../Shared/EventSourceTestHelper.cs | 21 +++++++++----- .../Shared/TestEventListener.cs | 24 +++++++++------ 5 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 test/OpenTelemetry.Exporter.Prometheus.Tests/EventSourceTest.cs diff --git a/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs b/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs index 27520b4d943..f9f6b6f2ed8 100644 --- a/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs +++ b/src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs @@ -195,7 +195,7 @@ public void ShutdownEvent(int spansLeftUnprocessed) [Event(3, Message = "Exporter returned error '{0}'.", Level = EventLevel.Warning)] public void ExporterErrorResult(ExportResult exportResult) { - this.WriteEvent(3, exportResult.ToString()); + this.WriteEvent(3, exportResult); } [Event(4, Message = "Unknown error in SpanProcessor event '{0}': '{1}'.", Level = EventLevel.Error)] diff --git a/test/OpenTelemetry.Exporter.Prometheus.Tests/EventSourceTest.cs b/test/OpenTelemetry.Exporter.Prometheus.Tests/EventSourceTest.cs new file mode 100644 index 00000000000..05fcbb130c6 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Prometheus.Tests/EventSourceTest.cs @@ -0,0 +1,29 @@ +// +// 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 OpenTelemetry.Tests; +using Xunit; + +namespace OpenTelemetry.Exporter.Prometheus.Tests; + +public class EventSourceTest +{ + [Fact] + public void EventSourceTest_PrometheusExporterEventSource() + { + EventSourceTestHelper.MethodsAreImplementedConsistentlyWithTheirAttributes(PrometheusExporterEventSource.Log); + } +} diff --git a/test/OpenTelemetry.Exporter.Prometheus.Tests/OpenTelemetry.Exporter.Prometheus.Tests.csproj b/test/OpenTelemetry.Exporter.Prometheus.Tests/OpenTelemetry.Exporter.Prometheus.Tests.csproj index 1973599e201..2062a3530e3 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.Tests/OpenTelemetry.Exporter.Prometheus.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Prometheus.Tests/OpenTelemetry.Exporter.Prometheus.Tests.csproj @@ -29,6 +29,8 @@ + + diff --git a/test/OpenTelemetry.Tests/Shared/EventSourceTestHelper.cs b/test/OpenTelemetry.Tests/Shared/EventSourceTestHelper.cs index 67afcbb57b8..3d2c1e9f813 100644 --- a/test/OpenTelemetry.Tests/Shared/EventSourceTestHelper.cs +++ b/test/OpenTelemetry.Tests/Shared/EventSourceTestHelper.cs @@ -42,17 +42,24 @@ private static void VerifyMethodImplementation(EventSource eventSource, MethodIn object[] eventArguments = GenerateEventArguments(eventMethod); eventMethod.Invoke(eventSource, eventArguments); - EventWrittenEventArgs actualEvent = null; + EventWrittenEventArgs actualEvent = listener.Messages.FirstOrDefault(x => x.EventName == eventMethod.Name); - actualEvent = listener.Messages.First(q => q.EventName == eventMethod.Name); + if (actualEvent == null) + { + // check for errors + actualEvent = listener.Messages.FirstOrDefault(x => x.EventId == 0); + if (actualEvent != null) + { + throw new Exception(actualEvent.Message); + } + + // give up + throw new Exception("Listener failed to collect event."); + } VerifyEventId(eventMethod, actualEvent); VerifyEventLevel(eventMethod, actualEvent); - - if (eventMethod.Name != "ExporterErrorResult") - { - VerifyEventMessage(eventMethod, actualEvent, eventArguments); - } + VerifyEventMessage(eventMethod, actualEvent, eventArguments); } catch (Exception e) { diff --git a/test/OpenTelemetry.Tests/Shared/TestEventListener.cs b/test/OpenTelemetry.Tests/Shared/TestEventListener.cs index edff6577ca9..1da83d32344 100644 --- a/test/OpenTelemetry.Tests/Shared/TestEventListener.cs +++ b/test/OpenTelemetry.Tests/Shared/TestEventListener.cs @@ -26,8 +26,11 @@ namespace OpenTelemetry.Tests /// internal class TestEventListener : EventListener { + /// Unique Id used to identify events from the test thread. + private readonly Guid activityId; + /// A queue of events that have been logged. - private readonly Queue events; + private readonly List events; /// /// Lock for event writing tracking. @@ -39,11 +42,14 @@ internal class TestEventListener : EventListener /// public TestEventListener() { - this.events = new Queue(); + this.activityId = Guid.NewGuid(); + EventSource.SetCurrentThreadActivityId(this.activityId); + + this.events = new List(); this.eventWritten = new AutoResetEvent(false); this.OnOnEventWritten = e => { - this.events.Enqueue(e); + this.events.Add(e); this.eventWritten.Set(); }; } @@ -55,7 +61,7 @@ public TestEventListener() public Action OnOnEventWritten { get; set; } /// Gets the events that have been written. - public IEnumerable Messages + public IList Messages { get { @@ -64,10 +70,7 @@ public IEnumerable Messages this.eventWritten.WaitOne(TimeSpan.FromSeconds(5)); } - while (this.events.Count != 0) - { - yield return this.events.Dequeue(); - } + return this.events; } } @@ -83,7 +86,10 @@ public void ClearMessages() /// The event data that was written. protected override void OnEventWritten(EventWrittenEventArgs eventData) { - this.OnOnEventWritten(eventData); + if (eventData.ActivityId == this.activityId) + { + this.OnOnEventWritten(eventData); + } } /// Handler for event source creation. From 3d03426694b12e294b30c6ba955ff4afd621f2c7 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Mon, 19 Sep 2022 11:22:35 -0700 Subject: [PATCH 24/34] HttpClient instrumentation: Clarify drop of support for .NET 5 and prior (#3675) --- src/OpenTelemetry.Api/CHANGELOG.md | 4 +++- src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md | 4 +++- src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md | 7 ++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md index fe1fadfd7a7..307b1cbbb90 100644 --- a/src/OpenTelemetry.Api/CHANGELOG.md +++ b/src/OpenTelemetry.Api/CHANGELOG.md @@ -12,7 +12,9 @@ Released 2022-Aug-18 warning at build time as described [here](https://github.com/dotnet/runtime/pull/72518) (note: building using older versions of the .NET SDK produces an error at build time). This is because .NET 5 reached EOL in May 2022 and .NET - Core 3.1 reaches EOL in December 2022. + Core 3.1 reaches EOL in December 2022. End of support + dates for .NET are published + [here](https://dotnet.microsoft.com/download/dotnet). There is no guarantee that System.Diagnostics.DiagnosticSource will continue to work on older versions of .NET. However, the build warning can be diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index 69fbffefb9c..0ff631694a3 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -16,7 +16,9 @@ Released 2022-Aug-18 * Removed `netstandard2.0` and `netstandard2.1` targets. .NET 5 reached EOL - in May 2022 and .NET Core 3.1 reaches EOL in December 2022. The + in May 2022 and .NET Core 3.1 reaches EOL in December 2022. End of support + dates for .NET are published + [here](https://dotnet.microsoft.com/download/dotnet). The instrumentation for ASP.NET Core now requires .NET 6 or later. ([#3567](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3567)) diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index d387533a70e..172942a1d5f 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -2,7 +2,12 @@ ## Unreleased -* Dropped `netstandard2.0` target and added `net6.0` +* Dropped `netstandard2.0` target and added `net6.0`. .NET 5 reached EOL + in May 2022 and .NET Core 3.1 reaches EOL in December 2022. End of support + dates for .NET are published + [here](https://dotnet.microsoft.com/download/dotnet). + The instrumentation for HttpClient now requires .NET 6 or later. + This does not affect applications targeting .NET Framework. ([#3664](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3664)) * Added overloads which accept a name to the `TracerProviderBuilder` From f45206ba0e9f2251807c3173b9085d7c588205f0 Mon Sep 17 00:00:00 2001 From: Omar Boukli-Hacene Date: Mon, 19 Sep 2022 21:08:15 +0200 Subject: [PATCH 25/34] Fix ConsoleActivityExporter output alignment (#3674) --- .../ConsoleActivityExporter.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleActivityExporter.cs b/src/OpenTelemetry.Exporter.Console/ConsoleActivityExporter.cs index 9c08ce59f27..5594efc16b4 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleActivityExporter.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleActivityExporter.cs @@ -32,24 +32,24 @@ public override ExportResult Export(in Batch batch) { foreach (var activity in batch) { - this.WriteLine($"Activity.TraceId: {activity.TraceId}"); - this.WriteLine($"Activity.SpanId: {activity.SpanId}"); - this.WriteLine($"Activity.TraceFlags: {activity.ActivityTraceFlags}"); + this.WriteLine($"Activity.TraceId: {activity.TraceId}"); + this.WriteLine($"Activity.SpanId: {activity.SpanId}"); + this.WriteLine($"Activity.TraceFlags: {activity.ActivityTraceFlags}"); if (!string.IsNullOrEmpty(activity.TraceStateString)) { - this.WriteLine($"Activity.TraceState: {activity.TraceStateString}"); + this.WriteLine($"Activity.TraceState: {activity.TraceStateString}"); } if (activity.ParentSpanId != default) { - this.WriteLine($"Activity.ParentSpanId: {activity.ParentSpanId}"); + this.WriteLine($"Activity.ParentSpanId: {activity.ParentSpanId}"); } this.WriteLine($"Activity.ActivitySourceName: {activity.Source.Name}"); - this.WriteLine($"Activity.DisplayName: {activity.DisplayName}"); - this.WriteLine($"Activity.Kind: {activity.Kind}"); - this.WriteLine($"Activity.StartTime: {activity.StartTimeUtc:yyyy-MM-ddTHH:mm:ss.fffffffZ}"); - this.WriteLine($"Activity.Duration: {activity.Duration}"); + this.WriteLine($"Activity.DisplayName: {activity.DisplayName}"); + this.WriteLine($"Activity.Kind: {activity.Kind}"); + this.WriteLine($"Activity.StartTime: {activity.StartTimeUtc:yyyy-MM-ddTHH:mm:ss.fffffffZ}"); + this.WriteLine($"Activity.Duration: {activity.Duration}"); var statusCode = string.Empty; var statusDesc = string.Empty; @@ -79,18 +79,18 @@ public override ExportResult Export(in Batch batch) if (activity.Status != ActivityStatusCode.Unset) { - this.WriteLine($"StatusCode : {activity.Status}"); + this.WriteLine($"StatusCode: {activity.Status}"); if (!string.IsNullOrEmpty(activity.StatusDescription)) { - this.WriteLine($"Activity.StatusDescription : {activity.StatusDescription}"); + this.WriteLine($"Activity.StatusDescription: {activity.StatusDescription}"); } } else if (!string.IsNullOrEmpty(statusCode)) { - this.WriteLine($" StatusCode : {statusCode}"); + this.WriteLine($" StatusCode: {statusCode}"); if (!string.IsNullOrEmpty(statusDesc)) { - this.WriteLine($" Activity.StatusDescription : {statusDesc}"); + this.WriteLine($" Activity.StatusDescription: {statusDesc}"); } } From a6bdf63be766b68bc2ad81479c7163644db3f5cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Sep 2022 18:09:30 -0700 Subject: [PATCH 26/34] Bump codecov/codecov-action from 3.1.0 to 3.1.1 (#3676) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.0 to 3.1.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/master/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3.1.0...v3.1.1) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Cijo Thomas --- .github/workflows/code-coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/code-coverage.yml b/.github/workflows/code-coverage.yml index 978f1bd9be8..bec49f1128c 100644 --- a/.github/workflows/code-coverage.yml +++ b/.github/workflows/code-coverage.yml @@ -54,7 +54,7 @@ jobs: - name: Merging test results run: reportgenerator -reports:TestResults/**/*.xml -targetdir:TestResults -reporttypes:Cobertura -assemblyFilters:"-microsoft.data.sqlclient*;-grpc.core*;-opentracing*" - - uses: codecov/codecov-action@v3.1.0 + - uses: codecov/codecov-action@v3.1.1 with: file: TestResults/Cobertura.xml env_vars: OS From 988a27be05a7945d887cb69fceac5abdb9b01844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 20 Sep 2022 09:40:58 +0200 Subject: [PATCH 27/34] exportor -> exporter (#3678) --- src/OpenTelemetry/Metrics/BaseExportingMetricReader.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry/Metrics/BaseExportingMetricReader.cs b/src/OpenTelemetry/Metrics/BaseExportingMetricReader.cs index 647025fd719..c9b6346d517 100644 --- a/src/OpenTelemetry/Metrics/BaseExportingMetricReader.cs +++ b/src/OpenTelemetry/Metrics/BaseExportingMetricReader.cs @@ -44,8 +44,8 @@ public BaseExportingMetricReader(BaseExporter exporter) this.exporter = exporter; - var exportorType = exporter.GetType(); - var attributes = exportorType.GetCustomAttributes(typeof(ExportModesAttribute), true); + var exporterType = exporter.GetType(); + var attributes = exporterType.GetCustomAttributes(typeof(ExportModesAttribute), true); if (attributes.Length > 0) { var attr = (ExportModesAttribute)attributes[attributes.Length - 1]; From 74412f0b1956d7afd62796753a2989314f808e0b Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 21 Sep 2022 11:54:34 -0700 Subject: [PATCH 28/34] [ASP.NET Core] Enable diagnostic source events using explicit names (#3519) --- .../AspNetCoreInstrumentation.cs | 15 ++++++++++++++- .../CHANGELOG.md | 10 +++++++--- .../AspNetCoreInstrumentationBenchmarks.cs | 8 ++++---- .../BasicTests.cs | 6 ++++-- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs index 2f9022782d1..f20f74501bc 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs @@ -14,6 +14,7 @@ // limitations under the License. // using System; +using System.Collections.Generic; using OpenTelemetry.Instrumentation.AspNetCore.Implementation; namespace OpenTelemetry.Instrumentation.AspNetCore @@ -23,11 +24,23 @@ namespace OpenTelemetry.Instrumentation.AspNetCore /// internal class AspNetCoreInstrumentation : IDisposable { + private static readonly HashSet DiagnosticSourceEvents = new() + { + "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start", + "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop", + "Microsoft.AspNetCore.Mvc.BeforeAction", + "Microsoft.AspNetCore.Diagnostics.UnhandledException", + "Microsoft.AspNetCore.Hosting.UnhandledException", + }; + + private readonly Func isEnabled = (eventName, obj1, obj2) + => DiagnosticSourceEvents.Contains(eventName); + private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; public AspNetCoreInstrumentation(HttpInListener httpInListener) { - this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(httpInListener, null); + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(httpInListener, this.isEnabled); this.diagnosticSourceSubscriber.Subscribe(); } diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index 0ff631694a3..dc3c4a2c843 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -2,15 +2,19 @@ ## Unreleased -* Fix issue where when an application has an ExceptionFilter, the exception data - wouldn't be collected. - ([#3475](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3475)) +* Performance improvement (Reduced memory allocation) - Updated DiagnosticSource +event subscription to specific set of events. +([#3519](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3519)) * Added overloads which accept a name to the `TracerProviderBuilder` `AddAspNetCoreInstrumentation` extension to allow for more fine-grained options management ([#3661](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3661)) +* Fix issue where when an application has an ExceptionFilter, the exception data + wouldn't be collected. + ([#3475](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3475)) + ## 1.0.0-rc9.6 Released 2022-Aug-18 diff --git a/test/Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs b/test/Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs index b6b31f7dbfd..f3602de5611 100644 --- a/test/Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs +++ b/test/Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs @@ -27,17 +27,17 @@ /* // * Summary * -BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000 +BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22621 Intel Core i7-8850H CPU 2.60GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores .NET SDK=7.0.100-preview.6.22275.1 - [Host] : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT + [Host] : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT Job=InProcess Toolchain=InProcessEmitToolchain | Method | Mean | Error | StdDev | Gen 0 | Allocated | |-------------------------------------------- |---------:|--------:|--------:|-------:|----------:| -| UninstrumentedAspNetCoreApp | 155.6 us | 2.63 us | 2.33 us | 0.9766 | 5 KB | -| InstrumentedAspNetCoreAppWithDefaultOptions | 176.8 us | 3.24 us | 2.70 us | 1.2207 | 7 KB | +| UninstrumentedAspNetCoreApp | 164.7 us | 1.66 us | 1.39 us | 0.9766 | 5 KB | +| InstrumentedAspNetCoreAppWithDefaultOptions | 178.7 us | 2.65 us | 2.35 us | 0.9766 | 5 KB | */ namespace Benchmarks.Instrumentation diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs index 022e3d6398f..4093da8cdc9 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs @@ -695,7 +695,7 @@ public async Task ShouldExportActivityWithOneOrMoreExceptionFilters(int mode) AssertException(exportedItems); } - [Fact(Skip = "Pending Changes https://github.com/open-telemetry/opentelemetry-dotnet/issues/3495")] + [Fact] public async Task DiagnosticSourceCustomCallbacksAreReceivedOnlyForSubscribedEvents() { int numberOfCustomCallbacks = 0; @@ -772,7 +772,7 @@ void ConfigureTestServices(IServiceCollection services) Assert.Equal(1, numberOfExceptionCallbacks); } - [Fact(Skip = "Pending Changes https://github.com/open-telemetry/opentelemetry-dotnet/issues/3495")] + [Fact] public async Task DiagnosticSourceExceptionCallBackIsNotReceivedForExceptionsHandledInMiddleware() { int numberOfExceptionCallbacks = 0; @@ -823,6 +823,8 @@ static void ThrowException(IApplicationBuilder app) } Assert.Equal(0, numberOfExceptionCallbacks); + + await app.DisposeAsync(); } public void Dispose() From 3158d38bbd64031fe6db58906af22d12c4f2c346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 22 Sep 2022 17:40:04 +0200 Subject: [PATCH 29/34] [Exporter.Prometheus] Execute all tests in all supported frameworks (#3680) --- OpenTelemetry.sln | 6 --- ...etry.Exporter.Prometheus.AspNetCore.csproj | 1 + src/OpenTelemetry/AssemblyInfo.cs | 2 +- ...xporter.Prometheus.AspNetCore.Tests.csproj | 7 ++++ .../EventSourceTest.cs | 0 ...orter.Prometheus.HttpListener.Tests.csproj | 5 ++- .../PrometheusCollectionManagerTests.cs | 8 ++-- ...enerMeterProviderBuilderExtensionsTests.cs | 2 +- .../PrometheusSerializerTests.cs | 0 ...Telemetry.Exporter.Prometheus.Tests.csproj | 37 ------------------- 10 files changed, 18 insertions(+), 50 deletions(-) rename test/{OpenTelemetry.Exporter.Prometheus.Tests => OpenTelemetry.Exporter.Prometheus.HttpListener.Tests}/EventSourceTest.cs (100%) rename test/{OpenTelemetry.Exporter.Prometheus.Tests => OpenTelemetry.Exporter.Prometheus.HttpListener.Tests}/PrometheusCollectionManagerTests.cs (97%) rename test/{OpenTelemetry.Exporter.Prometheus.Tests => OpenTelemetry.Exporter.Prometheus.HttpListener.Tests}/PrometheusSerializerTests.cs (100%) delete mode 100644 test/OpenTelemetry.Exporter.Prometheus.Tests/OpenTelemetry.Exporter.Prometheus.Tests.csproj diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index 2a249e1e878..d72c5c82c4d 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -244,8 +244,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Tests.Stress. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApp.AspNetCore", "test\TestApp.AspNetCore\TestApp.AspNetCore.csproj", "{5FDAF679-DE5A-4C73-A49B-8ABCF2399229}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus.Tests", "test\OpenTelemetry.Exporter.Prometheus.Tests\OpenTelemetry.Exporter.Prometheus.Tests.csproj", "{48509CA5-5CCA-42A5-9B77-3FDA63885C0A}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -508,10 +506,6 @@ Global {5FDAF679-DE5A-4C73-A49B-8ABCF2399229}.Debug|Any CPU.Build.0 = Debug|Any CPU {5FDAF679-DE5A-4C73-A49B-8ABCF2399229}.Release|Any CPU.ActiveCfg = Release|Any CPU {5FDAF679-DE5A-4C73-A49B-8ABCF2399229}.Release|Any CPU.Build.0 = Release|Any CPU - {48509CA5-5CCA-42A5-9B77-3FDA63885C0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {48509CA5-5CCA-42A5-9B77-3FDA63885C0A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {48509CA5-5CCA-42A5-9B77-3FDA63885C0A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {48509CA5-5CCA-42A5-9B77-3FDA63885C0A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/OpenTelemetry.Exporter.Prometheus.AspNetCore.csproj b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/OpenTelemetry.Exporter.Prometheus.AspNetCore.csproj index 6fcd3effcf7..4e599da5c2b 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/OpenTelemetry.Exporter.Prometheus.AspNetCore.csproj +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/OpenTelemetry.Exporter.Prometheus.AspNetCore.csproj @@ -6,6 +6,7 @@ ASP.NET Core middleware for hosting OpenTelemetry .NET Prometheus Exporter $(PackageTags);prometheus;metrics core- + $(DefineConstants);PROMETHEUS_ASPNETCORE net6.0 + $(DefineConstants);PROMETHEUS_ASPNETCORE @@ -27,6 +28,12 @@ + + + + + + diff --git a/test/OpenTelemetry.Exporter.Prometheus.Tests/EventSourceTest.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/EventSourceTest.cs similarity index 100% rename from test/OpenTelemetry.Exporter.Prometheus.Tests/EventSourceTest.cs rename to test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/EventSourceTest.cs diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj index 5dbca0c573f..dd32d77eab6 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj @@ -2,7 +2,8 @@ Unit test project for Prometheus Exporter HttpListener for OpenTelemetry - net462 + net6.0;net462 + $(DefineConstants);PROMETHEUS_HTTP_LISTENER @@ -22,6 +23,8 @@ + + diff --git a/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusCollectionManagerTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusCollectionManagerTests.cs similarity index 97% rename from test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusCollectionManagerTests.cs rename to test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusCollectionManagerTests.cs index 2100cc6d455..d054241cbe7 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusCollectionManagerTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusCollectionManagerTests.cs @@ -29,8 +29,8 @@ namespace OpenTelemetry.Exporter.Prometheus.Tests { public sealed class PrometheusCollectionManagerTests { -#if NETFRAMEWORK - [Fact(Skip = "Might be flaky. Might be a bug. See: https://github.com/open-telemetry/opentelemetry-dotnet/pull/3618#issuecomment-1232200946")] +#if PROMETHEUS_HTTP_LISTENER + [Fact(Skip = "Might be flaky. Might be a bug. See: https://github.com/open-telemetry/opentelemetry-dotnet/issues/3679")] #else [Fact] #endif @@ -40,9 +40,9 @@ public async Task EnterExitCollectTest() using (var provider = Sdk.CreateMeterProviderBuilder() .AddMeter(meter.Name) -#if NETFRAMEWORK +#if PROMETHEUS_HTTP_LISTENER .AddPrometheusHttpListener() -#else +#elif PROMETHEUS_ASPNETCORE .AddPrometheusExporter() #endif .Build()) diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerMeterProviderBuilderExtensionsTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerMeterProviderBuilderExtensionsTests.cs index eb7832b4856..72cffdc54db 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerMeterProviderBuilderExtensionsTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerMeterProviderBuilderExtensionsTests.cs @@ -18,7 +18,7 @@ using OpenTelemetry.Metrics; using Xunit; -namespace OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests; +namespace OpenTelemetry.Exporter.Prometheus.Tests; public sealed class PrometheusHttpListenerMeterProviderBuilderExtensionsTests { diff --git a/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusSerializerTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusSerializerTests.cs similarity index 100% rename from test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusSerializerTests.cs rename to test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusSerializerTests.cs diff --git a/test/OpenTelemetry.Exporter.Prometheus.Tests/OpenTelemetry.Exporter.Prometheus.Tests.csproj b/test/OpenTelemetry.Exporter.Prometheus.Tests/OpenTelemetry.Exporter.Prometheus.Tests.csproj deleted file mode 100644 index 2062a3530e3..00000000000 --- a/test/OpenTelemetry.Exporter.Prometheus.Tests/OpenTelemetry.Exporter.Prometheus.Tests.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - Unit test project for common Prometheus Exporter components for OpenTelemetry - - net6.0;net462 - - - - - - - - all - runtime; build; native; contentfiles; analyzers - - - - - - - - - - - - - - - - - - - - - - - From 84762870ddb18405d07a6cbf6a256fe831434c23 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 22 Sep 2022 10:16:06 -0700 Subject: [PATCH 30/34] Update aspnetcore benchmark results (#3688) --- build/Common.nonprod.props | 2 +- .../AspNetCoreInstrumentationBenchmarks.cs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 5bde15718a9..f4635d8e840 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -30,7 +30,7 @@ Please sort alphabetically. Refer to https://docs.microsoft.com/nuget/concepts/package-versioning for semver syntax. --> - [0.13.1,0.14) + [0.13.2,0.14) [2.3.0,3.0) [2.3.1,3.0) [3.19.4,4.0) diff --git a/test/Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs b/test/Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs index f3602de5611..fb295ec2f7b 100644 --- a/test/Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs +++ b/test/Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs @@ -27,17 +27,17 @@ /* // * Summary * -BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22621 +BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.521) Intel Core i7-8850H CPU 2.60GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores .NET SDK=7.0.100-preview.6.22275.1 - [Host] : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT + [Host] : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT AVX2 Job=InProcess Toolchain=InProcessEmitToolchain -| Method | Mean | Error | StdDev | Gen 0 | Allocated | +| Method | Mean | Error | StdDev | Gen0 | Allocated | |-------------------------------------------- |---------:|--------:|--------:|-------:|----------:| -| UninstrumentedAspNetCoreApp | 164.7 us | 1.66 us | 1.39 us | 0.9766 | 5 KB | -| InstrumentedAspNetCoreAppWithDefaultOptions | 178.7 us | 2.65 us | 2.35 us | 0.9766 | 5 KB | +| UninstrumentedAspNetCoreApp | 172.3 us | 2.35 us | 2.09 us | 0.9766 | 4.73 KB | +| InstrumentedAspNetCoreAppWithDefaultOptions | 175.2 us | 2.52 us | 2.10 us | 0.9766 | 4.86 KB | */ namespace Benchmarks.Instrumentation From ed0450ef0ef5178cb29cb8908c3ff120a053caad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Sep 2022 13:50:15 -0700 Subject: [PATCH 31/34] Bump actions/stale from 5 to 6 (#3692) Bumps [actions/stale](https://github.com/actions/stale) from 5 to 6. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/stale dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 93351d06e7f..7143dcc9420 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -10,7 +10,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v5 + - uses: actions/stale@v6 with: stale-pr-message: 'This PR was marked stale due to lack of activity and will be closed in 7 days. Commenting or Pushing will instruct the bot to automatically remove the label. This bot runs once per day.' close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' From 8800b2ffdbdc013390e54a0994288111f3e95a54 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 26 Sep 2022 12:22:41 -0700 Subject: [PATCH 32/34] Move all diagnostic source events to a single callback method `OnEventWritten` (#3691) --- .../Implementation/HttpInListener.cs | 118 ++++++++++++------ .../Implementation/HttpInMetricsListener.cs | 101 ++++++++------- .../GrpcClientDiagnosticListener.cs | 26 +++- .../HttpHandlerDiagnosticListener.cs | 35 +++++- .../HttpHandlerMetricsDiagnosticListener.cs | 40 +++--- .../SqlClientDiagnosticListener.cs | 3 +- .../DiagnosticSourceListener.cs | 17 +-- .../ListenerHandler.cs | 30 +---- .../BasicTests.cs | 105 +++++++++------- .../DiagnosticSourceListenerTest.cs | 36 ------ .../Instrumentation/TestListenerHandler.cs | 53 -------- 11 files changed, 272 insertions(+), 292 deletions(-) delete mode 100644 test/OpenTelemetry.Tests/Instrumentation/DiagnosticSourceListenerTest.cs delete mode 100644 test/OpenTelemetry.Tests/Instrumentation/TestListenerHandler.cs diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs index 1fc8e50516b..e8a214203b3 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs @@ -32,16 +32,25 @@ namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation internal class HttpInListener : ListenerHandler { internal const string ActivityOperationName = "Microsoft.AspNetCore.Hosting.HttpRequestIn"; + internal const string OnStartEvent = "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start"; + internal const string OnStopEvent = "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop"; + internal const string OnMvcBeforeActionEvent = "Microsoft.AspNetCore.Mvc.BeforeAction"; + internal const string OnUnhandledHostingExceptionEvent = "Microsoft.AspNetCore.Hosting.UnhandledException"; + internal const string OnUnHandledDiagnosticsExceptionEvent = "Microsoft.AspNetCore.Diagnostics.UnhandledException"; + #if NET7_0_OR_GREATER // https://github.com/dotnet/aspnetcore/blob/8d6554e655b64da75b71e0e20d6db54a3ba8d2fb/src/Hosting/Hosting/src/GenericHost/GenericWebHostBuilder.cs#L85 internal static readonly string AspNetCoreActivitySourceName = "Microsoft.AspNetCore"; #endif + internal static readonly AssemblyName AssemblyName = typeof(HttpInListener).Assembly.GetName(); internal static readonly string ActivitySourceName = AssemblyName.Name; internal static readonly Version Version = AssemblyName.Version; internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); + private const string DiagnosticSourceName = "Microsoft.AspNetCore"; private const string UnknownHostName = "UNKNOWN-HOST"; + private static readonly Func> HttpRequestHeaderValuesGetter = (request, name) => request.Headers[name]; private readonly PropertyFetcher stopExceptionFetcher = new("Exception"); private readonly AspNetCoreInstrumentationOptions options; @@ -54,8 +63,40 @@ public HttpInListener(AspNetCoreInstrumentationOptions options) this.options = options; } + public override void OnEventWritten(string name, object payload) + { + switch (name) + { + case OnStartEvent: + { + this.OnStartActivity(Activity.Current, payload); + } + + break; + case OnStopEvent: + { + this.OnStopActivity(Activity.Current, payload); + } + + break; + case OnMvcBeforeActionEvent: + { + this.OnMvcBeforeAction(Activity.Current, payload); + } + + break; + case OnUnhandledHostingExceptionEvent: + case OnUnHandledDiagnosticsExceptionEvent: + { + this.OnException(Activity.Current, payload); + } + + break; + } + } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The objects should not be disposed.")] - public override void OnStartActivity(Activity activity, object payload) + public void OnStartActivity(Activity activity, object payload) { // The overall flow of what AspNetCore library does is as below: // Activity.Start() @@ -179,7 +220,7 @@ public override void OnStartActivity(Activity activity, object payload) } } - public override void OnStopActivity(Activity activity, object payload) + public void OnStopActivity(Activity activity, object payload) { if (activity.IsAllDataRequested) { @@ -239,55 +280,52 @@ public override void OnStopActivity(Activity activity, object payload) } } - public override void OnCustom(string name, Activity activity, object payload) + public void OnMvcBeforeAction(Activity activity, object payload) { - if (name == "Microsoft.AspNetCore.Mvc.BeforeAction") + // We cannot rely on Activity.Current here + // There could be activities started by middleware + // after activity started by framework resulting in different Activity.Current. + // so, we need to first find the activity started by Asp.Net Core. + // For .net6.0 onwards we could use IHttpActivityFeature to get the activity created by framework + // var httpActivityFeature = context.Features.Get(); + // activity = httpActivityFeature.Activity; + // However, this will not work as in case of custom propagator + // we start a new activity during onStart event which is a sibling to the activity created by framework + // So, in that case we need to get the activity created by us here. + // we can do so only by looping through activity.Parent chain. + while (activity != null) { - // We cannot rely on Activity.Current here - // There could be activities started by middleware - // after activity started by framework resulting in different Activity.Current. - // so, we need to first find the activity started by Asp.Net Core. - // For .net6.0 onwards we could use IHttpActivityFeature to get the activity created by framework - // var httpActivityFeature = context.Features.Get(); - // activity = httpActivityFeature.Activity; - // However, this will not work as in case of custom propagator - // we start a new activity during onStart event which is a sibling to the activity created by framework - // So, in that case we need to get the activity created by us here. - // we can do so only by looping through activity.Parent chain. - while (activity != null) + if (string.Equals(activity.OperationName, ActivityOperationName, StringComparison.Ordinal)) { - if (string.Equals(activity.OperationName, ActivityOperationName, StringComparison.Ordinal)) - { - break; - } - - activity = activity.Parent; + break; } - if (activity == null) - { - return; - } + activity = activity.Parent; + } - if (activity.IsAllDataRequested) - { - var beforeActionEventData = payload as BeforeActionEventData; - var template = beforeActionEventData.ActionDescriptor?.AttributeRouteInfo?.Template; - if (!string.IsNullOrEmpty(template)) - { - // override the span name that was previously set to the path part of URL. - activity.DisplayName = template; - activity.SetTag(SemanticConventions.AttributeHttpRoute, template); - } + if (activity == null) + { + return; + } - // TODO: Should we get values from RouteData? - // private readonly PropertyFetcher beforeActionRouteDataFetcher = new PropertyFetcher("routeData"); - // var routeData = this.beforeActionRouteDataFetcher.Fetch(payload) as RouteData; + if (activity.IsAllDataRequested) + { + var beforeActionEventData = payload as BeforeActionEventData; + var template = beforeActionEventData.ActionDescriptor?.AttributeRouteInfo?.Template; + if (!string.IsNullOrEmpty(template)) + { + // override the span name that was previously set to the path part of URL. + activity.DisplayName = template; + activity.SetTag(SemanticConventions.AttributeHttpRoute, template); } + + // TODO: Should we get values from RouteData? + // private readonly PropertyFetcher beforeActionRouteDataFetcher = new PropertyFetcher("routeData"); + // var routeData = this.beforeActionRouteDataFetcher.Fetch(payload) as RouteData; } } - public override void OnException(Activity activity, object payload) + public void OnException(Activity activity, object payload) { if (activity.IsAllDataRequested) { diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs index 6c3a150e3a3..5bcae334616 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs @@ -24,6 +24,8 @@ namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation { internal class HttpInMetricsListener : ListenerHandler { + private const string OnStopEvent = "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop"; + private readonly Meter meter; private readonly Histogram httpServerDuration; @@ -34,65 +36,68 @@ public HttpInMetricsListener(string name, Meter meter) this.httpServerDuration = meter.CreateHistogram("http.server.duration", "ms", "measures the duration of the inbound HTTP request"); } - public override void OnStopActivity(Activity activity, object payload) + public override void OnEventWritten(string name, object payload) { - HttpContext context = payload as HttpContext; - if (context == null) + if (name == OnStopEvent) { - AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInMetricsListener), nameof(this.OnStopActivity)); - return; - } + HttpContext context = payload as HttpContext; + if (context == null) + { + AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInMetricsListener), nameof(this.OnEventWritten)); + return; + } - // TODO: Prometheus pulls metrics by invoking the /metrics endpoint. Decide if it makes sense to suppress this. - // Below is just a temporary way of achieving this suppression for metrics (we should consider suppressing traces too). - // If we want to suppress activity from Prometheus then we should use SuppressInstrumentationScope. - if (context.Request.Path.HasValue && context.Request.Path.Value.Contains("metrics")) - { - return; - } + // TODO: Prometheus pulls metrics by invoking the /metrics endpoint. Decide if it makes sense to suppress this. + // Below is just a temporary way of achieving this suppression for metrics (we should consider suppressing traces too). + // If we want to suppress activity from Prometheus then we should use SuppressInstrumentationScope. + if (context.Request.Path.HasValue && context.Request.Path.Value.Contains("metrics")) + { + return; + } - string host; + string host; - if (context.Request.Host.Port is null or 80 or 443) - { - host = context.Request.Host.Host; - } - else - { - host = context.Request.Host.Host + ":" + context.Request.Host.Port; - } + if (context.Request.Host.Port is null or 80 or 443) + { + host = context.Request.Host.Host; + } + else + { + host = context.Request.Host.Host + ":" + context.Request.Host.Port; + } - TagList tags; + TagList tags; - var target = (context.GetEndpoint() as RouteEndpoint)?.RoutePattern.RawText; + var target = (context.GetEndpoint() as RouteEndpoint)?.RoutePattern.RawText; - // TODO: This is just a minimal set of attributes. See the spec for additional attributes: - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#http-server - if (!string.IsNullOrEmpty(target)) - { - tags = new TagList + // TODO: This is just a minimal set of attributes. See the spec for additional attributes: + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#http-server + if (!string.IsNullOrEmpty(target)) { - { SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocol(context.Request.Protocol) }, - { SemanticConventions.AttributeHttpScheme, context.Request.Scheme }, - { SemanticConventions.AttributeHttpMethod, context.Request.Method }, - { SemanticConventions.AttributeHttpHost, host }, - { SemanticConventions.AttributeHttpTarget, target }, - { SemanticConventions.AttributeHttpStatusCode, context.Response.StatusCode.ToString() }, - }; - } - else - { - tags = new TagList + tags = new TagList + { + { SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocol(context.Request.Protocol) }, + { SemanticConventions.AttributeHttpScheme, context.Request.Scheme }, + { SemanticConventions.AttributeHttpMethod, context.Request.Method }, + { SemanticConventions.AttributeHttpHost, host }, + { SemanticConventions.AttributeHttpTarget, target }, + { SemanticConventions.AttributeHttpStatusCode, context.Response.StatusCode.ToString() }, + }; + } + else { - { SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocol(context.Request.Protocol) }, - { SemanticConventions.AttributeHttpScheme, context.Request.Scheme }, - { SemanticConventions.AttributeHttpMethod, context.Request.Method }, - { SemanticConventions.AttributeHttpHost, host }, - { SemanticConventions.AttributeHttpStatusCode, context.Response.StatusCode.ToString() }, - }; - } + tags = new TagList + { + { SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocol(context.Request.Protocol) }, + { SemanticConventions.AttributeHttpScheme, context.Request.Scheme }, + { SemanticConventions.AttributeHttpMethod, context.Request.Method }, + { SemanticConventions.AttributeHttpHost, host }, + { SemanticConventions.AttributeHttpStatusCode, context.Response.StatusCode.ToString() }, + }; + } - this.httpServerDuration.Record(activity.Duration.TotalMilliseconds, tags); + this.httpServerDuration.Record(Activity.Current.Duration.TotalMilliseconds, tags); + } } } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs index 79b7c691020..299d9ff9f8e 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs @@ -31,6 +31,9 @@ internal sealed class GrpcClientDiagnosticListener : ListenerHandler internal static readonly Version Version = AssemblyName.Version; internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); + private const string OnStartEvent = "Grpc.Net.Client.GrpcOut.Start"; + private const string OnStopEvent = "Grpc.Net.Client.GrpcOut.Stop"; + private readonly GrpcClientInstrumentationOptions options; private readonly PropertyFetcher startRequestFetcher = new("Request"); private readonly PropertyFetcher stopRequestFetcher = new("Response"); @@ -41,7 +44,26 @@ public GrpcClientDiagnosticListener(GrpcClientInstrumentationOptions options) this.options = options; } - public override void OnStartActivity(Activity activity, object payload) + public override void OnEventWritten(string name, object payload) + { + switch (name) + { + case OnStartEvent: + { + this.OnStartActivity(Activity.Current, payload); + } + + break; + case OnStopEvent: + { + this.OnStopActivity(Activity.Current, payload); + } + + break; + } + } + + public void OnStartActivity(Activity activity, object payload) { // The overall flow of what GrpcClient library does is as below: // Activity.Start() @@ -137,7 +159,7 @@ public override void OnStartActivity(Activity activity, object payload) } } - public override void OnStopActivity(Activity activity, object payload) + public void OnStopActivity(Activity activity, object payload) { if (activity.IsAllDataRequested) { diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs index 6e0f982b034..2b1e741906d 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs @@ -35,6 +35,10 @@ internal sealed class HttpHandlerDiagnosticListener : ListenerHandler internal static readonly Version Version = AssemblyName.Version; internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); + private const string OnStartEvent = "System.Net.Http.HttpRequestOut.Start"; + private const string OnStopEvent = "System.Net.Http.HttpRequestOut.Stop"; + private const string OnUnhandledExceptionEvent = "System.Net.Http.Exception"; + private readonly PropertyFetcher startRequestFetcher = new("Request"); private readonly PropertyFetcher stopResponseFetcher = new("Response"); private readonly PropertyFetcher stopExceptionFetcher = new("Exception"); @@ -59,7 +63,32 @@ public HttpHandlerDiagnosticListener(HttpClientInstrumentationOptions options) this.options = options; } - public override void OnStartActivity(Activity activity, object payload) + public override void OnEventWritten(string name, object payload) + { + switch (name) + { + case OnStartEvent: + { + this.OnStartActivity(Activity.Current, payload); + } + + break; + case OnStopEvent: + { + this.OnStopActivity(Activity.Current, payload); + } + + break; + case OnUnhandledExceptionEvent: + { + this.OnException(Activity.Current, payload); + } + + break; + } + } + + public void OnStartActivity(Activity activity, object payload) { // The overall flow of what HttpClient library does is as below: // Activity.Start() @@ -148,7 +177,7 @@ public override void OnStartActivity(Activity activity, object payload) } } - public override void OnStopActivity(Activity activity, object payload) + public void OnStopActivity(Activity activity, object payload) { // For .NET7.0 or higher versions, activity is created using activity source // However, the framework will fallback to creating activity if the sampler's decision is to drop and there is a active diagnostic listener. @@ -206,7 +235,7 @@ public override void OnStopActivity(Activity activity, object payload) } } - public override void OnException(Activity activity, object payload) + public void OnException(Activity activity, object payload) { // For .NET7.0 or higher versions, activity is created using activity source // However, the framework will fallback to creating activity if the sampler's decision is to drop and there is a active diagnostic listener. diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs index 0c2d8691466..2e8234f00db 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs @@ -24,6 +24,8 @@ namespace OpenTelemetry.Instrumentation.Http.Implementation { internal class HttpHandlerMetricsDiagnosticListener : ListenerHandler { + internal const string OnStopEvent = "System.Net.Http.HttpRequestOut.Stop"; + private readonly PropertyFetcher stopResponseFetcher = new("Response"); private readonly Histogram httpClientDuration; @@ -33,28 +35,32 @@ public HttpHandlerMetricsDiagnosticListener(string name, Meter meter) this.httpClientDuration = meter.CreateHistogram("http.client.duration", "ms", "measures the duration of the outbound HTTP request"); } - public override void OnStopActivity(Activity activity, object payload) + public override void OnEventWritten(string name, object payload) { - if (Sdk.SuppressInstrumentation) - { - return; - } - - if (this.stopResponseFetcher.TryFetch(payload, out HttpResponseMessage response) && response != null) + if (name == OnStopEvent) { - var request = response.RequestMessage; + if (Sdk.SuppressInstrumentation) + { + return; + } - // TODO: This is just a minimal set of attributes. See the spec for additional attributes: - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#http-client - var tags = new KeyValuePair[] + var activity = Activity.Current; + if (this.stopResponseFetcher.TryFetch(payload, out HttpResponseMessage response) && response != null) { - new KeyValuePair(SemanticConventions.AttributeHttpMethod, HttpTagHelper.GetNameForHttpMethod(request.Method)), - new KeyValuePair(SemanticConventions.AttributeHttpScheme, request.RequestUri.Scheme), - new KeyValuePair(SemanticConventions.AttributeHttpStatusCode, (int)response.StatusCode), - new KeyValuePair(SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.Version)), - }; + var request = response.RequestMessage; + + // TODO: This is just a minimal set of attributes. See the spec for additional attributes: + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#http-client + var tags = new KeyValuePair[] + { + new KeyValuePair(SemanticConventions.AttributeHttpMethod, HttpTagHelper.GetNameForHttpMethod(request.Method)), + new KeyValuePair(SemanticConventions.AttributeHttpScheme, request.RequestUri.Scheme), + new KeyValuePair(SemanticConventions.AttributeHttpStatusCode, (int)response.StatusCode), + new KeyValuePair(SemanticConventions.AttributeHttpFlavor, HttpTagHelper.GetFlavorTagValueFromProtocolVersion(request.Version)), + }; - this.httpClientDuration.Record(activity.Duration.TotalMilliseconds, tags); + this.httpClientDuration.Record(activity.Duration.TotalMilliseconds, tags); + } } } } diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs index 151a4080548..4f360bcbf18 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs @@ -49,8 +49,9 @@ public SqlClientDiagnosticListener(string sourceName, SqlClientInstrumentationOp public override bool SupportsNullActivity => true; - public override void OnCustom(string name, Activity activity, object payload) + public override void OnEventWritten(string name, object payload) { + var activity = Activity.Current; switch (name) { case SqlDataBeforeExecuteCommand: diff --git a/src/OpenTelemetry/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs b/src/OpenTelemetry/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs index 812fc572ced..43a78008272 100644 --- a/src/OpenTelemetry/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs +++ b/src/OpenTelemetry/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs @@ -49,22 +49,7 @@ public void OnNext(KeyValuePair value) try { - if (value.Key.EndsWith("Start", StringComparison.Ordinal)) - { - this.handler.OnStartActivity(Activity.Current, value.Value); - } - else if (value.Key.EndsWith("Stop", StringComparison.Ordinal)) - { - this.handler.OnStopActivity(Activity.Current, value.Value); - } - else if (value.Key.EndsWith("Exception", StringComparison.Ordinal)) - { - this.handler.OnException(Activity.Current, value.Value); - } - else - { - this.handler.OnCustom(value.Key, Activity.Current, value.Value); - } + this.handler.OnEventWritten(value.Key, value.Value); } catch (Exception ex) { diff --git a/src/OpenTelemetry/DiagnosticSourceInstrumentation/ListenerHandler.cs b/src/OpenTelemetry/DiagnosticSourceInstrumentation/ListenerHandler.cs index 66ae48e0cab..2c1678715b1 100644 --- a/src/OpenTelemetry/DiagnosticSourceInstrumentation/ListenerHandler.cs +++ b/src/OpenTelemetry/DiagnosticSourceInstrumentation/ListenerHandler.cs @@ -41,40 +41,12 @@ public ListenerHandler(string sourceName) /// public virtual bool SupportsNullActivity { get; } - /// - /// Method called for an event with the suffix 'Start'. - /// - /// The to be started. - /// An object that represent the value being passed as a payload for the event. - public virtual void OnStartActivity(Activity activity, object payload) - { - } - - /// - /// Method called for an event with the suffix 'Stop'. - /// - /// The to be stopped. - /// An object that represent the value being passed as a payload for the event. - public virtual void OnStopActivity(Activity activity, object payload) - { - } - - /// - /// Method called for an event with the suffix 'Exception'. - /// - /// The . - /// An object that represent the value being passed as a payload for the event. - public virtual void OnException(Activity activity, object payload) - { - } - /// /// Method called for an event which does not have 'Start', 'Stop' or 'Exception' as suffix. /// /// Custom name. - /// The to be processed. /// An object that represent the value being passed as a payload for the event. - public virtual void OnCustom(string name, Activity activity, object payload) + public virtual void OnEventWritten(string name, object payload) { } } diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs index 4093da8cdc9..2ce0e7989c7 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs @@ -466,14 +466,24 @@ void ConfigureTestServices(IServiceCollection services) .AddAspNetCoreInstrumentation(new AspNetCoreInstrumentation( new TestHttpInListener(new AspNetCoreInstrumentationOptions()) { - OnStartActivityCallback = (activity, payload) => + OnEventWrittenCallback = (name, payload) => { - baggageCountAfterStart = Baggage.Current.Count; - }, - OnStopActivityCallback = (activity, payload) => - { - baggageCountAfterStop = Baggage.Current.Count; - stopSignal.Set(); + switch (name) + { + case HttpInListener.OnStartEvent: + { + baggageCountAfterStart = Baggage.Current.Count; + } + + break; + case HttpInListener.OnStopEvent: + { + baggageCountAfterStop = Baggage.Current.Count; + stopSignal.Set(); + } + + break; + } }, })) .Build(); @@ -625,7 +635,7 @@ public async Task ActivitiesStartedInMiddlewareBySettingHostActivityToNullShould Assert.Equal(activityName, middlewareActivity.OperationName); Assert.Equal(activityName, middlewareActivity.DisplayName); - // tag http.route should not be added on activity started by asp.net core as it will not be found during oncustom event + // tag http.route should not be added on activity started by asp.net core as it will not be found during OnEventWritten event Assert.DoesNotContain(aspnetcoreframeworkactivity.TagObjects, t => t.Key == SemanticConventions.AttributeHttpRoute); Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", aspnetcoreframeworkactivity.OperationName); Assert.Equal("/api/values/2", aspnetcoreframeworkactivity.DisplayName); @@ -707,10 +717,18 @@ void ConfigureTestServices(IServiceCollection services) .AddAspNetCoreInstrumentation(new AspNetCoreInstrumentation( new TestHttpInListener(new AspNetCoreInstrumentationOptions()) { - OnCustomCallback = (name, activity, payload) => + OnEventWrittenCallback = (name, payload) => { - actualCustomEventName = name; - numberOfCustomCallbacks++; + switch (name) + { + case HttpInListener.OnMvcBeforeActionEvent: + { + actualCustomEventName = name; + numberOfCustomCallbacks++; + } + + break; + } }, })) .Build(); @@ -742,9 +760,20 @@ void ConfigureTestServices(IServiceCollection services) .AddAspNetCoreInstrumentation(new AspNetCoreInstrumentation( new TestHttpInListener(new AspNetCoreInstrumentationOptions()) { - OnExceptionCallback = (activity, payload) => + OnEventWrittenCallback = (name, payload) => { - numberOfExceptionCallbacks++; + switch (name) + { + // TODO: Add test case for validating name for both the types + // of exception event. + case HttpInListener.OnUnhandledHostingExceptionEvent: + case HttpInListener.OnUnHandledDiagnosticsExceptionEvent: + { + numberOfExceptionCallbacks++; + } + + break; + } }, })) .Build(); @@ -782,9 +811,18 @@ public async Task DiagnosticSourceExceptionCallBackIsNotReceivedForExceptionsHan .AddAspNetCoreInstrumentation(new AspNetCoreInstrumentation( new TestHttpInListener(new AspNetCoreInstrumentationOptions()) { - OnExceptionCallback = (activity, payload) => + OnEventWrittenCallback = (name, payload) => { - numberOfExceptionCallbacks++; + switch (name) + { + case HttpInListener.OnUnhandledHostingExceptionEvent: + case HttpInListener.OnUnHandledDiagnosticsExceptionEvent: + { + numberOfExceptionCallbacks++; + } + + break; + } }, })) .Build(); @@ -954,45 +992,18 @@ public override SamplingResult ShouldSample(in SamplingParameters samplingParame private class TestHttpInListener : HttpInListener { - public Action OnStartActivityCallback; - - public Action OnStopActivityCallback; - - public Action OnExceptionCallback; - - public Action OnCustomCallback; + public Action OnEventWrittenCallback; public TestHttpInListener(AspNetCoreInstrumentationOptions options) : base(options) { } - public override void OnStartActivity(Activity activity, object payload) - { - base.OnStartActivity(activity, payload); - - this.OnStartActivityCallback?.Invoke(activity, payload); - } - - public override void OnStopActivity(Activity activity, object payload) - { - base.OnStopActivity(activity, payload); - - this.OnStopActivityCallback?.Invoke(activity, payload); - } - - public override void OnCustom(string name, Activity activity, object payload) - { - base.OnCustom(name, activity, payload); - - this.OnCustomCallback?.Invoke(name, activity, payload); - } - - public override void OnException(Activity activity, object payload) + public override void OnEventWritten(string name, object payload) { - base.OnException(activity, payload); + base.OnEventWritten(name, payload); - this.OnExceptionCallback?.Invoke(activity, payload); + this.OnEventWrittenCallback?.Invoke(name, payload); } } @@ -1013,7 +1024,7 @@ public override void PreProcess(HttpContext context) // Setting the host activity i.e. activity started by asp.net core // to null here will have no impact on middleware activity. // This also means that asp.net core activity will not be found - // during OnCustom event. + // during OnEventWritten event. Activity.Current = null; this.activity = this.activitySource.StartActivity(this.activityName); } diff --git a/test/OpenTelemetry.Tests/Instrumentation/DiagnosticSourceListenerTest.cs b/test/OpenTelemetry.Tests/Instrumentation/DiagnosticSourceListenerTest.cs deleted file mode 100644 index 7e9b6fc2de7..00000000000 --- a/test/OpenTelemetry.Tests/Instrumentation/DiagnosticSourceListenerTest.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// 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.Instrumentation.Tests -{ - public class DiagnosticSourceListenerTest - { - private const string TestSourceName = "TestSourceName"; - private readonly DiagnosticSource diagnosticSource; - private readonly TestListenerHandler testListenerHandler; - private readonly DiagnosticSourceSubscriber testDiagnosticSourceSubscriber; - - public DiagnosticSourceListenerTest() - { - this.diagnosticSource = new DiagnosticListener(TestSourceName); - this.testListenerHandler = new TestListenerHandler(TestSourceName); - this.testDiagnosticSourceSubscriber = new DiagnosticSourceSubscriber(this.testListenerHandler, null); - this.testDiagnosticSourceSubscriber.Subscribe(); - } - } -} diff --git a/test/OpenTelemetry.Tests/Instrumentation/TestListenerHandler.cs b/test/OpenTelemetry.Tests/Instrumentation/TestListenerHandler.cs deleted file mode 100644 index 81cb2f4b053..00000000000 --- a/test/OpenTelemetry.Tests/Instrumentation/TestListenerHandler.cs +++ /dev/null @@ -1,53 +0,0 @@ -// -// 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.Instrumentation.Tests -{ - internal class TestListenerHandler : ListenerHandler - { - public int OnStartInvokedCount = 0; - public int OnStopInvokedCount = 0; - public int OnExceptionInvokedCount = 0; - public int OnCustomInvokedCount = 0; - - public TestListenerHandler(string sourceName) - : base(sourceName) - { - } - - public override void OnStartActivity(Activity activity, object payload) - { - this.OnStartInvokedCount++; - } - - public override void OnStopActivity(Activity activity, object payload) - { - this.OnStopInvokedCount++; - } - - public override void OnException(Activity activity, object payload) - { - this.OnExceptionInvokedCount++; - } - - public override void OnCustom(string name, Activity activity, object payload) - { - this.OnCustomInvokedCount++; - } - } -} From 86ee906dcd02c562e85814ca07f2a1a15a83dc98 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 27 Sep 2022 10:34:30 -0700 Subject: [PATCH 33/34] Update Diagnostic Source to rc version (#3698) --- build/Common.props | 2 +- src/OpenTelemetry.Api/CHANGELOG.md | 3 +++ .../OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/build/Common.props b/build/Common.props index 03ac93b08fb..8a5640bef03 100644 --- a/build/Common.props +++ b/build/Common.props @@ -42,7 +42,7 @@ [2.8.0,3.0) [1.2.0-beta.435,2.0) 1.4.0 - 7.0.0-preview.7.22375.6 + 7.0.0-rc.1.22426.10 4.7.0 4.7.0 4.5.3 diff --git a/src/OpenTelemetry.Api/CHANGELOG.md b/src/OpenTelemetry.Api/CHANGELOG.md index 307b1cbbb90..99bade8a2a9 100644 --- a/src/OpenTelemetry.Api/CHANGELOG.md +++ b/src/OpenTelemetry.Api/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated to System.Diagnostics.DiagnosticSource version `7.0.0-rc.1.22426.10`. +([#3698](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3698)) + ## 1.4.0-alpha.2 Released 2022-Aug-18 diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj index f406c0b7518..183657025bd 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj @@ -29,7 +29,7 @@ - + From d10f1f945dc9afd5cb233e7bf9f47befb714db54 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 27 Sep 2022 14:51:41 -0700 Subject: [PATCH 34/34] Unit test to validate spans in http redirect (#3699) --- .../HttpClientTests.Basic.cs | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs index 3b49cac0348..3272e8f5c63 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs @@ -39,7 +39,16 @@ public HttpClientTests() this.serverLifeTime = TestHttpServer.RunServer( (ctx) => { - ctx.Response.StatusCode = 200; + if (ctx.Request.Url.PathAndQuery.Contains("redirect")) + { + ctx.Response.RedirectLocation = "/"; + ctx.Response.StatusCode = 302; + } + else + { + ctx.Response.StatusCode = 200; + } + ctx.Response.OutputStream.Close(); }, out var host, @@ -317,6 +326,28 @@ public async Task HttpClientInstrumentationBacksOffIfAlreadyInstrumented() Assert.Equal(4, processor.Invocations.Count); // SetParentProvider/OnShutdown/Dispose/OnStart called. } + [Fact] + public async Task HttpClientRedirectTest() + { + var processor = new Mock>(); + using (Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation() + .AddProcessor(processor.Object) + .Build()) + { + using var c = new HttpClient(); + await c.GetAsync($"{this.url}redirect"); + } + + Assert.Equal(7, processor.Invocations.Count); // SetParentProvider/OnStart/OnEnd/OnStart/OnEnd/OnShutdown/Dispose called. + + var firstActivity = (Activity)processor.Invocations[2].Arguments[0]; // First OnEnd + Assert.Contains(firstActivity.TagObjects, t => t.Key == "http.status_code" && (int)t.Value == 302); + + var secondActivity = (Activity)processor.Invocations[4].Arguments[0]; // Second OnEnd + Assert.Contains(secondActivity.TagObjects, t => t.Key == "http.status_code" && (int)t.Value == 200); + } + [Fact] public async void RequestNotCollectedWhenInstrumentationFilterApplied() {