@@ -36,6 +36,7 @@ public abstract partial class Renderer : IDisposable, IAsyncDisposable
3636 private readonly ILogger _logger ;
3737 private readonly ComponentFactory _componentFactory ;
3838 private readonly RenderingMetrics ? _renderingMetrics ;
39+ private readonly RenderingActivitySource ? _renderingActivitySource ;
3940 private Dictionary < int , ParameterView > ? _rootComponentsLatestParameters ;
4041 private Task ? _ongoingQuiescenceTask ;
4142
@@ -93,17 +94,16 @@ public Renderer(IServiceProvider serviceProvider, ILoggerFactory loggerFactory,
9394 // logger name in here as a string literal.
9495 _logger = loggerFactory . CreateLogger ( "Microsoft.AspNetCore.Components.RenderTree.Renderer" ) ;
9596 _componentFactory = new ComponentFactory ( componentActivator , this ) ;
96- if ( RenderingMetrics . IsMetricsSupported )
97- {
98- _renderingMetrics = serviceProvider . GetService < RenderingMetrics > ( ) ;
99- }
97+ _renderingMetrics = serviceProvider . GetService < RenderingMetrics > ( ) ;
98+ _renderingActivitySource = serviceProvider . GetService < RenderingActivitySource > ( ) ;
10099
101100 ServiceProviderCascadingValueSuppliers = serviceProvider . GetService < ICascadingValueSupplier > ( ) is null
102101 ? Array . Empty < ICascadingValueSupplier > ( )
103102 : serviceProvider . GetServices < ICascadingValueSupplier > ( ) . ToArray ( ) ;
104103 }
105104
106- internal RenderingMetrics ? RenderingMetrics => RenderingMetrics . IsMetricsSupported ? _renderingMetrics : null ;
105+ internal RenderingMetrics ? RenderingMetrics => _renderingMetrics ;
106+ internal RenderingActivitySource ? RenderingActivitySource => _renderingActivitySource ;
107107
108108 internal ICascadingValueSupplier [ ] ServiceProviderCascadingValueSuppliers { get ; }
109109
@@ -440,15 +440,24 @@ public virtual Task DispatchEventAsync(ulong eventHandlerId, EventFieldInfo? fie
440440 {
441441 Dispatcher . AssertAccess ( ) ;
442442
443- var eventStartTimestamp = RenderingMetrics . IsMetricsSupported && RenderingMetrics != null && RenderingMetrics . IsEventDurationEnabled ? Stopwatch . GetTimestamp ( ) : 0 ;
444-
445443 if ( waitForQuiescence )
446444 {
447445 _pendingTasks ??= new ( ) ;
448446 }
449447
450448 var ( renderedByComponentId , callback , attributeName ) = GetRequiredEventBindingEntry ( eventHandlerId ) ;
451449
450+ // collect trace
451+ Activity ? activity = null ;
452+ if ( RenderingActivitySource != null )
453+ {
454+ var receiverName = ( callback . Receiver ? . GetType ( ) ?? callback . Delegate . Target ? . GetType ( ) ) ? . FullName ;
455+ var methodName = callback . Delegate . Method ? . Name ;
456+ activity = RenderingActivitySource . StartEventActivity ( receiverName , methodName , attributeName , null ) ;
457+ }
458+
459+ var eventStartTimestamp = RenderingMetrics != null && RenderingMetrics . IsEventDurationEnabled ? Stopwatch . GetTimestamp ( ) : 0 ;
460+
452461 // If this event attribute was rendered by a component that's since been disposed, don't dispatch the event at all.
453462 // This can occur because event handler disposal is deferred, so event handler IDs can outlive their components.
454463 // The reason the following check is based on "which component rendered this frame" and not on "which component
@@ -491,23 +500,36 @@ public virtual Task DispatchEventAsync(ulong eventHandlerId, EventFieldInfo? fie
491500 task = callback . InvokeAsync ( eventArgs ) ;
492501
493502 // collect metrics
494- if ( RenderingMetrics . IsMetricsSupported && RenderingMetrics != null && RenderingMetrics . IsEventDurationEnabled )
503+ if ( RenderingMetrics != null && RenderingMetrics . IsEventDurationEnabled )
495504 {
496505 var receiverName = ( callback . Receiver ? . GetType ( ) ?? callback . Delegate . Target ? . GetType ( ) ) ? . FullName ;
497- RenderingMetrics . EventDurationSync ( eventStartTimestamp , receiverName , attributeName ) ;
498- _ = RenderingMetrics . CaptureEventDurationAsync ( task , eventStartTimestamp , receiverName , attributeName ) ;
506+ var methodName = callback . Delegate . Method ? . Name ;
507+ RenderingMetrics . EventDurationSync ( eventStartTimestamp , receiverName , methodName , attributeName ) ;
508+ _ = RenderingMetrics . CaptureEventDurationAsync ( task , eventStartTimestamp , receiverName , methodName , attributeName ) ;
499509 }
500- if ( RenderingMetrics . IsMetricsSupported && RenderingMetrics != null && RenderingMetrics . IsEventExceptionEnabled )
510+ if ( RenderingMetrics != null && RenderingMetrics . IsEventExceptionEnabled )
501511 {
502512 _ = RenderingMetrics . CaptureEventFailedAsync ( task , callback , attributeName ) ;
503513 }
514+
515+ // stop activity/trace
516+ if ( RenderingActivitySource != null && activity != null )
517+ {
518+ _ = RenderingActivitySource . CaptureEventStopAsync ( task , activity ) ;
519+ }
504520 }
505521 catch ( Exception e )
506522 {
507- if ( RenderingMetrics . IsMetricsSupported && RenderingMetrics != null && RenderingMetrics . IsEventExceptionEnabled )
523+ if ( RenderingMetrics != null && RenderingMetrics . IsEventExceptionEnabled )
508524 {
509525 RenderingMetrics . EventFailed ( e . GetType ( ) . FullName , callback , attributeName ) ;
510526 }
527+
528+ if ( RenderingActivitySource != null && activity != null )
529+ {
530+ RenderingActivitySource . FailEventActivity ( activity , e ) ;
531+ }
532+
511533 HandleExceptionViaErrorBoundary ( e , receiverComponentState ) ;
512534 return Task . CompletedTask ;
513535 }
@@ -795,7 +817,7 @@ private void ProcessRenderQueue()
795817
796818 _isBatchInProgress = true ;
797819 var updateDisplayTask = Task . CompletedTask ;
798- var batchStartTimestamp = RenderingMetrics . IsMetricsSupported && RenderingMetrics != null && RenderingMetrics . IsBatchDurationEnabled ? Stopwatch . GetTimestamp ( ) : 0 ;
820+ var batchStartTimestamp = RenderingMetrics != null && RenderingMetrics . IsBatchDurationEnabled ? Stopwatch . GetTimestamp ( ) : 0 ;
799821
800822 try
801823 {
@@ -828,18 +850,18 @@ private void ProcessRenderQueue()
828850 // if there is async work to be done.
829851 _ = InvokeRenderCompletedCalls ( batch . UpdatedComponents , updateDisplayTask ) ;
830852
831- if ( RenderingMetrics . IsMetricsSupported && RenderingMetrics != null && RenderingMetrics . IsBatchDurationEnabled )
853+ if ( RenderingMetrics != null && RenderingMetrics . IsBatchDurationEnabled )
832854 {
833855 _renderingMetrics . BatchDuration ( batchStartTimestamp , batch . UpdatedComponents . Count ) ;
834856 }
835- if ( RenderingMetrics . IsMetricsSupported && RenderingMetrics != null && RenderingMetrics . IsBatchExceptionEnabled )
857+ if ( RenderingMetrics != null && RenderingMetrics . IsBatchExceptionEnabled )
836858 {
837859 _ = _renderingMetrics . CaptureBatchFailedAsync ( updateDisplayTask ) ;
838860 }
839861 }
840862 catch ( Exception e )
841863 {
842- if ( RenderingMetrics . IsMetricsSupported && RenderingMetrics != null && RenderingMetrics . IsBatchExceptionEnabled )
864+ if ( RenderingMetrics != null && RenderingMetrics . IsBatchExceptionEnabled )
843865 {
844866 _renderingMetrics . BatchFailed ( e . GetType ( ) . Name ) ;
845867 }
0 commit comments