diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs index 43f461c6a5..c58d22e54d 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs @@ -26,6 +26,7 @@ internal class HttpInListener : ListenerHandler internal static readonly ActivitySource ActivitySource = ActivitySourceFactory.Create(SemanticConventionsVersion); internal static readonly bool Net7OrGreater = Environment.Version.Major >= 7; internal static readonly bool Net10OrGreater = Environment.Version.Major >= 10; + internal static readonly bool Net11OrGreater = Environment.Version.Major >= 11; private const string DiagnosticSourceName = "Microsoft.AspNetCore"; @@ -168,20 +169,18 @@ public void OnStartActivity(Activity activity, object? payload) ActivityInstrumentationHelper.SetKindProperty(activity, ActivityKind.Server); } - // See the spec: https://github.com/open-telemetry/semantic-conventions/blob/v1.40.0/docs/http/http-spans.md - var path = (request.PathBase.HasValue || request.Path.HasValue) ? (request.PathBase + request.Path).ToString() : "/"; - TelemetryHelper.RequestDataHelper.SetActivityDisplayName(activity, request.Method); // ASP.NET Core 10 does not support OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS so we // still need to set the HTTP method tag so that any override by the user is honoured. + // See https://github.com/dotnet/aspnetcore/issues/65873. TelemetryHelper.RequestDataHelper.SetHttpMethodTag(activity, request.Method); if (!Net10OrGreater || !this.nativeAspNetCoreOpenTelemetryEnabled) { if (request.Host.HasValue) { - activity.SetTag(SemanticConventions.AttributeServerAddress, request.Host.Value); + activity.SetTag(SemanticConventions.AttributeServerAddress, request.Host.Host); if (request.Host.Port is { } port) { @@ -199,6 +198,9 @@ public void OnStartActivity(Activity activity, object? payload) } activity.SetTag(SemanticConventions.AttributeUrlScheme, request.Scheme); + + // See the spec: https://github.com/open-telemetry/semantic-conventions/blob/v1.40.0/docs/http/http-spans.md + var path = (request.PathBase.HasValue || request.Path.HasValue) ? (request.PathBase + request.Path).ToString() : "/"; activity.SetTag(SemanticConventions.AttributeUrlPath, path); } @@ -393,27 +395,28 @@ private static void AddGrpcAttributes(Activity activity, string grpcMethod, Http } } - // ASP.NET Core 10 does not generate OpenTelemetry tags by default so we can only take - // the optimal path if the user has explicitly opted-out of suppressing the OpenTelemetry data. private static bool AspNetCoreHasNativeOpenTelemetryTags() { -#if NET10_0_OR_GREATER - if (AppContext.TryGetSwitch("Microsoft.AspNetCore.Hosting.SuppressActivityOpenTelemetryData", out var suppressed)) + bool? suppressed = null; + + // ASP.NET Core 10 added a feature switch to specify whether to suppress OpenTelemetry + // tags being added natively by default, so we can take an optimal path if the user has + // not explicitly opted-out of suppressing the OpenTelemetry data. + if (AppContext.TryGetSwitch("Microsoft.AspNetCore.Hosting.SuppressActivityOpenTelemetryData", out var configuredValue)) { - return !suppressed; + suppressed = configuredValue; } -#endif -#if NET10_0 + + if (suppressed is { } suppressedValue) + { + return !suppressedValue; + } + + // In ASP.NET Core 8 and 9 the feature switch does not exist and there are no native OpenTelemetry tags. // In ASP.NET Core 10 OpenTelemetry tags are suppressed by default, // see https://github.com/dotnet/aspnetcore/blob/7387de91234d3ef751fa50b3d1bfede4130213ff/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L59-L67. - return false; -#elif NET11_0_OR_GREATER // In ASP.NET Core 11+ OpenTelemetry tags are emitted by default, // see https://github.com/dotnet/aspnetcore/blob/655f41d52f2fc75992eac41496b8e9cc119e1b54/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L59-L67. - return true; -#else - // In ASP.NET Core 8 and 9 the feature switch does not exist and there are no native OpenTelemetry tags - return false; -#endif + return Net11OrGreater; } } diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/EndToEndTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/EndToEndTests.cs index 09fc5df6d5..fa9f27640c 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/EndToEndTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/EndToEndTests.cs @@ -30,14 +30,10 @@ public EndToEndTests(WebApplicationFactory factory) [InlineData(true)] public async Task HttpRequestActivityIsCorrectWithFeatureSwitch(bool isEnabled) { - bool? originalValue = null; + const string SwitchName = "Microsoft.AspNetCore.Hosting.SuppressActivityOpenTelemetryData"; - if (AppContext.TryGetSwitch("Microsoft.AspNetCore.Hosting.SuppressActivityOpenTelemetryData", out var existingValue)) - { - originalValue = existingValue; - } - - AppContext.SetSwitch("Microsoft.AspNetCore.Hosting.SuppressActivityOpenTelemetryData", isEnabled); + var wasConfigured = AppContext.TryGetSwitch(SwitchName, out var originalValue); + AppContext.SetSwitch(SwitchName, isEnabled); try { @@ -58,7 +54,7 @@ void ConfigureTestServices(IServiceCollection services) builder.ConfigureTestServices(ConfigureTestServices); builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); }) - .CreateClient(); + .CreateClient(new() { BaseAddress = new Uri("http://localhost:12345") }); client.DefaultRequestHeaders.UserAgent.Add(new("OpenTelemetry.Instrumentation.AspNetCore.Tests", "1.0")); @@ -73,16 +69,15 @@ void ConfigureTestServices(IServiceCollection services) Assert.Equal("GET /ping", activity.DisplayName); Assert.Equal("GET", activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethod)); Assert.Equal("localhost", activity.GetTagValue(SemanticConventions.AttributeServerAddress)); + Assert.Equal(12345, activity.GetTagValue(SemanticConventions.AttributeServerPort)); Assert.Equal("OpenTelemetry.Instrumentation.AspNetCore.Tests/1.0", activity.GetTagValue(SemanticConventions.AttributeUserAgentOriginal)); Assert.Equal("http", activity.GetTagValue(SemanticConventions.AttributeUrlScheme)); Assert.Equal("/ping", activity.GetTagValue(SemanticConventions.AttributeUrlPath)); } finally { - if (originalValue is { } previousValue) - { - AppContext.SetSwitch("Microsoft.AspNetCore.Hosting.SuppressActivityOpenTelemetryData", previousValue); - } + var resetValue = wasConfigured ? originalValue : Environment.Version.Major < 11; + AppContext.SetSwitch(SwitchName, resetValue); } }