Skip to content

Commit 9e581c4

Browse files
bcoegetsantry[bot]
andauthored
feat(analytics): emit event for engagement score when dashboard loads (#97786)
Emits an event when a dashboard loads that includes a ratio of engagement based on the number of issues, vs., tracing widgets. --------- Co-authored-by: getsantry[bot] <66042841+getsantry[bot]@users.noreply.github.com>
1 parent d1e184e commit 9e581c4

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

static/app/utils/analytics/dashboardsAnalyticsEvents.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ export enum WidgetBuilderVersion {
77

88
// Used in the full-page widget builder
99
type DashboardsEventParametersWidgetBuilder = {
10+
'dashboards_views.engagement.load': {
11+
issuesRatio: number;
12+
logRatio: number;
13+
title: string;
14+
tracingRatio: number;
15+
};
1016
'dashboards_views.widget_builder.change': {
1117
builder_version: WidgetBuilderVersion;
1218
field: string;
@@ -54,6 +60,7 @@ const dashboardsEventMapWidgetBuilder: Record<
5460
'Widget Builder: Template added to dashboard',
5561
'dashboards_views.widget_builder.templates.add_to_dashboard.customize':
5662
'Widget Builder: Template added to dashboard and customized',
63+
'dashboards_views.engagement.load': 'Dashboard Load: Engagement by Product',
5764
};
5865

5966
export type DashboardsEventParameters = {

static/app/views/dashboards/dashboard.tsx

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ class Dashboard extends Component<Props, State> {
153153
}
154154

155155
componentDidMount() {
156-
const {newWidget} = this.props;
156+
const {dashboard, newWidget} = this.props;
157157
window.addEventListener('resize', this.debouncedHandleResize);
158158

159159
// Always load organization tags on dashboards
@@ -167,6 +167,7 @@ class Dashboard extends Component<Props, State> {
167167
this.fetchMemberList();
168168

169169
connectDashboardCharts(DASHBOARD_CHART_GROUP);
170+
this.trackEngagementAnalytics(dashboard.widgets);
170171
}
171172

172173
componentDidUpdate(prevProps: Props) {
@@ -479,6 +480,41 @@ class Dashboard extends Component<Props, State> {
479480
this.setState({isMobile: false});
480481
};
481482

483+
trackEngagementAnalytics(widgets: Widget[]) {
484+
// Handle edge-case of dashboard with no widgets.
485+
if (!widgets.length) return;
486+
const {dashboard, organization} = this.props;
487+
// For attributing engagement metrics initially track the ratio
488+
// of widgets reading from Transactions, Spans, Errors, and Issues, and Logs.
489+
const issuesWidgetTypes = new Set<string | undefined>([
490+
'error-events',
491+
'issue',
492+
'metrics',
493+
]);
494+
const logWidgetTypes = new Set<string | undefined>(['logs']);
495+
const tracingWidgetTypes = new Set<string | undefined>(['transaction-like', 'spans']);
496+
let issuesWidgetCount = 0.0;
497+
let logWidgetCount = 0.0;
498+
let tracingWidgetCount = 0.0;
499+
for (const widget of widgets) {
500+
if (issuesWidgetTypes.has(widget.widgetType)) {
501+
issuesWidgetCount += 1.0;
502+
} else if (logWidgetTypes.has(widget.widgetType)) {
503+
logWidgetCount += 1.0;
504+
} else if (tracingWidgetTypes.has(widget.widgetType)) {
505+
tracingWidgetCount += 1.0;
506+
}
507+
}
508+
const analyticsPayload = {
509+
organization,
510+
title: dashboard.title,
511+
tracingRatio: tracingWidgetCount / widgets.length,
512+
issuesRatio: issuesWidgetCount / widgets.length,
513+
logRatio: logWidgetCount / widgets.length,
514+
};
515+
trackAnalytics('dashboards_views.engagement.load', analyticsPayload);
516+
}
517+
482518
get addWidgetLayout() {
483519
const {isMobile, layouts} = this.state;
484520
let position: Position = BOTTOM_MOBILE_VIEW_POSITION;

0 commit comments

Comments
 (0)