From f7d1691cbdb13d549bf4ef2665fe5c11faa3f858 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 16 Jul 2025 12:47:38 +0200 Subject: [PATCH 1/2] - rename RouteChange->Navigate - don't propagate HTTP/SignalR links to event traces --- .../Components/src/ComponentsActivitySource.cs | 2 +- .../Server/src/Circuits/CircuitActivitySource.cs | 12 +++++++----- .../test/Circuits/CircuitActivitySourceTest.cs | 3 +-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Components/Components/src/ComponentsActivitySource.cs b/src/Components/Components/src/ComponentsActivitySource.cs index 77e8caeff27d..56174a9d96e6 100644 --- a/src/Components/Components/src/ComponentsActivitySource.cs +++ b/src/Components/Components/src/ComponentsActivitySource.cs @@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Components; internal class ComponentsActivitySource { internal const string Name = "Microsoft.AspNetCore.Components"; - internal const string OnRouteName = $"{Name}.RouteChange"; + internal const string OnRouteName = $"{Name}.Navigate"; internal const string OnEventName = $"{Name}.HandleEvent"; private static ActivitySource ActivitySource { get; } = new ActivitySource(Name); diff --git a/src/Components/Server/src/Circuits/CircuitActivitySource.cs b/src/Components/Server/src/Circuits/CircuitActivitySource.cs index 1c03702dba63..01e793082693 100644 --- a/src/Components/Server/src/Circuits/CircuitActivitySource.cs +++ b/src/Components/Server/src/Circuits/CircuitActivitySource.cs @@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits; internal class CircuitActivitySource { internal const string Name = "Microsoft.AspNetCore.Components.Server.Circuits"; - internal const string OnCircuitName = $"{Name}.CircuitStart"; + internal const string OnCircuitName = $"{Name}.StartCircuit"; private ComponentsActivityLinkStore? _activityLinkStore; @@ -42,13 +42,13 @@ public CircuitActivityHandle StartCircuitActivity(string circuitId, ActivityCont } if (httpActivityContext != default) { - // store the http link - _activityLinkStore.SetActivityContext(ComponentsActivityLinkStore.Http, httpActivityContext, null); + // add the http link + activity.AddLink(new ActivityLink(httpActivityContext)); } if (signalRActivity != null && signalRActivity.Source.Name == "Microsoft.AspNetCore.SignalR.Server") { - // store the SignalR link - _activityLinkStore.SetActivityContext(ComponentsActivityLinkStore.SignalR, signalRActivity.Context, null); + // add the SignalR link + activity.AddLink(new ActivityLink(signalRActivity.Context)); } } return new CircuitActivityHandle { Previous = signalRActivity, Activity = activity }; @@ -56,6 +56,8 @@ public CircuitActivityHandle StartCircuitActivity(string circuitId, ActivityCont return default; } + // We call this at the end of circuit creation, rather than at the end of the circuit lifecycle + // because long-lived traces are difficult to work with in the telemetry UIs public void StopCircuitActivity(CircuitActivityHandle activityHandle, Exception? ex) { var activity = activityHandle.Activity; diff --git a/src/Components/Server/test/Circuits/CircuitActivitySourceTest.cs b/src/Components/Server/test/Circuits/CircuitActivitySourceTest.cs index 292eab307959..6901387c9b81 100644 --- a/src/Components/Server/test/Circuits/CircuitActivitySourceTest.cs +++ b/src/Components/Server/test/Circuits/CircuitActivitySourceTest.cs @@ -54,12 +54,11 @@ public void StartCircuitActivity_CreatesAndStartsActivity() Assert.Equal(ActivityKind.Internal, activity.Kind); Assert.True(activity.IsAllDataRequested); Assert.Equal(circuitId, activity.GetTagItem("aspnetcore.components.circuit.id")); - Assert.Empty(activity.Links); + Assert.Contains(activity.Links, link => link.Context == httpContext); Assert.False(activity.IsStopped); circuitActivitySource.StopCircuitActivity(activityHandle, null); Assert.True(activity.IsStopped); - Assert.Contains(activity.Links, link => link.Context == httpContext); } [Fact] From c344de6d57e76b8d90282506bf53e89c41b66f12 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 16 Jul 2025 14:30:29 +0200 Subject: [PATCH 2/2] rename methods --- .../src/ComponentsActivitySource.cs | 14 +++++----- .../Components/src/RenderTree/Renderer.cs | 6 ++--- .../Components/src/Routing/Router.cs | 6 ++--- .../test/ComponentsActivitySourceTest.cs | 26 +++++++++---------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/Components/Components/src/ComponentsActivitySource.cs b/src/Components/Components/src/ComponentsActivitySource.cs index 56174a9d96e6..1ce87e918417 100644 --- a/src/Components/Components/src/ComponentsActivitySource.cs +++ b/src/Components/Components/src/ComponentsActivitySource.cs @@ -23,7 +23,7 @@ public void Init(ComponentsActivityLinkStore store) _componentsActivityLinkStore = store; } - public ComponentsActivityHandle StartRouteActivity(string componentType, string route) + public ComponentsActivityHandle StartNavigateActivity(string componentType, string route) { var activity = ActivitySource.CreateActivity(OnRouteName, ActivityKind.Internal, parentId: null, null, null); if (activity is not null) @@ -54,12 +54,12 @@ public ComponentsActivityHandle StartRouteActivity(string componentType, string return default; } - public void StopRouteActivity(ComponentsActivityHandle activityHandle, Exception? ex) + public void StopNavigateActivity(ComponentsActivityHandle activityHandle, Exception? ex) { StopComponentActivity(ComponentsActivityLinkStore.Route, activityHandle, ex); } - public static ComponentsActivityHandle StartEventActivity(string? componentType, string? methodName, string? attributeName) + public static ComponentsActivityHandle StartHandleEventActivity(string? componentType, string? methodName, string? attributeName) { var activity = ActivitySource.CreateActivity(OnEventName, ActivityKind.Internal, parentId: null, null, null); @@ -91,21 +91,21 @@ public static ComponentsActivityHandle StartEventActivity(string? componentType, return default; } - public void StopEventActivity(ComponentsActivityHandle activityHandle, Exception? ex) + public void StopHandleEventActivity(ComponentsActivityHandle activityHandle, Exception? ex) { StopComponentActivity(ComponentsActivityLinkStore.Event, activityHandle, ex); } - public async Task CaptureEventStopAsync(Task task, ComponentsActivityHandle activityHandle) + public async Task CaptureHandleEventStopAsync(Task task, ComponentsActivityHandle activityHandle) { try { await task; - StopEventActivity(activityHandle, null); + StopHandleEventActivity(activityHandle, null); } catch (Exception ex) { - StopEventActivity(activityHandle, ex); + StopHandleEventActivity(activityHandle, ex); } } diff --git a/src/Components/Components/src/RenderTree/Renderer.cs b/src/Components/Components/src/RenderTree/Renderer.cs index f5ea90bc304f..138240ce2812 100644 --- a/src/Components/Components/src/RenderTree/Renderer.cs +++ b/src/Components/Components/src/RenderTree/Renderer.cs @@ -461,7 +461,7 @@ public virtual Task DispatchEventAsync(ulong eventHandlerId, EventFieldInfo? fie { receiverName ??= (callback.Receiver?.GetType() ?? callback.Delegate.Target?.GetType())?.FullName; methodName ??= callback.Delegate.Method?.Name; - activityHandle = ComponentsActivitySource.StartEventActivity(receiverName, methodName, attributeName); + activityHandle = ComponentsActivitySource.StartHandleEventActivity(receiverName, methodName, attributeName); } var eventStartTimestamp = ComponentMetrics != null && ComponentMetrics.IsEventEnabled ? Stopwatch.GetTimestamp() : 0; @@ -518,7 +518,7 @@ public virtual Task DispatchEventAsync(ulong eventHandlerId, EventFieldInfo? fie // stop activity/trace if (ComponentActivitySource != null && activityHandle.Activity != null) { - _ = ComponentActivitySource.CaptureEventStopAsync(task, activityHandle); + _ = ComponentActivitySource.CaptureHandleEventStopAsync(task, activityHandle); } } catch (Exception e) @@ -532,7 +532,7 @@ public virtual Task DispatchEventAsync(ulong eventHandlerId, EventFieldInfo? fie if (ComponentActivitySource != null && activityHandle.Activity != null) { - ComponentActivitySource.StopEventActivity(activityHandle, e); + ComponentActivitySource.StopHandleEventActivity(activityHandle, e); } HandleExceptionViaErrorBoundary(e, receiverComponentState); diff --git a/src/Components/Components/src/Routing/Router.cs b/src/Components/Components/src/Routing/Router.cs index eedff373f656..4e38390d914f 100644 --- a/src/Components/Components/src/Routing/Router.cs +++ b/src/Components/Components/src/Routing/Router.cs @@ -246,7 +246,7 @@ internal virtual void Refresh(bool isNavigationIntercepted) endpointRouteData = RouteTable.ProcessParameters(endpointRouteData); _renderHandle.Render(Found(endpointRouteData)); - _renderHandle.ComponentActivitySource?.StopRouteActivity(activityHandle, null); + _renderHandle.ComponentActivitySource?.StopNavigateActivity(activityHandle, null); return; } @@ -301,7 +301,7 @@ internal virtual void Refresh(bool isNavigationIntercepted) NavigationManager.NavigateTo(_locationAbsolute, forceLoad: true); } } - _renderHandle.ComponentActivitySource?.StopRouteActivity(activityHandle, null); + _renderHandle.ComponentActivitySource?.StopNavigateActivity(activityHandle, null); } private ComponentsActivityHandle RecordDiagnostics(string componentType, string template) @@ -309,7 +309,7 @@ private ComponentsActivityHandle RecordDiagnostics(string componentType, string ComponentsActivityHandle activityHandle = default; if (_renderHandle.ComponentActivitySource != null) { - activityHandle = _renderHandle.ComponentActivitySource.StartRouteActivity(componentType, template); + activityHandle = _renderHandle.ComponentActivitySource.StartNavigateActivity(componentType, template); } if (_renderHandle.ComponentMetrics != null && _renderHandle.ComponentMetrics.IsNavigationEnabled) diff --git a/src/Components/Components/test/ComponentsActivitySourceTest.cs b/src/Components/Components/test/ComponentsActivitySourceTest.cs index 2496844885d7..04983ef0cac9 100644 --- a/src/Components/Components/test/ComponentsActivitySourceTest.cs +++ b/src/Components/Components/test/ComponentsActivitySourceTest.cs @@ -50,7 +50,7 @@ public void StartRouteActivity_CreatesAndStartsActivity() linkstore.SetActivityContext(ComponentsActivityLinkStore.Circuit, new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded), new KeyValuePair("aspnetcore.components.circuit.id", "test-circuit-id")); // Act - var activityHandle = componentsActivitySource.StartRouteActivity(componentType, route); + var activityHandle = componentsActivitySource.StartNavigateActivity(componentType, route); var activity = activityHandle.Activity; // Assert @@ -63,7 +63,7 @@ public void StartRouteActivity_CreatesAndStartsActivity() Assert.Equal(route, activity.GetTagItem("aspnetcore.components.route")); Assert.False(activity.IsStopped); - componentsActivitySource.StopRouteActivity(activityHandle, null); + componentsActivitySource.StopNavigateActivity(activityHandle, null); Assert.True(activity.IsStopped); Assert.Equal("test-circuit-id", activity.GetTagItem("aspnetcore.components.circuit.id")); Assert.Single(activity.Links); @@ -83,10 +83,10 @@ public void StartEventActivity_CreatesAndStartsActivity() // First set up a circuit and route context linkstore.SetActivityContext(ComponentsActivityLinkStore.Circuit, default, new KeyValuePair("aspnetcore.components.circuit.id", "test-circuit-id")); - componentsActivitySource.StartRouteActivity("ParentComponent", "/parent"); + componentsActivitySource.StartNavigateActivity("ParentComponent", "/parent"); // Act - var activityHandle = ComponentsActivitySource.StartEventActivity(componentType, methodName, attributeName); + var activityHandle = ComponentsActivitySource.StartHandleEventActivity(componentType, methodName, attributeName); var activity = activityHandle.Activity; // Assert @@ -100,7 +100,7 @@ public void StartEventActivity_CreatesAndStartsActivity() Assert.Equal(attributeName, activity.GetTagItem("aspnetcore.components.attribute.name")); Assert.False(activity.IsStopped); - componentsActivitySource.StopRouteActivity(activityHandle, null); + componentsActivitySource.StopNavigateActivity(activityHandle, null); Assert.True(activity.IsStopped); Assert.Equal("test-circuit-id", activity.GetTagItem("aspnetcore.components.circuit.id")); Assert.Empty(activity.Links); @@ -113,12 +113,12 @@ public void FailEventActivity_SetsErrorStatusAndStopsActivity() var componentsActivitySource = new ComponentsActivitySource(); var linkstore = new ComponentsActivityLinkStore(null); componentsActivitySource.Init(linkstore); - var activityHandle = ComponentsActivitySource.StartEventActivity("TestComponent", "OnClick", "onclick"); + var activityHandle = ComponentsActivitySource.StartHandleEventActivity("TestComponent", "OnClick", "onclick"); var activity = activityHandle.Activity; var exception = new InvalidOperationException("Test exception"); // Act - componentsActivitySource.StopEventActivity(activityHandle, exception); + componentsActivitySource.StopHandleEventActivity(activityHandle, exception); // Assert Assert.True(activity!.IsStopped); @@ -133,12 +133,12 @@ public async Task CaptureEventStopAsync_StopsActivityOnSuccessfulTask() var componentsActivitySource = new ComponentsActivitySource(); var linkstore = new ComponentsActivityLinkStore(null); componentsActivitySource.Init(linkstore); - var activityHandle = ComponentsActivitySource.StartEventActivity("TestComponent", "OnClick", "onclick"); + var activityHandle = ComponentsActivitySource.StartHandleEventActivity("TestComponent", "OnClick", "onclick"); var activity = activityHandle.Activity; var task = Task.CompletedTask; // Act - await componentsActivitySource.CaptureEventStopAsync(task, activityHandle); + await componentsActivitySource.CaptureHandleEventStopAsync(task, activityHandle); // Assert Assert.True(activity!.IsStopped); @@ -152,13 +152,13 @@ public async Task CaptureEventStopAsync_FailsActivityOnException() var componentsActivitySource = new ComponentsActivitySource(); var linkstore = new ComponentsActivityLinkStore(null); componentsActivitySource.Init(linkstore); - var activityHandle = ComponentsActivitySource.StartEventActivity("TestComponent", "OnClick", "onclick"); + var activityHandle = ComponentsActivitySource.StartHandleEventActivity("TestComponent", "OnClick", "onclick"); var activity = activityHandle.Activity; var exception = new InvalidOperationException("Test exception"); var task = Task.FromException(exception); // Act - await componentsActivitySource.CaptureEventStopAsync(task, activityHandle); + await componentsActivitySource.CaptureHandleEventStopAsync(task, activityHandle); // Assert Assert.True(activity!.IsStopped); @@ -175,7 +175,7 @@ public void StartRouteActivity_HandlesNullValues() componentsActivitySource.Init(linkstore); // Act - var activityHandle = componentsActivitySource.StartRouteActivity(null, null); + var activityHandle = componentsActivitySource.StartNavigateActivity(null, null); var activity = activityHandle.Activity; // Assert @@ -192,7 +192,7 @@ public void StartEventActivity_HandlesNullValues() componentsActivitySource.Init(linkstore); // Act - var activityHandle = ComponentsActivitySource.StartEventActivity(null, null, null); + var activityHandle = ComponentsActivitySource.StartHandleEventActivity(null, null, null); var activity = activityHandle.Activity; // Assert