Browse Source

Migrate to ActivitySource (#30089)

* WIP: Migrate to ActivitySource

* Add ActivityListener test

* Fix remaining tests

* Remove dummy listener

* Use ActivitySource.CreateActivity APIs

* Undo changes to Activity.Stop

* Undo test change
Sourabh Shirhatti 5 years ago
parent
commit
8df6490240

+ 18 - 4
src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs

@@ -24,6 +24,9 @@ namespace Microsoft.AspNetCore.Hosting
         private const string DeprecatedDiagnosticsEndRequestKey = "Microsoft.AspNetCore.Hosting.EndRequest";
         private const string DiagnosticsUnhandledExceptionKey = "Microsoft.AspNetCore.Hosting.UnhandledException";
 
+        private const string ActivitySourceName = "Microsoft.AspNetCore.Hosting";
+        private static readonly ActivitySource _activitySource = new ActivitySource(ActivitySourceName);
+
         private readonly DiagnosticListener _diagnosticListener;
         private readonly ILogger _logger;
 
@@ -46,11 +49,13 @@ namespace Microsoft.AspNetCore.Hosting
             }
 
             var diagnosticListenerEnabled = _diagnosticListener.IsEnabled();
+            var diagnosticListenerActivityCreationEnabled = (diagnosticListenerEnabled && _diagnosticListener.IsEnabled(ActivityName, httpContext));
             var loggingEnabled = _logger.IsEnabled(LogLevel.Critical);
 
-            if (loggingEnabled || (diagnosticListenerEnabled && _diagnosticListener.IsEnabled(ActivityName, httpContext)))
+
+            if (loggingEnabled || diagnosticListenerActivityCreationEnabled || _activitySource.HasListeners())
             {
-                context.Activity = StartActivity(httpContext, out var hasDiagnosticListener);
+                context.Activity = StartActivity(httpContext, loggingEnabled, diagnosticListenerActivityCreationEnabled, out var hasDiagnosticListener);
                 context.HasDiagnosticListener = hasDiagnosticListener;
             }
 
@@ -245,11 +250,20 @@ namespace Microsoft.AspNetCore.Hosting
         }
 
         [MethodImpl(MethodImplOptions.NoInlining)]
-        private Activity StartActivity(HttpContext httpContext, out bool hasDiagnosticListener)
+        private Activity? StartActivity(HttpContext httpContext, bool loggingEnabled, bool diagnosticListenerActivityCreationEnabled, out bool hasDiagnosticListener)
         {
-            var activity = new Activity(ActivityName);
+            var activity = _activitySource.CreateActivity(ActivityName, ActivityKind.Server);
+            if (activity is null && (loggingEnabled || diagnosticListenerActivityCreationEnabled))
+            {
+                activity = new Activity(ActivityName);
+            }
             hasDiagnosticListener = false;
 
+            if (activity is null)
+            {
+                return null;
+            }
+
             var headers = httpContext.Request.Headers;
             if (!headers.TryGetValue(HeaderNames.TraceParent, out var requestId))
             {

+ 30 - 1
src/Hosting/Hosting/test/HostingApplicationDiagnosticsTests.cs

@@ -362,6 +362,7 @@ namespace Microsoft.AspNetCore.Hosting.Tests
             Assert.Contains(Activity.Current.Baggage, pair => pair.Key == "Key2" && pair.Value == "value4");
         }
 
+
         [Fact]
         public void ActivityBaggagePreservesItemsOrder()
         {
@@ -465,7 +466,7 @@ namespace Microsoft.AspNetCore.Hosting.Tests
         }
 
         [Fact]
-        public void ActivityOnExportHookIsCalled()
+        public void ActivityOnImportHookIsCalled()
         {
             var diagnosticListener = new DiagnosticListener("DummySource");
             var hostingApplication = CreateApplication(out var features, diagnosticListener: diagnosticListener);
@@ -492,6 +493,34 @@ namespace Microsoft.AspNetCore.Hosting.Tests
             Assert.True(Activity.Current.Recorded);
         }
 
+        [Fact]
+        public void ActivityListenersAreCalled()
+        {
+            var hostingApplication = CreateApplication(out var features);
+            using var listener = new ActivityListener
+            {
+                ShouldListenTo = activitySource => true,
+                Sample = (ref ActivityCreationOptions<ActivityContext> _) => ActivitySamplingResult.AllData,
+                ActivityStarted = activity =>
+                {
+                    Assert.Equal("0123456789abcdef", Activity.Current.ParentSpanId.ToHexString());
+                }
+            };
+
+            ActivitySource.AddActivityListener(listener);
+
+            features.Set<IHttpRequestFeature>(new HttpRequestFeature()
+            {
+                Headers = new HeaderDictionary()
+                {
+                    {"traceparent", "00-0123456789abcdef0123456789abcdef-0123456789abcdef-01"},
+                    {"tracestate", "TraceState1"},
+                    {"baggage", "Key1=value1, Key2=value2"}
+                }
+            });
+            hostingApplication.CreateContext(features);
+        }
+
 
         private static void AssertProperty<T>(object o, string name)
         {