Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper way to add RouteValues as tags?? #1790

Open
notcool11 opened this issue Aug 19, 2021 · 3 comments
Open

Proper way to add RouteValues as tags?? #1790

notcool11 opened this issue Aug 19, 2021 · 3 comments
Labels
question Further information is requested

Comments

@notcool11
Copy link

Best practice for getting RouteValues and setting them as tags

Describe your environment.
.NET core 3.1 app that exposes REST based API endpoints

Here is my otel initialization:

            service.AddOpenTelemetryTracing((builder) => builder
                .SetResourceBuilder(
                    ResourceBuilder.
                    CreateDefault().
                    AddService(distributedTracingOptions.DistributedTracingSettings.ApplicationName).
                    AddAttributes(infrastructureTags))                    
                .AddAspNetCoreInstrumentation((options) => //inbound requests to host application
                    {
                        options.RecordException = true;
                        options.Enrich = distributedTracingOptions.StandardEnrichParentSpan;
                    })                    
                .AddHttpClientInstrumentation((options) => //outbound requests from host application
                    {
                        options.RecordException = true;
                        options.Enrich = distributedTracingOptions.StandardEnrichChildSpan;
                    })
                .SetSampler(new AlwaysOnSampler())
                .AddOtlpExporter(options =>
                {
                    options.Endpoint = OtlpUri;
                })
            );

What are you trying to achieve?
Following the guidance on enriching spans gets me access to the HttpRequest and HttpResponse objects. I already get a nice normalized URL in the Operation and in the http.route tag, so that is good. There is also an http.path tag that contains the original URL with the route values in them, which sort of works.

But, to make things more queryable it would be nice to store the individual route values as tags. For instance, if I have a REST based endpoint like this:

/api/endpoint/{statecode}/action

I'd like to do queries on my traces like this:

http.route.value.statecode = "HI"

This way I'd be able to carve up the traces based on particular route values as well as look for trends on route values that might have more errors or higher latency.

I can get access to the route values through the HttpResponse object like this:

var routeData = httpResponse.HttpContext.GetRouteData();

From there it is pretty simple to add all the tags to the activity. But is this okay?? The route data is not available on the request object during the ActivityStart event, so I have to wait until the ActivityStop event and grab it off the context object. Not sure if that is safe or not.

Thanks.

@notcool11 notcool11 added the question Further information is requested label Aug 19, 2021
@notcool11
Copy link
Author

created an extension method and added this to my enrich action:

        public static IEnumerable<KeyValuePair<string, object>> GetRoutingTags(this HttpResponse httpResponse)
        {
            var routeData = httpResponse?.HttpContext?.GetRouteData()
                ?.Values
                ?.Select(routeValue => new KeyValuePair<string, object>(routeValue.Key, routeValue.Value));

            return routeData;
        }

Works a treat, but does require reference to Microsoft.AspNetCore.Routing, which I don't see in the main solution. Suppose I could use reflection to avoid this reference and follow the pattern from HttpInListener for when it pulls the route. Thanks.

@sharpSteff
Copy link

@notcool11 where do I need to call GetRoutingTags() to add the route values as tags?

@sharpSteff
Copy link

@notcool11 Nevermind, I found it myself. I could use your method in:

.AddAspNetCoreInstrumentation(o =>
                        {
                            o.EnrichWithHttpResponse = (activity, request) =>
                            {
                                activity.AddRoutingTags(request);
                            };
                        })

with:

  public static void AddRoutingTags(this Activity activity, HttpResponse httpResponse)
   {
       if (httpResponse == null)
       {
           return;
       }

       var tags = GetRoutingTags(httpResponse);
       foreach (var tag in tags)
       {
           activity.AddTag(tag.Key, tag.Value);
       }
   }

@vishweshbankwar vishweshbankwar transferred this issue from open-telemetry/opentelemetry-dotnet May 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants