Skip to content

Commit fc78c0e

Browse files
committed
fix route attribute logic
1 parent 013686b commit fc78c0e

File tree

2 files changed

+85
-5
lines changed

2 files changed

+85
-5
lines changed

src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,12 @@ public void OnStopActivity(Activity activity, object? payload)
244244
var response = context.Response;
245245

246246
#if !NETSTANDARD
247-
var routePattern = (context.Features.Get<IExceptionHandlerPathFeature>()?.Endpoint as RouteEndpoint ??
248-
context.GetEndpoint() as RouteEndpoint)?.RoutePattern.RawText;
249-
if (!string.IsNullOrEmpty(routePattern))
247+
var endpoint = context.Features.Get<IExceptionHandlerPathFeature>()?.Endpoint as RouteEndpoint
248+
?? context.GetEndpoint() as RouteEndpoint;
249+
250+
if (endpoint != null)
250251
{
251-
TelemetryHelper.RequestDataHelper.SetActivityDisplayName(activity, context.Request.Method, routePattern);
252-
activity.SetTag(SemanticConventions.AttributeHttpRoute, routePattern);
252+
activity.SetRouteAttributeTag(endpoint, context.Request);
253253
}
254254
#endif
255255

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#if !NETSTANDARD
5+
6+
using System.Diagnostics;
7+
using System.Text;
8+
using Microsoft.AspNetCore.Http;
9+
using Microsoft.AspNetCore.Routing;
10+
using Microsoft.AspNetCore.Routing.Patterns;
11+
using OpenTelemetry.Trace;
12+
13+
namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation;
14+
15+
internal static class RouteAttributeHelper
16+
{
17+
public static void SetRouteAttributeTag(this Activity activity, RouteEndpoint endpoint, HttpRequest request)
18+
{
19+
var routePattern = GetRoutePattern(endpoint.RoutePattern, request.RouteValues);
20+
21+
if (!string.IsNullOrEmpty(routePattern))
22+
{
23+
TelemetryHelper.RequestDataHelper.SetActivityDisplayName(activity, request.Method, routePattern);
24+
activity.SetTag(SemanticConventions.AttributeHttpRoute, routePattern);
25+
}
26+
}
27+
28+
private static string GetRoutePattern(RoutePattern routePattern, RouteValueDictionary routeValues)
29+
{
30+
var sb = new StringBuilder();
31+
32+
for (var i = 0; i < routePattern.PathSegments.Count; i++)
33+
{
34+
var segment = routePattern.PathSegments[i];
35+
36+
foreach (var part in segment.Parts)
37+
{
38+
if (part is RoutePatternLiteralPart literalPart)
39+
{
40+
sb.Append(literalPart.Content);
41+
}
42+
else if (part is RoutePatternParameterPart parameterPart)
43+
{
44+
switch (parameterPart.Name)
45+
{
46+
case "area":
47+
case "controller":
48+
case "action":
49+
routePattern.RequiredValues.TryGetValue(parameterPart.Name, out var parameterValue);
50+
if (parameterValue != null)
51+
{
52+
sb.Append(parameterValue);
53+
break;
54+
}
55+
56+
goto default;
57+
default:
58+
if (routeValues.ContainsKey(parameterPart.Name))
59+
{
60+
sb.Append('{');
61+
sb.Append(parameterPart.Name);
62+
sb.Append('}');
63+
}
64+
65+
break;
66+
}
67+
}
68+
}
69+
70+
if (i < routePattern.PathSegments.Count - 1)
71+
{
72+
sb.Append('/');
73+
}
74+
}
75+
76+
return sb.ToString();
77+
}
78+
}
79+
80+
#endif

0 commit comments

Comments
 (0)