Apm-agent-dotnet: MS_SubRoutes are not affecting Transaction names.

Created on 15 Feb 2021  路  7Comments  路  Source: elastic/apm-agent-dotnet

APM Agent version

The version of the Elastic.Apm nuget package used: master branch directly, AspNetFullFrameworkSampleApp

Environment

Operating system and version: Windows Version 10.0.19042.804

.NET Framework/Core name and version (e.g. .NET 4.6.1, NET Core 3.1.100) : .NET 4.6.1

Application Target Framework(s) (e.g. net461, netcoreapp3.1): net461

Describe the bug

Transaction names are generated from request.Unvalidated.Path for WebApi routes that have [Route] attribute on it.

To Reproduce

Steps to reproduce the behavior:

  1. Use AspNetFullFrameworkSampleApp from master branch (set default apm and kibana from for example Quick start guide
  2. Find AspNetFullFrameworkSampleApp.Controllers.WebApiController
  3. Add this sample controller method:
[RoutePrefix("api/webapi")]
public class WebApiController : ApiController
{
    ...
    [HttpGet]
    [Route("{someId}")]
    public IHttpActionResult AskMe(Guid someId) => Ok($"This is an example response from a web api controller: {someId}");
    ...
  1. Launch AspNetFullFrameworkSampleApp
  2. Use for example postman to request endpoint with dummy guid:
    image
  3. Find call in Kibana APM

Expected behavior

Transaction name is taken from subroute route template.
image
Example fix would be in Elastic.Apm.Model.Transaction.GetNameFromRouteContext(IDictionary<string, object> routeValues) you can add another if statement (around line 546):

else if (routeValues.TryGetValue("MS_SubRoutes", out var template))
{
    var subroute = ((IEnumerable<IHttpRouteData>)template).FirstOrDefault();
    if(subroute != null)
    {
        name = subroute.Route.RouteTemplate;
    }
}

Actual behavior

Guid is used as transaction name:
image

bug agent-dotnet

Most helpful comment

Thanks for opening @kszymanski. This seems like a reasonable change to include

All 7 comments

Thanks for opening @kszymanski. This seems like a reasonable change to include

Thank you @russcam! Looking forward to 1.9.0 release!

@kszymanski Could you tell me why RouteData might be empty?
Route Attrubute:
image

Request URL:
image

Route Data:
image

@insanity13 the RouteData looks like one that's associated with an MVC controller (System.Web.Routing.RouteData) and not one associated with a Web API controller (System.Web.Http.Routing.HttpRouteData). Does the controller derive from System.Web.Http.ApiController and are attribute routes registered with HttpConfiguration? e.g.

https://github.com/elastic/apm-agent-dotnet/blob/531d37cc391f9da919a0fde085bfe07c95e940b2/sample/AspNetFullFrameworkSampleApp/App_Start/RouteConfig.cs#L20

Does the controller derive from System.Web.Http.ApiController

Yes, all API-contrillers derive from System.Web.Http.ApiController:
image

and are attribute routes registered with HttpConfiguration

Yes, we are call MapHttpAttributeRoutes()

@insanity13 I'm sorry but I don't know why. I had myself a problem with Route attribute and APM that did not see correct route name so I debug it and google around. That is how I found article about MS_SubRoutes. I also noticed RoutePrefix attribute is making a difference some times.

Unfortunately, I have not found a way to get information about the route in my case (in Request End).

  • .NET 4.7.2
  • ASP.NET Web App using OWIN Startup

    • System.Web.Http.Owin, Version=5.2.7


    • Microsoft.AspNet.WebApi, Version=5.2.7

Found only one option: to register the ActionFilter and get a template from ControllerContext. In this place, the template is correct.

Was this page helpful?
0 / 5 - 0 ratings