diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index 80160ef205..20dc05051a 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* Fixed issue + [#5019](https://github.com/open-telemetry/opentelemetry-dotnet/issues/5019) + where metrics and traces were not exported for incoming requests when using + ASP.NET Core 2.x. + ([#2724](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2724)) + ## 1.11.1 Released 2025-Mar-05 diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs index 5ac36618e3..cfee2b9301 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs @@ -47,6 +47,7 @@ internal class HttpInListener : ListenerHandler }; private static readonly PropertyFetcher ExceptionPropertyFetcher = new("Exception"); + private static readonly PropertyFetcher HttpContextPropertyFetcher = new("HttpContext"); private readonly AspNetCoreTraceInstrumentationOptions options; @@ -102,8 +103,15 @@ public void OnStartActivity(Activity activity, object? payload) if (payload is not HttpContext context) { - AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInListener), nameof(this.OnStartActivity), activity.OperationName); - return; + if (TryFetchHttpContext(payload, out var innerContext)) + { + context = innerContext; + } + else + { + AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInListener), nameof(this.OnStartActivity), activity.OperationName); + return; + } } // Ensure context extraction irrespective of sampling decision @@ -237,8 +245,15 @@ public void OnStopActivity(Activity activity, object? payload) { if (payload is not HttpContext context) { - AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInListener), nameof(this.OnStopActivity), activity.OperationName); - return; + if (TryFetchHttpContext(payload, out var innerContext)) + { + context = innerContext; + } + else + { + AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInListener), nameof(this.OnStopActivity), activity.OperationName); + return; + } } var response = context.Response; @@ -347,6 +362,12 @@ static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception } } +#if NET + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The ASP.NET Core framework guarantees that top level properties are preserved")] +#endif + private static bool TryFetchHttpContext(object? payload, [NotNullWhen(true)] out HttpContext? context) + => HttpContextPropertyFetcher.TryFetch(payload, out context) && context is not null; + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool TryGetGrpcMethod(Activity activity, [NotNullWhen(true)] out string? grpcMethod) { diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs index 551421403a..a53d6c3ff2 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs @@ -65,21 +65,21 @@ static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception { return ExceptionPropertyFetcher.TryFetch(payload, out exc) && exc != null; } -#if NET - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The ASP.NET Core framework guarantees that top level properties are preserved")] -#endif - static bool TryFetchHttpContext(object? payload, [NotNullWhen(true)] out HttpContext? ctx) - { - return HttpContextPropertyFetcher.TryFetch(payload, out ctx) && ctx != null; - } } public static void OnStopEventWritten(string name, object? payload) { if (payload is not HttpContext context) { - AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInMetricsListener), nameof(OnStopEventWritten), HttpServerRequestDurationMetricName); - return; + if (TryFetchHttpContext(payload, out var innerContext)) + { + context = innerContext; + } + else + { + AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInMetricsListener), nameof(OnStopEventWritten), HttpServerRequestDurationMetricName); + return; + } } TagList tags = default; @@ -133,4 +133,10 @@ public override void OnEventWritten(string name, object? payload) break; } } + +#if NET + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The ASP.NET Core framework guarantees that top level properties are preserved")] +#endif + private static bool TryFetchHttpContext(object? payload, [NotNullWhen(true)] out HttpContext? context) + => HttpContextPropertyFetcher.TryFetch(payload, out context) && context is not null; }