Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ internal class HttpInListener : ListenerHandler
internal static readonly ActivitySource ActivitySource = ActivitySourceFactory.Create<HttpInListener>(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";

Expand Down Expand Up @@ -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)
{
Expand All @@ -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);
}

Expand Down Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,10 @@ public EndToEndTests(WebApplicationFactory<Program> 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
{
Expand All @@ -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"));

Expand All @@ -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);
}
}

Expand Down
Loading