From 48a425f28cc33f761628ae4ccb6c4598704ec64a Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 6 Oct 2023 20:36:55 -0700 Subject: [PATCH 01/17] Add support for .NET8.0 specific metrics --- .../Implementation/HttpInMetricsListener.cs | 2 ++ .../MeterProviderBuilderExtensions.cs | 22 +++++++++++++++- src/Shared/SemanticConventions.cs | 1 + .../DependencyInjectionConfigTests.cs | 2 ++ .../MetricTests.cs | 26 ++++++++++--------- 5 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs index 9a8b35040c6..6cce4432df3 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs @@ -32,6 +32,7 @@ internal sealed class HttpInMetricsListener : ListenerHandler private const string OnStopEvent = "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop"; private const string EventName = "OnStopActivity"; + private const string NetworkProtocolName = "http"; private readonly Meter meter; private readonly AspNetCoreMetricsInstrumentationOptions options; @@ -184,6 +185,7 @@ public void OnEventWritten_New(string name, object payload) TagList tags = default; // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/http/http-spans.md + tags.Add(new KeyValuePair(SemanticConventions.AttributeNetworkProtocolName, NetworkProtocolName)); tags.Add(new KeyValuePair(SemanticConventions.AttributeNetworkProtocolVersion, HttpTagHelper.GetFlavorTagValueFromProtocol(context.Request.Protocol))); tags.Add(new KeyValuePair(SemanticConventions.AttributeUrlScheme, context.Request.Scheme)); tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpRequestMethod, context.Request.Method)); diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs index 99330ac220a..9ffa29cf893 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs @@ -14,10 +14,14 @@ // limitations under the License. // +#if !NET8_0_OR_GREATER using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.AspNetCore; using OpenTelemetry.Instrumentation.AspNetCore.Implementation; +using OpenTelemetry.Internal; +#endif + using OpenTelemetry.Internal; namespace OpenTelemetry.Metrics; @@ -34,8 +38,23 @@ public static class MeterProviderBuilderExtensions /// The instance of to chain the calls. public static MeterProviderBuilder AddAspNetCoreInstrumentation( this MeterProviderBuilder builder) - => AddAspNetCoreInstrumentation(builder, name: null, configureAspNetCoreInstrumentationOptions: null); + { + Guard.ThrowIfNull(builder); + +#if !NET8_0_OR_GREATER + return AddAspNetCoreInstrumentation(builder, name: null, configureAspNetCoreInstrumentationOptions: null); +#else + return builder + .AddMeter("Microsoft.AspNetCore.Hosting") + .AddMeter("Microsoft.AspNetCore.Server.Kestrel") + .AddMeter("Microsoft.AspNetCore.Http.Connections") + .AddMeter("Microsoft.AspNetCore.Routing") + .AddMeter("Microsoft.AspNetCore.Diagnostics") + .AddMeter("Microsoft.AspNetCore.RateLimiting"); +#endif + } +#if !NET8_0_OR_GREATER /// /// Enables the incoming requests automatic data collection for ASP.NET Core. /// @@ -91,4 +110,5 @@ public static MeterProviderBuilder AddAspNetCoreInstrumentation( return builder; } +#endif } diff --git a/src/Shared/SemanticConventions.cs b/src/Shared/SemanticConventions.cs index 3f0ce13a20b..d48f7d6bca1 100644 --- a/src/Shared/SemanticConventions.cs +++ b/src/Shared/SemanticConventions.cs @@ -120,6 +120,7 @@ internal static class SemanticConventions public const string AttributeHttpRequestMethod = "http.request.method"; // replaces: "http.method" (AttributeHttpMethod) public const string AttributeHttpResponseStatusCode = "http.response.status_code"; // replaces: "http.status_code" (AttributeHttpStatusCode) public const string AttributeNetworkProtocolVersion = "network.protocol.version"; // replaces: "http.flavor" (AttributeHttpFlavor) + public const string AttributeNetworkProtocolName = "network.protocol.name"; public const string AttributeServerAddress = "server.address"; // replaces: "net.host.name" (AttributeNetHostName) and "net.peer.name" (AttributeNetPeerName) public const string AttributeServerPort = "server.port"; // replaces: "net.host.port" (AttributeNetHostPort) and "net.peer.port" (AttributeNetPeerPort) public const string AttributeServerSocketAddress = "server.socket.address"; // replaces: "net.peer.ip" (AttributeNetPeerIp) diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs index 86e31d863ed..0d9acad0ca9 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs @@ -65,6 +65,7 @@ void ConfigureTestServices(IServiceCollection services) Assert.True(optionsPickedFromDI); } +#if !NET8_0_OR_GREATER [Theory] [InlineData(null)] [InlineData("CustomName")] @@ -95,4 +96,5 @@ void ConfigureTestServices(IServiceCollection services) Assert.True(optionsPickedFromDI); } +#endif } diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs index 8b179278a49..67c3110425c 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs @@ -51,10 +51,10 @@ public void AddAspNetCoreInstrumentation_BadArgs() } [Fact] - public async Task RequestMetricIsCaptured_Old() + public async Task RequestMetricIsCaptured_New() { var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary { [SemanticConventionOptInKeyName] = null }) + .AddInMemoryCollection(new Dictionary { [SemanticConventionOptInKeyName] = "http" }) .Build(); var metricItems = new List(); @@ -87,25 +87,27 @@ public async Task RequestMetricIsCaptured_Old() this.meterProvider.Dispose(); var requestMetrics = metricItems - .Where(item => item.Name == "http.server.duration") + .Where(item => item.Name == "http.server.request.duration") .ToArray(); var metric = Assert.Single(requestMetrics); - Assert.Equal("ms", metric.Unit); + + Assert.Equal("s", metric.Unit); var metricPoints = GetMetricPoints(metric); Assert.Equal(2, metricPoints.Count); - AssertMetricPoints_Old( + AssertMetricPoints_New( metricPoints: metricPoints, expectedRoutes: new List { "api/Values", "api/Values/{id}" }, expectedTagsCount: 6); } +#if !NET8_0_OR_GREATER [Fact] - public async Task RequestMetricIsCaptured_New() + public async Task RequestMetricIsCaptured_Old() { var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary { [SemanticConventionOptInKeyName] = "http" }) + .AddInMemoryCollection(new Dictionary { [SemanticConventionOptInKeyName] = null }) .Build(); var metricItems = new List(); @@ -138,19 +140,18 @@ public async Task RequestMetricIsCaptured_New() this.meterProvider.Dispose(); var requestMetrics = metricItems - .Where(item => item.Name == "http.server.request.duration") + .Where(item => item.Name == "http.server.duration") .ToArray(); var metric = Assert.Single(requestMetrics); - - Assert.Equal("s", metric.Unit); + Assert.Equal("ms", metric.Unit); var metricPoints = GetMetricPoints(metric); Assert.Equal(2, metricPoints.Count); - AssertMetricPoints_New( + AssertMetricPoints_Old( metricPoints: metricPoints, expectedRoutes: new List { "api/Values", "api/Values/{id}" }, - expectedTagsCount: 5); + expectedTagsCount: 6); } [Fact] @@ -323,6 +324,7 @@ void ConfigureTestServices(IServiceCollection services) Assert.Contains(tagsToAdd[0], tags); Assert.Contains(tagsToAdd[1], tags); } +#endif public void Dispose() { From 2c5afab537b615acd18b2b4ef8bbe968f3064e98 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 9 Oct 2023 09:30:55 -0700 Subject: [PATCH 02/17] fix build --- .../.publicApi/net8.0/PublicAPI.Unshipped.txt | 10 ---------- .../AspNetCoreMetrics.cs | 2 ++ .../AspNetCoreMetricsInstrumentationOptions.cs | 2 ++ .../Implementation/HttpInMetricsListener.cs | 2 ++ .../MeterProviderBuilderExtensions.cs | 4 ++-- 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net8.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net8.0/PublicAPI.Unshipped.txt index 88cc5073da4..b3b24c45be9 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net8.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net8.0/PublicAPI.Unshipped.txt @@ -12,19 +12,9 @@ OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreInstrumentationOptions.Filter OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreInstrumentationOptions.RecordException.set -> void -OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions -OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.AspNetCoreMetricEnrichmentFunc -OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.AspNetCoreMetricsInstrumentationOptions() -> void -OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.Enrich.get -> OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.AspNetCoreMetricEnrichmentFunc -OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.Filter.get -> System.Func -OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.Filter.set -> void OpenTelemetry.Metrics.MeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureAspNetCoreInstrumentationOptions) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configureAspNetCoreInstrumentationOptions) -> OpenTelemetry.Metrics.MeterProviderBuilder 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 -virtual OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.AspNetCoreMetricEnrichmentFunc.Invoke(string name, Microsoft.AspNetCore.Http.HttpContext context, ref System.Diagnostics.TagList tags) -> void diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs index 6c527187d91..64fb588a208 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs @@ -14,6 +14,7 @@ // limitations under the License. // +#if !NET8_0_OR_GREATER using System.Diagnostics.Metrics; using System.Reflection; using OpenTelemetry.Instrumentation.AspNetCore.Implementation; @@ -59,3 +60,4 @@ public void Dispose() this.meter?.Dispose(); } } +#endif diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetricsInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetricsInstrumentationOptions.cs index e61558d5b8b..f0bbf599ba7 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetricsInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetricsInstrumentationOptions.cs @@ -14,6 +14,7 @@ // limitations under the License. // +#if !NET8_0_OR_GREATER using System.Diagnostics; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; @@ -76,3 +77,4 @@ internal AspNetCoreMetricsInstrumentationOptions(IConfiguration configuration) /// public AspNetCoreMetricEnrichmentFunc Enrich { get; set; } } +#endif diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs index 6cce4432df3..db7fa2a5272 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs @@ -14,6 +14,7 @@ // limitations under the License. // +#if !NET8_0_OR_GREATER using System.Diagnostics; using System.Diagnostics.Metrics; using Microsoft.AspNetCore.Http; @@ -216,3 +217,4 @@ public void OnEventWritten_New(string name, object payload) this.httpServerRequestDuration.Record(Activity.Current.Duration.TotalSeconds, tags); } } +#endif diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs index 9ffa29cf893..4722b5f17be 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs @@ -20,9 +20,9 @@ using OpenTelemetry.Instrumentation.AspNetCore; using OpenTelemetry.Instrumentation.AspNetCore.Implementation; using OpenTelemetry.Internal; -#endif - +#else using OpenTelemetry.Internal; +#endif namespace OpenTelemetry.Metrics; From e9d2292a8f9a049be9c60dc362c44174de709b1c Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 9 Oct 2023 09:44:03 -0700 Subject: [PATCH 03/17] fix test --- .../MetricTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs index 67c3110425c..085c6ecb797 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs @@ -219,7 +219,7 @@ public async Task RequestMetricIsCaptured_Dup() AssertMetricPoints_New( metricPoints: metricPoints, expectedRoutes: new List { "api/Values", "api/Values/{id}" }, - expectedTagsCount: 5); + expectedTagsCount: 6); } [Fact] From 85bb4cf8e7fd97b8142f7b19b247039693da0ec7 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 9 Oct 2023 09:55:23 -0700 Subject: [PATCH 04/17] fix build --- .../MetricTests.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs index 085c6ecb797..d1840fba024 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs @@ -14,11 +14,17 @@ // limitations under the License. // +#if !NET8_0_OR_GREATER using System.Diagnostics; +#endif using Microsoft.AspNetCore.Hosting; +#if !NET8_0_OR_GREATER using Microsoft.AspNetCore.Http; +#endif using Microsoft.AspNetCore.Mvc.Testing; +#if !NET8_0_OR_GREATER using Microsoft.AspNetCore.TestHost; +#endif using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; From 10b9a75e7503f6aec4d8325a720956e86d09419e Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 9 Oct 2023 13:53:37 -0700 Subject: [PATCH 05/17] revert api changes --- .../.publicApi/net8.0/PublicAPI.Unshipped.txt | 10 ++++++++ ...AspNetCoreMetricsInstrumentationOptions.cs | 3 +-- .../MeterProviderBuilderExtensions.cs | 25 +++++++++++++------ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net8.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net8.0/PublicAPI.Unshipped.txt index b3b24c45be9..88cc5073da4 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net8.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/net8.0/PublicAPI.Unshipped.txt @@ -12,9 +12,19 @@ OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreInstrumentationOptions.Filter OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreInstrumentationOptions.RecordException.set -> void +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.AspNetCoreMetricEnrichmentFunc +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.AspNetCoreMetricsInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.Enrich.get -> OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.AspNetCoreMetricEnrichmentFunc +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.Filter.get -> System.Func +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.Filter.set -> void OpenTelemetry.Metrics.MeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configureAspNetCoreInstrumentationOptions) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configureAspNetCoreInstrumentationOptions) -> OpenTelemetry.Metrics.MeterProviderBuilder 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 +virtual OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.AspNetCoreMetricEnrichmentFunc.Invoke(string name, Microsoft.AspNetCore.Http.HttpContext context, ref System.Diagnostics.TagList tags) -> void diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetricsInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetricsInstrumentationOptions.cs index f0bbf599ba7..0710a9e4fe9 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetricsInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetricsInstrumentationOptions.cs @@ -14,7 +14,6 @@ // limitations under the License. // -#if !NET8_0_OR_GREATER using System.Diagnostics; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; @@ -77,4 +76,4 @@ internal AspNetCoreMetricsInstrumentationOptions(IConfiguration configuration) /// public AspNetCoreMetricEnrichmentFunc Enrich { get; set; } } -#endif + diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs index 4722b5f17be..3051cf94b63 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs @@ -17,12 +17,12 @@ #if !NET8_0_OR_GREATER using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +#endif using OpenTelemetry.Instrumentation.AspNetCore; +#if !NET8_0_OR_GREATER using OpenTelemetry.Instrumentation.AspNetCore.Implementation; -using OpenTelemetry.Internal; -#else -using OpenTelemetry.Internal; #endif +using OpenTelemetry.Internal; namespace OpenTelemetry.Metrics; @@ -41,9 +41,7 @@ public static MeterProviderBuilder AddAspNetCoreInstrumentation( { Guard.ThrowIfNull(builder); -#if !NET8_0_OR_GREATER - return AddAspNetCoreInstrumentation(builder, name: null, configureAspNetCoreInstrumentationOptions: null); -#else +#if NET8_0_OR_GREATER return builder .AddMeter("Microsoft.AspNetCore.Hosting") .AddMeter("Microsoft.AspNetCore.Server.Kestrel") @@ -51,10 +49,11 @@ public static MeterProviderBuilder AddAspNetCoreInstrumentation( .AddMeter("Microsoft.AspNetCore.Routing") .AddMeter("Microsoft.AspNetCore.Diagnostics") .AddMeter("Microsoft.AspNetCore.RateLimiting"); +#else + return AddAspNetCoreInstrumentation(builder, name: null, configureAspNetCoreInstrumentationOptions: null); #endif } -#if !NET8_0_OR_GREATER /// /// Enables the incoming requests automatic data collection for ASP.NET Core. /// @@ -80,6 +79,16 @@ public static MeterProviderBuilder AddAspNetCoreInstrumentation( { Guard.ThrowIfNull(builder); +#if NET8_0_OR_GREATER + return builder + .AddMeter("Microsoft.AspNetCore.Hosting") + .AddMeter("Microsoft.AspNetCore.Server.Kestrel") + .AddMeter("Microsoft.AspNetCore.Http.Connections") + .AddMeter("Microsoft.AspNetCore.Routing") + .AddMeter("Microsoft.AspNetCore.Diagnostics") + .AddMeter("Microsoft.AspNetCore.RateLimiting"); +#else + // Note: Warm-up the status code mapping. _ = TelemetryHelper.BoxedStatusCodes; @@ -109,6 +118,6 @@ public static MeterProviderBuilder AddAspNetCoreInstrumentation( }); return builder; - } #endif + } } From d48b7980a0b1064f7f16bcf50ba1066b55f3f43a Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 9 Oct 2023 15:29:26 -0700 Subject: [PATCH 06/17] add simple test --- .../MetricTests.cs | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs index d1840fba024..6a8034ce7a0 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs @@ -17,6 +17,9 @@ #if !NET8_0_OR_GREATER using System.Diagnostics; #endif +#if NET8_0_OR_GREATER +using Microsoft.AspNetCore.Builder; +#endif using Microsoft.AspNetCore.Hosting; #if !NET8_0_OR_GREATER using Microsoft.AspNetCore.Http; @@ -56,6 +59,67 @@ public void AddAspNetCoreInstrumentation_BadArgs() Assert.Throws(() => builder.AddAspNetCoreInstrumentation()); } +#if NET8_0_OR_GREATER + [Fact] + public async Task ValidateNet8MetricsAsync() + { + var metricItems = new List(); + + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(metricItems) + .Build(); + + var builder = WebApplication.CreateBuilder(); + builder.Logging.ClearProviders(); + var app = builder.Build(); + + app.MapGet("/", () => "Hello"); + + _ = app.RunAsync(); + + using var client = new HttpClient(); + var res = await client.GetStringAsync("http://localhost:5000/").ConfigureAwait(false); + Assert.NotNull(res); + + this.meterProvider.Dispose(); + + var requestDurationMetric = metricItems + .Where(item => item.Name == "http.server.request.duration") + .ToArray(); + + var activeRequestsMetric = metricItems. + Where(item => item.Name == "http.server.active_requests") + .ToArray(); + + var routeMatchingMetric = metricItems. + Where(item => item.Name == "aspnetcore.routing.match_attempts") + .ToArray(); + + var kestrelActiveConnectionsMetric = metricItems. + Where(item => item.Name == "kestrel.active_connections") + .ToArray(); + var kestrelQueuedConnectionMetric = metricItems. + Where(item => item.Name == "kestrel.queued_connections") + .ToArray(); + + Assert.Single(requestDurationMetric); + Assert.Single(activeRequestsMetric); + Assert.Single(routeMatchingMetric); + Assert.Single(kestrelActiveConnectionsMetric); + Assert.Single(kestrelQueuedConnectionMetric); + + // TODO + // kestrel.queued_requests + // kestrel.upgraded_connections + // kestrel.rejected_connections + // kestrel.tls_handshake.duration + // kestrel.active_tls_handshakes + + await app.DisposeAsync(); + } +#endif + [Fact] public async Task RequestMetricIsCaptured_New() { From 067b84a09d59796e6c762c523a2ab44a2a1fff6b Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 10 Oct 2023 08:45:49 -0700 Subject: [PATCH 07/17] Add more tests --- .../MetricTests.cs | 67 ++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs index 6a8034ce7a0..57fb30e1adb 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs @@ -18,13 +18,15 @@ using System.Diagnostics; #endif #if NET8_0_OR_GREATER +using System.Threading.RateLimiting; using Microsoft.AspNetCore.Builder; #endif using Microsoft.AspNetCore.Hosting; -#if !NET8_0_OR_GREATER using Microsoft.AspNetCore.Http; -#endif using Microsoft.AspNetCore.Mvc.Testing; +#if NET8_0_OR_GREATER +using Microsoft.AspNetCore.RateLimiting; +#endif #if !NET8_0_OR_GREATER using Microsoft.AspNetCore.TestHost; #endif @@ -118,6 +120,67 @@ public async Task ValidateNet8MetricsAsync() await app.DisposeAsync(); } + + [Fact] + public async Task ValidateNet8RateLimitingMetricsAsync() + { + var metricItems = new List(); + + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(metricItems) + .Build(); + + var builder = WebApplication.CreateBuilder(); + builder.Services.AddRateLimiter(_ => _ + .AddFixedWindowLimiter(policyName: "fixed", options => + { + options.PermitLimit = 4; + options.Window = TimeSpan.FromSeconds(12); + options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst; + options.QueueLimit = 2; + })); + + builder.Logging.ClearProviders(); + var app = builder.Build(); + + app.UseRateLimiter(); + + static string GetTicks() => (DateTime.Now.Ticks & 0x11111).ToString("00000"); + + app.MapGet("/", () => Results.Ok($"Hello {GetTicks()}")) + .RequireRateLimiting("fixed"); + + _ = app.RunAsync(); + + using var client = new HttpClient(); + var res = await client.GetStringAsync("http://localhost:5000/").ConfigureAwait(false); + Assert.NotNull(res); + + this.meterProvider.Dispose(); + + var activeRequestleasesMetric = metricItems + .Where(item => item.Name == "aspnetcore.rate_limiting.active_request_leases") + .ToArray(); + + var requestLeaseDurationMetric = metricItems. + Where(item => item.Name == "aspnetcore.rate_limiting.request_lease.duration") + .ToArray(); + + var limitingRequestsMetric = metricItems. + Where(item => item.Name == "aspnetcore.rate_limiting.requests") + .ToArray(); + + Assert.Single(activeRequestleasesMetric); + Assert.Single(requestLeaseDurationMetric); + Assert.Single(limitingRequestsMetric); + + // TODO + // aspnetcore.rate_limiting.request.time_in_queue + // aspnetcore.rate_limiting.queued_requests + + await app.DisposeAsync(); + } #endif [Fact] From 244b43f1a0c044bad31d67ebad280b7a70095a2d Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 10 Oct 2023 08:55:15 -0700 Subject: [PATCH 08/17] changelog --- .../CHANGELOG.md | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index e1439a9c231..edfe0389a10 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -31,6 +31,44 @@ and [metrics](https://github.com/open-telemetry/semantic-conventions/blob/2bad9afad58fbd6b33cc683d1ad1f006e35e4a5d/docs/http/http-metrics.md). +* Following metrics will now be enabled by default when targeting + `.NET8.0` framework. + + * **Meter** : `Microsoft.AspNetCore.Hosting` + * `http.server.request.duration` + * `http.server.active_requests` + + * **Meter** : `Microsoft.AspNetCore.Server.Kestrel` + * `kestrel.active_connections` + * `kestrel.connection.duration` + * `kestrel.rejected_connections` + * `kestrel.queued_connections` + * `kestrel.queued_requests` + * `kestrel.upgraded_connections` + * `kestrel.tls_handshake.duration` + * `kestrel.active_tls_handshakes` + + * **Meter** : `Microsoft.AspNetCore.Http.Connections` + * `signalr.server.connection.duration` + * `signalr.server.active_connections` + + * **Meter** : `Microsoft.AspNetCore.Routing` + * `aspnetcore.routing.match_attempts` + + * **Meter** : `Microsoft.AspNetCore.Diagnostics` + * `aspnetcore.diagnostics.exceptions` + + * **Meter** : `Microsoft.AspNetCore.RateLimiting` + * `aspnetcore.rate_limiting.active_request_leases` + * `aspnetcore.rate_limiting.request_lease.duration` + * `aspnetcore.rate_limiting.queued_requests` + * `aspnetcore.rate_limiting.request.time_in_queue` + * `aspnetcore.rate_limiting.requests` + + **NOTE**: Users can opt-out of metrics that are not required using + [views](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/metrics/customizing-the-sdk#view). + [#4934](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4934) + ## 1.5.1-beta.1 Released 2023-Jul-20 From be073414f0c1f9bbf7eafaae7317b346317fb59a Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 10 Oct 2023 08:58:40 -0700 Subject: [PATCH 09/17] fix space --- src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index edfe0389a10..fbb0799f874 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -33,7 +33,7 @@ * Following metrics will now be enabled by default when targeting `.NET8.0` framework. - + * **Meter** : `Microsoft.AspNetCore.Hosting` * `http.server.request.duration` * `http.server.active_requests` From 98e323deb505151deedca6f45a1d66ef1f96a7dd Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 11 Oct 2023 15:57:08 -0700 Subject: [PATCH 10/17] pr feedback --- .../CHANGELOG.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index fbb0799f874..fd27f698203 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -32,7 +32,7 @@ [metrics](https://github.com/open-telemetry/semantic-conventions/blob/2bad9afad58fbd6b33cc683d1ad1f006e35e4a5d/docs/http/http-metrics.md). * Following metrics will now be enabled by default when targeting - `.NET8.0` framework. + `.NET8.0` or newer framework. * **Meter** : `Microsoft.AspNetCore.Hosting` * `http.server.request.duration` @@ -65,9 +65,16 @@ * `aspnetcore.rate_limiting.request.time_in_queue` * `aspnetcore.rate_limiting.requests` - **NOTE**: Users can opt-out of metrics that are not required using + **NOTE**: `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable for these + metrics is not supported. Users can opt-out of metrics that are not required + using [views](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/metrics/customizing-the-sdk#view). - [#4934](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4934) + ([#4934](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4934)) + +* Added `network.protocol.name` dimension to `http.server.request.duration` +metric. This change only affects users setting `OTEL_SEMCONV_STABILITY_OPT_IN` +to `http` or `http/dup`. +([#4934](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4934)) ## 1.5.1-beta.1 From 2c8928c9cbc0789f3e40dff0d589d265cc6fc6c9 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 18 Oct 2023 10:58:56 -0700 Subject: [PATCH 11/17] address feedback --- .../CHANGELOG.md | 14 ++++++--- .../AspNetCoreInstrumentationEventSource.cs | 6 ++++ .../MeterProviderBuilderExtensions.cs | 30 +++++++++---------- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index fd27f698203..b282adc7cc3 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -65,10 +65,16 @@ * `aspnetcore.rate_limiting.request.time_in_queue` * `aspnetcore.rate_limiting.requests` - **NOTE**: `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable for these - metrics is not supported. Users can opt-out of metrics that are not required - using - [views](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/metrics/customizing-the-sdk#view). + **NOTES**: + * When targeting `.NET8.0` framework, `http.server.request.duration` metric + will only follow + [v1.22.0](https://github.com/open-telemetry/semantic-conventions/blob/v1.22.0/docs/http/http-metrics.md#metric-httpclientrequestduration) + semantic conventions specification. Ability to switch behavior to older + conventions using `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable is + not available. + * Users can opt-out of metrics that are not required using + [views](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/metrics/customizing-the-sdk#drop-an-instrument). + ([#4934](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4934)) * Added `network.protocol.name` dimension to `http.server.request.duration` diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs index 3f67896c167..cb3898d947b 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs @@ -92,4 +92,10 @@ public void UnknownErrorProcessingEvent(string handlerName, string eventName, st { this.WriteEvent(5, handlerName, eventName, ex); } + + [Event(6, Message = "'{0}' is not supported for .NET8.0 and above targets", Level = EventLevel.Verbose)] + public void UnSupportedOption(string optionName) + { + this.WriteEvent(6, optionName); + } } diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs index 3051cf94b63..95015676419 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs @@ -19,9 +19,7 @@ using Microsoft.Extensions.Options; #endif using OpenTelemetry.Instrumentation.AspNetCore; -#if !NET8_0_OR_GREATER using OpenTelemetry.Instrumentation.AspNetCore.Implementation; -#endif using OpenTelemetry.Internal; namespace OpenTelemetry.Metrics; @@ -42,13 +40,7 @@ public static MeterProviderBuilder AddAspNetCoreInstrumentation( Guard.ThrowIfNull(builder); #if NET8_0_OR_GREATER - return builder - .AddMeter("Microsoft.AspNetCore.Hosting") - .AddMeter("Microsoft.AspNetCore.Server.Kestrel") - .AddMeter("Microsoft.AspNetCore.Http.Connections") - .AddMeter("Microsoft.AspNetCore.Routing") - .AddMeter("Microsoft.AspNetCore.Diagnostics") - .AddMeter("Microsoft.AspNetCore.RateLimiting"); + return builder.ConfigureMeters(); #else return AddAspNetCoreInstrumentation(builder, name: null, configureAspNetCoreInstrumentationOptions: null); #endif @@ -80,13 +72,8 @@ public static MeterProviderBuilder AddAspNetCoreInstrumentation( Guard.ThrowIfNull(builder); #if NET8_0_OR_GREATER - return builder - .AddMeter("Microsoft.AspNetCore.Hosting") - .AddMeter("Microsoft.AspNetCore.Server.Kestrel") - .AddMeter("Microsoft.AspNetCore.Http.Connections") - .AddMeter("Microsoft.AspNetCore.Routing") - .AddMeter("Microsoft.AspNetCore.Diagnostics") - .AddMeter("Microsoft.AspNetCore.RateLimiting"); + AspNetCoreInstrumentationEventSource.Log.UnSupportedOption(nameof(AspNetCoreMetricsInstrumentationOptions)); + return builder.ConfigureMeters(); #else // Note: Warm-up the status code mapping. @@ -120,4 +107,15 @@ public static MeterProviderBuilder AddAspNetCoreInstrumentation( return builder; #endif } + + internal static MeterProviderBuilder ConfigureMeters(this MeterProviderBuilder builder) + { + return builder + .AddMeter("Microsoft.AspNetCore.Hosting") + .AddMeter("Microsoft.AspNetCore.Server.Kestrel") + .AddMeter("Microsoft.AspNetCore.Http.Connections") + .AddMeter("Microsoft.AspNetCore.Routing") + .AddMeter("Microsoft.AspNetCore.Diagnostics") + .AddMeter("Microsoft.AspNetCore.RateLimiting"); + } } From f85de21445b30829df953c3a11ffc0882dc6fa9f Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 19 Oct 2023 14:10:09 -0700 Subject: [PATCH 12/17] Update src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> --- .../Implementation/AspNetCoreInstrumentationEventSource.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs index cb3898d947b..ad602a83e6b 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs @@ -94,7 +94,7 @@ public void UnknownErrorProcessingEvent(string handlerName, string eventName, st } [Event(6, Message = "'{0}' is not supported for .NET8.0 and above targets", Level = EventLevel.Verbose)] - public void UnSupportedOption(string optionName) + public void UnsupportedOption(string optionName) { this.WriteEvent(6, optionName); } From 2794531ec73e68ea13c6e23d2b774ae9bdb5faf7 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 19 Oct 2023 14:12:31 -0700 Subject: [PATCH 13/17] Update src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> --- .../MeterProviderBuilderExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs index 95015676419..80c071a2304 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/MeterProviderBuilderExtensions.cs @@ -72,7 +72,7 @@ public static MeterProviderBuilder AddAspNetCoreInstrumentation( Guard.ThrowIfNull(builder); #if NET8_0_OR_GREATER - AspNetCoreInstrumentationEventSource.Log.UnSupportedOption(nameof(AspNetCoreMetricsInstrumentationOptions)); + AspNetCoreInstrumentationEventSource.Log.UnsupportedOption(nameof(AspNetCoreMetricsInstrumentationOptions)); return builder.ConfigureMeters(); #else From 5da07414628fb802c235039a207a9e2ed1159079 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 19 Oct 2023 14:57:13 -0700 Subject: [PATCH 14/17] Update src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs Co-authored-by: Cijo Thomas --- .../Implementation/AspNetCoreInstrumentationEventSource.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs index ad602a83e6b..f8c846cba9f 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs @@ -93,7 +93,7 @@ public void UnknownErrorProcessingEvent(string handlerName, string eventName, st this.WriteEvent(5, handlerName, eventName, ex); } - [Event(6, Message = "'{0}' is not supported for .NET8.0 and above targets", Level = EventLevel.Verbose)] + [Event(6, Message = "'{0}' is not supported for .NET8.0 and above targets", Level = EventLevel.Warning)] public void UnsupportedOption(string optionName) { this.WriteEvent(6, optionName); From d60250ba70e845bd78bee29fed0bf741ff8c97f5 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 19 Oct 2023 15:13:10 -0700 Subject: [PATCH 15/17] test --- .../MetricTests.cs | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs index 57fb30e1adb..1d15fa4d9d2 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs @@ -84,32 +84,33 @@ public async Task ValidateNet8MetricsAsync() var res = await client.GetStringAsync("http://localhost:5000/").ConfigureAwait(false); Assert.NotNull(res); + // We need to let metric callback execute as it is executed AFTER response was returned. + // In unit tests environment there may be a lot of parallel unit tests executed, so + // giving some breezing room for the callbacks to complete + await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false); + this.meterProvider.Dispose(); var requestDurationMetric = metricItems - .Where(item => item.Name == "http.server.request.duration") - .ToArray(); + .Count(item => item.Name == "http.server.request.duration"); var activeRequestsMetric = metricItems. - Where(item => item.Name == "http.server.active_requests") - .ToArray(); + Count(item => item.Name == "http.server.active_requests"); var routeMatchingMetric = metricItems. - Where(item => item.Name == "aspnetcore.routing.match_attempts") - .ToArray(); + Count(item => item.Name == "aspnetcore.routing.match_attempts"); var kestrelActiveConnectionsMetric = metricItems. - Where(item => item.Name == "kestrel.active_connections") - .ToArray(); + Count(item => item.Name == "kestrel.active_connections"); + var kestrelQueuedConnectionMetric = metricItems. - Where(item => item.Name == "kestrel.queued_connections") - .ToArray(); + Count(item => item.Name == "kestrel.queued_connections"); - Assert.Single(requestDurationMetric); - Assert.Single(activeRequestsMetric); - Assert.Single(routeMatchingMetric); - Assert.Single(kestrelActiveConnectionsMetric); - Assert.Single(kestrelQueuedConnectionMetric); + Assert.Equal(1, requestDurationMetric); + Assert.Equal(1, activeRequestsMetric); + Assert.Equal(1, routeMatchingMetric); + Assert.Equal(1, kestrelActiveConnectionsMetric); + Assert.Equal(1, kestrelQueuedConnectionMetric); // TODO // kestrel.queued_requests @@ -157,6 +158,11 @@ public async Task ValidateNet8RateLimitingMetricsAsync() var res = await client.GetStringAsync("http://localhost:5000/").ConfigureAwait(false); Assert.NotNull(res); + // We need to let metric callback execute as it is executed AFTER response was returned. + // In unit tests environment there may be a lot of parallel unit tests executed, so + // giving some breezing room for the callbacks to complete + await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false); + this.meterProvider.Dispose(); var activeRequestleasesMetric = metricItems From 8066515e2f517df44c291d5d70b15314d7518cf9 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 20 Oct 2023 11:30:30 -0700 Subject: [PATCH 16/17] Update src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md Co-authored-by: Cijo Thomas --- src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index b282adc7cc3..cd44bf2237d 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -66,7 +66,7 @@ * `aspnetcore.rate_limiting.requests` **NOTES**: - * When targeting `.NET8.0` framework, `http.server.request.duration` metric + * When targeting `.NET8.0` framework or newer, `http.server.request.duration` metric will only follow [v1.22.0](https://github.com/open-telemetry/semantic-conventions/blob/v1.22.0/docs/http/http-metrics.md#metric-httpclientrequestduration) semantic conventions specification. Ability to switch behavior to older From 3b0e27e2359ff586aaa16d1ca4e1a901499e787e Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 20 Oct 2023 12:27:31 -0700 Subject: [PATCH 17/17] add link to docs for metric details --- src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index cd44bf2237d..10e074b856c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -31,8 +31,8 @@ and [metrics](https://github.com/open-telemetry/semantic-conventions/blob/2bad9afad58fbd6b33cc683d1ad1f006e35e4a5d/docs/http/http-metrics.md). -* Following metrics will now be enabled by default when targeting - `.NET8.0` or newer framework. +* Following metrics will now be enabled by default when targeting `.NET8.0` or + newer framework: * **Meter** : `Microsoft.AspNetCore.Hosting` * `http.server.request.duration` @@ -65,6 +65,10 @@ * `aspnetcore.rate_limiting.request.time_in_queue` * `aspnetcore.rate_limiting.requests` + For details about each individual metric check [ASP.NET Core + docs + page](https://learn.microsoft.com/dotnet/core/diagnostics/built-in-metrics-aspnetcore). + **NOTES**: * When targeting `.NET8.0` framework or newer, `http.server.request.duration` metric will only follow