From f65b650805da166ae02a5ccbc925a638abf6f682 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Mon, 19 Apr 2021 22:31:28 -0700 Subject: [PATCH] AspNetCore instrumentation options to be configurable from DI (#1997) --- examples/AspNetCore/Startup.cs | 14 +++++++++++ examples/AspNetCore/appsettings.json | 3 +++ .../CHANGELOG.md | 4 ++++ ...elemetry.Instrumentation.AspNetCore.csproj | 1 + .../README.md | 23 +++++++++++++++++++ .../TracerProviderBuilderExtensions.cs | 21 +++++++++++++---- .../Internal/ServiceProviderExtensions.cs | 5 ++-- 7 files changed, 64 insertions(+), 7 deletions(-) diff --git a/examples/AspNetCore/Startup.cs b/examples/AspNetCore/Startup.cs index c2c4a4a817e..625c7c16615 100644 --- a/examples/AspNetCore/Startup.cs +++ b/examples/AspNetCore/Startup.cs @@ -24,6 +24,7 @@ using Microsoft.Extensions.Hosting; using Microsoft.OpenApi.Models; using OpenTelemetry.Exporter; +using OpenTelemetry.Instrumentation.AspNetCore; using OpenTelemetry.Resources; using OpenTelemetry.Trace; @@ -95,6 +96,19 @@ public void ConfigureServices(IServiceCollection services) .AddAspNetCoreInstrumentation() .AddHttpClientInstrumentation() .AddConsoleExporter()); + + // For options which can be bound from IConfiguration. + services.Configure(this.Configuration.GetSection("AspNetCoreInstrumentation")); + + // For options which can be configured from code only. + services.Configure(options => + { + options.Filter = (req) => + { + return req.Request.Host != null; + }; + }); + break; } } diff --git a/examples/AspNetCore/appsettings.json b/examples/AspNetCore/appsettings.json index 3279eec3559..d9e5cf957cc 100644 --- a/examples/AspNetCore/appsettings.json +++ b/examples/AspNetCore/appsettings.json @@ -20,5 +20,8 @@ "Otlp": { "ServiceName": "otlp-test", "Endpoint": "http://localhost:4317" + }, + "AspNetCoreInstrumentation": { + "RecordException": "true" } } diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index 1eb669d13e3..46cf43e7411 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* When using OpenTelemetry.Extensions.Hosting you can now bind + `AspNetCoreInstrumentationOptions` from DI. + ([#1997](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1997)) + ## 1.0.0-rc3 Released 2021-Mar-19 diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj index ccc20812aab..2f127aa0863 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj @@ -9,6 +9,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md index 0a078229bec..60a70cce8d6 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md @@ -57,6 +57,29 @@ This instrumentation can be configured to change the default behavior by using `AspNetCoreInstrumentationOptions`, which allows adding [`Filter`](#filter), [`Enrich`](#enrich) as explained below. +// TODO: This section could be refined. +When used with [`OpenTelemetry.Extensions.Hosting`](../OpenTelemetry.Extensions.Hosting/README.md), +all configurations to `AspNetCoreInstrumentationOptions` can be done in the `ConfigureServices` +method of you applications `Startup` class as shown below. + +```csharp +// Configure +services.Configure(options => + { + options.Filter = (req) => + { + // only collect telemetry about HTTP GET requests + return httpContext.Request.Method.Equals("GET"); + }; + }); + +services.AddOpenTelemetryTracing( + (builder) => builder + .AddAspNetCoreInstrumentation() + .AddJaegerExporter() + ); +``` + ### Filter This instrumentation by default collects all the incoming http requests. It diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs index 6ae19062faa..faba8be5714 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/TracerProviderBuilderExtensions.cs @@ -40,14 +40,25 @@ public static TracerProviderBuilder AddAspNetCoreInstrumentation( throw new ArgumentNullException(nameof(builder)); } - var aspnetCoreOptions = new AspNetCoreInstrumentationOptions(); - configureAspNetCoreInstrumentationOptions?.Invoke(aspnetCoreOptions); - builder.AddInstrumentation(() => new AspNetCoreInstrumentation(aspnetCoreOptions)); + if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + { + return deferredTracerProviderBuilder.Configure((sp, builder) => + { + AddAspNetCoreInstrumentation(builder, sp.GetOptions(), configureAspNetCoreInstrumentationOptions); + }); + } + + return AddAspNetCoreInstrumentation(builder, new AspNetCoreInstrumentationOptions(), configureAspNetCoreInstrumentationOptions); + } + + private static TracerProviderBuilder AddAspNetCoreInstrumentation(TracerProviderBuilder builder, AspNetCoreInstrumentationOptions options, Action configure = null) + { + configure?.Invoke(options); + var instrumentation = new AspNetCoreInstrumentation(options); builder.AddSource(HttpInListener.ActivitySourceName); builder.AddLegacySource(HttpInListener.ActivityOperationName); // for the activities created by AspNetCore builder.AddLegacySource(HttpInListener.ActivityNameByHttpInListener); // for the sibling activities created by the instrumentation library - - return builder; + return builder.AddInstrumentation(() => instrumentation); } } } diff --git a/src/OpenTelemetry/Internal/ServiceProviderExtensions.cs b/src/OpenTelemetry/Internal/ServiceProviderExtensions.cs index d6c53d4ae66..ff899cc3fe8 100644 --- a/src/OpenTelemetry/Internal/ServiceProviderExtensions.cs +++ b/src/OpenTelemetry/Internal/ServiceProviderExtensions.cs @@ -14,7 +14,8 @@ // limitations under the License. // -#if NET461 || NETSTANDARD2_0 +#if NET461 || NETSTANDARD2_0 || NETSTANDARD2_1 +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; #endif @@ -34,7 +35,7 @@ internal static class ServiceProviderExtensions public static T GetOptions(this IServiceProvider serviceProvider) where T : class, new() { -#if NET461 || NETSTANDARD2_0 +#if NET461 || NETSTANDARD2_0 || NETSTANDARD2_1 IOptions options = (IOptions)serviceProvider.GetService(typeof(IOptions)); // Note: options could be null if user never invoked services.AddOptions().