@@ -26,7 +26,6 @@ internal class HostingApplicationDiagnostics
2626
2727 private const string ActivitySourceName = "Microsoft.AspNetCore.Hosting" ;
2828 private static readonly ActivitySource _activitySource = new ActivitySource ( ActivitySourceName ) ;
29- private ActivityListener ? _dummyListener ;
3029
3130 private readonly DiagnosticListener _diagnosticListener ;
3231 private readonly ILogger _logger ;
@@ -53,19 +52,7 @@ public void BeginRequest(HttpContext httpContext, HostingApplication.Context con
5352 var diagnosticListenerActivityCreationEnabled = ( diagnosticListenerEnabled && _diagnosticListener . IsEnabled ( ActivityName , httpContext ) ) ;
5453 var loggingEnabled = _logger . IsEnabled ( LogLevel . Critical ) ;
5554
56- // TODO: If loggingEnabled check to change to if ActivityPropogation options are enabled
57- if ( loggingEnabled || diagnosticListenerActivityCreationEnabled )
58- {
59- _dummyListener = new ActivityListener ( )
60- {
61- ShouldListenTo = activitySource => ReferenceEquals ( activitySource , _activitySource ) ,
62- Sample = ( ref ActivityCreationOptions < ActivityContext > options ) => ActivitySamplingResult . PropagationData ,
63- SampleUsingParentId = ( ref ActivityCreationOptions < string > options ) => ActivitySamplingResult . PropagationData
64- } ;
65- ActivitySource . AddActivityListener ( _dummyListener ) ;
66- }
67-
68- context . Activity = StartActivity ( httpContext , diagnosticListenerActivityCreationEnabled , out var hasDiagnosticListener ) ;
55+ context . Activity = StartActivity ( httpContext , loggingEnabled , diagnosticListenerActivityCreationEnabled , out var hasDiagnosticListener ) ;
6956 context . HasDiagnosticListener = hasDiagnosticListener ;
7057
7158 if ( diagnosticListenerEnabled )
@@ -77,10 +64,6 @@ public void BeginRequest(HttpContext httpContext, HostingApplication.Context con
7764 }
7865 }
7966
80- // Dispose dummy listener
81- // TODO: How do we avoid allocating a new listener on each request
82- _dummyListener ? . Dispose ( ) ;
83-
8467 // To avoid allocation, return a null scope if the logger is not on at least to some degree.
8568 if ( loggingEnabled )
8669 {
@@ -263,19 +246,18 @@ private static void RecordRequestStartEventLog(HttpContext httpContext)
263246 }
264247
265248 [ MethodImpl ( MethodImplOptions . NoInlining ) ]
266- private Activity ? StartActivity ( HttpContext httpContext , bool diagnosticListenerActivityCreationEnabled , out bool hasDiagnosticListener )
249+ private Activity ? StartActivity ( HttpContext httpContext , bool loggingEnabled , bool diagnosticListenerActivityCreationEnabled , out bool hasActivityStartDiagnosticListener )
267250 {
268- hasDiagnosticListener = false ;
251+ hasActivityStartDiagnosticListener = false ;
269252 if ( diagnosticListenerActivityCreationEnabled )
270253 {
271254 if ( _diagnosticListener . IsEnabled ( ActivityStartKey ) )
272255 {
273- hasDiagnosticListener = true ;
256+ hasActivityStartDiagnosticListener = true ;
274257 }
275258 }
276-
277259 // Short-circuit to avoid doing an expensive header lookup
278- if ( ! ( hasDiagnosticListener || _activitySource . HasListeners ( ) ) )
260+ if ( ! ( diagnosticListenerActivityCreationEnabled || _activitySource . HasListeners ( ) || loggingEnabled ) )
279261 {
280262 return null ;
281263 }
@@ -285,48 +267,57 @@ private static void RecordRequestStartEventLog(HttpContext httpContext)
285267 {
286268 headers . TryGetValue ( HeaderNames . RequestId , out requestId ) ;
287269 }
270+
288271 var activity = _activitySource . StartActivity ( ActivityName , ActivityKind . Server , requestId ) ;
289- if ( activity is not null )
272+ bool ActivityStarted = true ;
273+ if ( activity is null )
290274 {
291- if ( ! StringValues . IsNullOrEmpty ( requestId ) )
292- {
293- // activity.SetParentId(requestId);
294- if ( headers . TryGetValue ( HeaderNames . TraceState , out var traceState ) )
295- {
296- activity . TraceStateString = traceState ;
297- }
298-
299- // We expect baggage to be empty by default
300- // Only very advanced users will be using it in near future, we encourage them to keep baggage small (few items)
301- var baggage = headers . GetCommaSeparatedValues ( HeaderNames . Baggage ) ;
302- if ( baggage . Length == 0 )
303- {
304- baggage = headers . GetCommaSeparatedValues ( HeaderNames . CorrelationContext ) ;
305- }
275+ ActivityStarted = false ;
276+ activity = new Activity ( ActivityName ) ;
277+ }
306278
307- // AddBaggage adds items at the beginning of the list, so we need to add them in reverse to keep the same order as the client
308- // An order could be important if baggage has two items with the same key (that is allowed by the contract)
309- for ( var i = baggage . Length - 1 ; i >= 0 ; i -- )
310- {
311- if ( NameValueHeaderValue . TryParse ( baggage [ i ] , out var baggageItem ) )
312- {
313- activity . AddBaggage ( baggageItem . Name . ToString ( ) , HttpUtility . UrlDecode ( baggageItem . Value . ToString ( ) ) ) ;
314- }
315- }
279+ if ( ! StringValues . IsNullOrEmpty ( requestId ) )
280+ {
281+ activity . SetParentId ( requestId ) ;
282+ if ( headers . TryGetValue ( HeaderNames . TraceState , out var traceState ) )
283+ {
284+ activity . TraceStateString = traceState ;
316285 }
317286
318- if ( diagnosticListenerActivityCreationEnabled )
287+ // We expect baggage to be empty by default
288+ // Only very advanced users will be using it in near future, we encourage them to keep baggage small (few items)
289+ var baggage = headers . GetCommaSeparatedValues ( HeaderNames . Baggage ) ;
290+ if ( baggage . Length == 0 )
319291 {
320- // Review: Breaking change: We will no longer fire OnActivityImport before Activity.Start()
321- _diagnosticListener . OnActivityImport ( activity , httpContext ) ;
292+ baggage = headers . GetCommaSeparatedValues ( HeaderNames . CorrelationContext ) ;
293+ }
322294
323- if ( hasDiagnosticListener )
295+ // AddBaggage adds items at the beginning of the list, so we need to add them in reverse to keep the same order as the client
296+ // An order could be important if baggage has two items with the same key (that is allowed by the contract)
297+ for ( var i = baggage . Length - 1 ; i >= 0 ; i -- )
298+ {
299+ if ( NameValueHeaderValue . TryParse ( baggage [ i ] , out var baggageItem ) )
324300 {
325- //Review: Do we need to explicity call this?
326- _diagnosticListener . Write ( ActivityStartKey , httpContext ) ;
301+ activity . AddBaggage ( baggageItem . Name . ToString ( ) , HttpUtility . UrlDecode ( baggageItem . Value . ToString ( ) ) ) ;
327302 }
328303 }
329304 }
305+
306+ if ( diagnosticListenerActivityCreationEnabled )
307+ {
308+ _diagnosticListener . OnActivityImport ( activity , httpContext ) ;
309+ }
310+
311+ if ( ! ActivityStarted )
312+ {
313+ activity . Start ( ) ;
314+ }
315+
316+ if ( hasActivityStartDiagnosticListener )
317+ {
318+ _diagnosticListener . Write ( ActivityStartKey , httpContext ) ;
319+ }
320+
330321 return activity ;
331322 }
332323
0 commit comments