1616
1717namespace OpenCensus . Collector . AspNetCore . Implementation
1818{
19- using System ;
2019 using System . Diagnostics ;
2120 using System . Linq ;
2221 using System . Text ;
@@ -31,6 +30,9 @@ internal class HttpInListener : ListenerHandler
3130 private const string UnknownHostName = "UNKNOWN-HOST" ;
3231 private readonly PropertyFetcher startContextFetcher = new PropertyFetcher ( "HttpContext" ) ;
3332 private readonly PropertyFetcher stopContextFetcher = new PropertyFetcher ( "HttpContext" ) ;
33+ private readonly PropertyFetcher beforeActionActionDescriptorFetcher = new PropertyFetcher ( "actionDescriptor" ) ;
34+ private readonly PropertyFetcher beforeActionAttributeRouteInfoFetcher = new PropertyFetcher ( "AttributeRouteInfo" ) ;
35+ private readonly PropertyFetcher beforeActionTemplateFetcher = new PropertyFetcher ( "Template" ) ;
3436 private readonly IPropagationComponent propagationComponent ;
3537
3638 public HttpInListener ( ITracer tracer , ISampler sampler , IPropagationComponent propagationComponent )
@@ -84,15 +86,16 @@ public override void OnStopActivity(Activity activity, object payload)
8486
8587 if ( context == null )
8688 {
87- // Debug.WriteLine("context is null");
89+ // TODO: Debug.WriteLine("context is null");
8890 return ;
8991 }
9092
9193 var span = this . Tracer . CurrentSpan ;
9294
9395 if ( span == null )
9496 {
95- // report lost span
97+ // TODO: report lost span
98+ return ;
9699 }
97100
98101 var response = context . Response ;
@@ -101,6 +104,41 @@ public override void OnStopActivity(Activity activity, object payload)
101104 span . End ( ) ;
102105 }
103106
107+ public override void OnCustom ( string name , Activity activity , object payload )
108+ {
109+ if ( name == "Microsoft.AspNetCore.Mvc.BeforeAction" )
110+ {
111+ var span = this . Tracer . CurrentSpan ;
112+
113+ if ( span == null )
114+ {
115+ // TODO: report lost span
116+ return ;
117+ }
118+
119+ // See https://github.com/aspnet/Mvc/blob/2414db256f32a047770326d14d8b0e2afd49ba49/src/Microsoft.AspNetCore.Mvc.Core/MvcCoreDiagnosticSourceExtensions.cs#L36-L44
120+ // Reflection accessing: ActionDescriptor.AttributeRouteInfo.Template
121+ // The reason to use reflection is to avoid a reference on MVC package.
122+ // This package can be used with non-MVC apps and this logic simply wouldn't run.
123+ // Taking reference on MVC will increase size of deployment for non-MVC apps.
124+ var actionDescriptor = this . beforeActionActionDescriptorFetcher . Fetch ( payload ) ;
125+ var attributeRouteInfo = this . beforeActionAttributeRouteInfoFetcher . Fetch ( actionDescriptor ) ;
126+ var template = this . beforeActionTemplateFetcher . Fetch ( attributeRouteInfo ) as string ;
127+
128+ if ( ! string . IsNullOrEmpty ( template ) )
129+ {
130+ // override the span name that was previously set to the path part of URL.
131+ span . Name = template ;
132+
133+ span . PutHttpRouteAttribute ( template ) ;
134+ }
135+
136+ // TODO: Should we get values from RouteData?
137+ // private readonly PropertyFetcher beforActionRouteDataFetcher = new PropertyFetcher("routeData");
138+ // var routeData = this.beforActionRouteDataFetcher.Fetch(payload) as RouteData;
139+ }
140+ }
141+
104142 private static string GetUri ( HttpRequest request )
105143 {
106144 var builder = new StringBuilder ( ) ;
0 commit comments