@@ -26,7 +26,6 @@ internal class HostingApplicationDiagnostics
26
26
27
27
private const string ActivitySourceName = "Microsoft.AspNetCore.Hosting" ;
28
28
private static readonly ActivitySource _activitySource = new ActivitySource ( ActivitySourceName ) ;
29
- private ActivityListener ? _dummyListener ;
30
29
31
30
private readonly DiagnosticListener _diagnosticListener ;
32
31
private readonly ILogger _logger ;
@@ -53,19 +52,7 @@ public void BeginRequest(HttpContext httpContext, HostingApplication.Context con
53
52
var diagnosticListenerActivityCreationEnabled = ( diagnosticListenerEnabled && _diagnosticListener . IsEnabled ( ActivityName , httpContext ) ) ;
54
53
var loggingEnabled = _logger . IsEnabled ( LogLevel . Critical ) ;
55
54
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 ) ;
69
56
context . HasDiagnosticListener = hasDiagnosticListener ;
70
57
71
58
if ( diagnosticListenerEnabled )
@@ -77,10 +64,6 @@ public void BeginRequest(HttpContext httpContext, HostingApplication.Context con
77
64
}
78
65
}
79
66
80
- // Dispose dummy listener
81
- // TODO: How do we avoid allocating a new listener on each request
82
- _dummyListener ? . Dispose ( ) ;
83
-
84
67
// To avoid allocation, return a null scope if the logger is not on at least to some degree.
85
68
if ( loggingEnabled )
86
69
{
@@ -263,19 +246,18 @@ private static void RecordRequestStartEventLog(HttpContext httpContext)
263
246
}
264
247
265
248
[ 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 )
267
250
{
268
- hasDiagnosticListener = false ;
251
+ hasActivityStartDiagnosticListener = false ;
269
252
if ( diagnosticListenerActivityCreationEnabled )
270
253
{
271
254
if ( _diagnosticListener . IsEnabled ( ActivityStartKey ) )
272
255
{
273
- hasDiagnosticListener = true ;
256
+ hasActivityStartDiagnosticListener = true ;
274
257
}
275
258
}
276
-
277
259
// Short-circuit to avoid doing an expensive header lookup
278
- if ( ! ( hasDiagnosticListener || _activitySource . HasListeners ( ) ) )
260
+ if ( ! ( diagnosticListenerActivityCreationEnabled || _activitySource . HasListeners ( ) || loggingEnabled ) )
279
261
{
280
262
return null ;
281
263
}
@@ -285,48 +267,57 @@ private static void RecordRequestStartEventLog(HttpContext httpContext)
285
267
{
286
268
headers . TryGetValue ( HeaderNames . RequestId , out requestId ) ;
287
269
}
270
+
288
271
var activity = _activitySource . StartActivity ( ActivityName , ActivityKind . Server , requestId ) ;
289
- if ( activity is not null )
272
+ bool ActivityStarted = true ;
273
+ if ( activity is null )
290
274
{
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
+ }
306
278
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 ;
316
285
}
317
286
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 )
319
291
{
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
+ }
322
294
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 ) )
324
300
{
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 ( ) ) ) ;
327
302
}
328
303
}
329
304
}
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
+
330
321
return activity ;
331
322
}
332
323
0 commit comments