Skip to content

[blazor] Diagnostic traces - OTEL names review #62751

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/Components/Components/src/ComponentsActivitySource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/Components/Components/src/RenderTree/Renderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions src/Components/Components/src/Routing/Router.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -301,15 +301,15 @@ 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)
{
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)
Expand Down
26 changes: 13 additions & 13 deletions src/Components/Components/test/ComponentsActivitySourceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void StartRouteActivity_CreatesAndStartsActivity()
linkstore.SetActivityContext(ComponentsActivityLinkStore.Circuit, new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded), new KeyValuePair<string, object>("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
Expand All @@ -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);
Expand All @@ -83,10 +83,10 @@ public void StartEventActivity_CreatesAndStartsActivity()

// First set up a circuit and route context
linkstore.SetActivityContext(ComponentsActivityLinkStore.Circuit, default, new KeyValuePair<string, object>("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
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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
Expand All @@ -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
Expand Down
12 changes: 7 additions & 5 deletions src/Components/Server/src/Circuits/CircuitActivitySource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -42,20 +42,22 @@ 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 };
}
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
Loading