Dashboard profiling: Send Faro measurements for individual panels operation time (#114898)

Dahboard profiling: Send Faro measurements for individual panels operation time
This commit is contained in:
Dominik Prokop
2025-12-09 11:44:17 +01:00
committed by GitHub
parent 39b7d86660
commit 02f431093c
2 changed files with 171 additions and 2 deletions
@@ -196,6 +196,39 @@ export class DashboardAnalyticsAggregator implements performanceUtils.ScenePerfo
return panel;
}
/**
* Send panel_render interactions for each panel with aggregated metrics
*/
private sendPanelRenderInteractions(data: performanceUtils.DashboardInteractionCompleteData): void {
const panelMetrics = this.getPanelMetrics();
panelMetrics.forEach((panel) => {
const totalPanelTime =
panel.totalQueryTime +
panel.totalTransformationTime +
panel.totalRenderTime +
panel.totalFieldConfigTime +
panel.pluginLoadTime;
// logMeasurement requires numeric values in second parameter, metadata in third
const measurementValues = {
totalTime: Math.round(totalPanelTime * 10) / 10,
queryCount: panel.queryOperations.length,
transformCount: panel.transformationOperations.length,
renderCount: panel.renderOperations.length,
fieldConfigCount: panel.fieldConfigOperations.length,
pluginLoadCount: panel.pluginLoadTime > 0 ? 1 : 0,
};
logMeasurement('panel_render', measurementValues, {
panelKey: panel.panelKey,
pluginId: panel.pluginId,
panelId: panel.panelId,
operationId: data.operationId, // Shared operationId for correlating with dashboard_render
});
});
}
/**
* Send analytics report for dashboard interactions
*/
@@ -218,6 +251,7 @@ export class DashboardAnalyticsAggregator implements performanceUtils.ScenePerfo
reportInteraction('dashboard_render', {
interactionType: data.interactionType,
uid: this.dashboardUID,
operationId: data.operationId, // OperationId for correlating with panel_render interactions
...payload,
});
@@ -225,7 +259,11 @@ export class DashboardAnalyticsAggregator implements performanceUtils.ScenePerfo
interactionType: data.interactionType,
dashboard: this.dashboardUID,
title: this.dashboardTitle,
operationId: data.operationId, // OperationId for correlating with panel_render interactions
});
// Send individual panel_render interactions
this.sendPanelRenderInteractions(data);
}
/**
@@ -351,6 +389,37 @@ export class DashboardAnalyticsAggregator implements performanceUtils.ScenePerfo
});
}
// Panel render interactions summary
if (panelMetrics && panelMetrics.length > 0) {
writePerformanceGroupStart('DAA', `📤 Panel render interactions: ${panelMetrics.length} panels reported`);
panelMetrics.forEach((panel) => {
const totalPanelTime =
panel.totalQueryTime +
panel.totalTransformationTime +
panel.totalRenderTime +
panel.totalFieldConfigTime +
panel.pluginLoadTime;
const isSlowPanel = totalPanelTime > SLOW_OPERATION_THRESHOLD_MS;
writePerformanceGroupLog('DAA', `🎨 ${panel.pluginId}-${panel.panelId}:`, {
totalTime: Math.round(totalPanelTime * 10) / 10,
operations: {
queries: panel.queryOperations.length,
transforms: panel.transformationOperations.length,
renders: panel.renderOperations.length,
fieldConfigs: panel.fieldConfigOperations.length,
pluginLoads: panel.pluginLoadTime > 0 ? 1 : 0,
},
isSlowPanel: isSlowPanel,
...(isSlowPanel && { warning: 'SLOW' }),
});
});
writePerformanceGroupEnd();
}
writePerformanceGroupEnd();
}
}
@@ -109,10 +109,16 @@ const payload = {
reportInteraction('dashboard_render', {
interactionType: e.origin,
uid,
operationId: e.operationId, // Shared operationId for correlating with panel_render measurements
...payload,
});
logMeasurement(`dashboard_render`, payload, { interactionType: e.origin, dashboard: uid, title: title });
logMeasurement('dashboard_render', payload, {
interactionType: e.origin,
dashboard: uid,
title: title,
operationId: e.operationId, // Shared operationId for correlating with panel_render measurements
});
```
### Interaction Origin Mapping
@@ -301,6 +307,7 @@ Aggregates panel-level performance metrics for analytics reporting:
- Tracks operation counts and total time spent per panel
- Sends comprehensive analytics reports via `reportInteraction` and `logMeasurement`
- Provides detailed panel breakdowns including slow panel detection
- Sends individual `panel_render` measurements for each panel with aggregated metrics via `logMeasurement`
#### ScenePerformanceLogger
@@ -344,6 +351,7 @@ Reported for each interaction via `reportInteraction` and `logMeasurement`:
{
interactionType: string, // Type of interaction
uid: string, // Dashboard UID
operationId: string, // Unique operationId for correlating with panel_render measurements
duration: number, // Total duration
networkDuration: number, // Network time
processingTime: number, // Client-side processing time
@@ -358,6 +366,8 @@ Reported for each interaction via `reportInteraction` and `logMeasurement`:
}
```
**Correlation**: The `operationId` field is shared between `dashboard_render` and all associated `panel_render` measurements, enabling correlation of panel metrics with their parent dashboard interaction.
#### Panel-Level Metrics
Aggregated by `DashboardAnalyticsAggregator` for each panel with detailed operation tracking:
@@ -406,6 +416,44 @@ Aggregated by `DashboardAnalyticsAggregator` for each panel with detailed operat
}
```
#### Panel Render Measurements
For each dashboard interaction, individual `panel_render` measurements are sent separately from `dashboard_render` via `logMeasurement`. These measurements are sent for all panels with collected metrics (even if all times are 0), providing granular panel-level analytics.
**When sent**: After `dashboard_render` interaction, one `panel_render` measurement per panel
**Correlation**: All `panel_render` measurements share the same `operationId` as their parent `dashboard_render` interaction, enabling correlation between dashboard and panel-level metrics.
**Measurement values** (via `logMeasurement`):
```typescript
{
totalTime: number, // Sum of all operation times
queryCount: number, // Number of query operations
transformCount: number, // Number of transformation operations
renderCount: number, // Number of render operations
fieldConfigCount: number, // Number of field config operations
pluginLoadCount: number // Number of plugin load operations (0 or 1)
}
```
**Measurement metadata** (via `logMeasurement` context):
```typescript
{
panelKey: string, // Panel key identifier
pluginId: string, // Panel plugin identifier
panelId: string, // Panel identifier
operationId: string // Shared operationId for correlating with dashboard_render
}
```
**Note**: `dashboard`, `title`, and `interactionType` are not included in `panel_render` metadata since they can be obtained by correlating with the parent `dashboard_render` interaction using `operationId`.
**Correlating panel_render with dashboard_render**:
All `panel_render` measurements share the same `operationId` as their parent `dashboard_render` interaction.
## Debugging and Development
### Enable Performance Debug Logging
@@ -500,7 +548,6 @@ DAA: [ANALYTICS] dashboard_view | 4 panels analyzed | 1 slow panels ⚠️
transform: 12.3,
render: 23.8,
fieldConfig: 5.0,
pluginLoad: 39.0
}
}
DAA: 📊 Queries: {
@@ -526,6 +573,59 @@ DAA: [ANALYTICS] dashboard_view | 4 panels analyzed | 1 slow panels ⚠️
**Note**: The indentation shows the **console group hierarchy**. In the browser console, each panel creates a collapsible group that can be expanded to see detailed operation breakdowns. The main dashboard analytics group contains nested panel groups for organized analysis.
#### Panel Render Measurements Summary
After the detailed panel breakdown, a summary of all `panel_render` measurements sent is displayed:
```
DAA: 📤 Panel render interactions: 4 panels reported
DAA: 🎨 timeseries-panel-1: {
totalTime: 125.3,
operations: {
queries: 2,
transforms: 1,
renders: 1,
fieldConfigs: 1,
pluginLoads: 1
},
isSlowPanel: true,
warning: "SLOW"
}
DAA: 🎨 stat-panel-2: {
totalTime: 45.2,
operations: {
queries: 1,
transforms: 0,
renders: 1,
fieldConfigs: 1,
pluginLoads: 0
},
isSlowPanel: false
}
DAA: 🎨 table-panel-3: {
totalTime: 89.7,
operations: {
queries: 1,
transforms: 2,
renders: 1,
fieldConfigs: 1
},
isSlowPanel: false
}
DAA: 🎨 graph-panel-4: {
totalTime: 234.1,
operations: {
queries: 3,
transforms: 1,
renders: 2,
fieldConfigs: 1
},
isSlowPanel: false
}
```
This summary provides a quick overview of all panels that had `panel_render` measurements sent, showing total time, operation counts, and slow panel warnings.
### Enable Echo Service Debug Logging
To observe Echo events in the browser console: