Skip to content

Commit ab2dac9

Browse files
[ObsUX][Infra] Add telemetry for anomaly job creation (#198061)
Closes #189619 Telemetry events created: - Infra Anomaly Detection Job Setup ``` { "event_type":"Infra Anomaly Detection Job Setup", "context":{...} "properties": { "job_type":"host", "configured_fields":{"start_date":"2024-09-24T16:11:41.446Z","partition_field":"cloud.instance.id","filter_field": "host.name:\"gke-edge-lite-oblt-edge-lite-oblt-poo-f77db573-2249\"} } } ``` - Infra Anomaly Detection Job Date Field Change ``` { "event_type":" Infra Anomaly Detection Job Date Field Change", "context":{...} "properties": { "job_type":"host", "start_date":"2024-09-24T16:11:41.446Z" } } ``` - Infra Anomaly Detection Job Partition Field Change ``` { "event_type":" Infra Anomaly Detection Job Date Field Change", "context":{...} "properties": { "job_type":"host", "partition_field":"cloud.instance.id" } } ``` - Infra Anomaly Detection Job Filter Field Change ``` { "event_type":" Infra Anomaly Detection Job Date Field Change", "context":{...} "properties": { "job_type":"host", "filter_field": "host.name:\"gke-edge-lite-oblt-edge-lite-oblt-poo-f77db573-2249\" } } ``` (cherry picked from commit 227aaf3)
1 parent 0f3a0af commit ab2dac9

File tree

6 files changed

+343
-11
lines changed

6 files changed

+343
-11
lines changed

x-pack/plugins/observability_solution/infra/public/components/ml/anomaly_detection/job_setup_screen.tsx

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import { FixedDatePicker } from '../../fixed_datepicker';
3838
import { DEFAULT_K8S_PARTITION_FIELD } from '../../../containers/ml/modules/metrics_k8s/module_descriptor';
3939
import { convertKueryToElasticSearchQuery } from '../../../utils/kuery';
4040
import { INFRA_ML_FLYOUT_FEEDBACK_LINK } from './flyout_home';
41-
import { KibanaEnvironmentContext } from '../../../hooks/use_kibana';
41+
import { KibanaEnvironmentContext, useKibanaContextForPlugin } from '../../../hooks/use_kibana';
4242
import { MetricsExplorerKueryBar } from '../../../pages/metrics/metrics_explorer/components/kuery_bar';
4343

4444
interface Props {
@@ -60,6 +60,7 @@ export const JobSetupScreen = (props: Props) => {
6060
const trackMetric = useUiTracker({ app: 'infra_metrics' });
6161
const { kibanaVersion, isCloudEnv, isServerlessEnv } = useContext(KibanaEnvironmentContext);
6262
const { euiTheme } = useEuiTheme();
63+
const { telemetry } = useKibanaContextForPlugin().services;
6364

6465
const indices = host.sourceConfiguration.indices;
6566

@@ -95,23 +96,47 @@ export const JobSetupScreen = (props: Props) => {
9596
}
9697
}, [props.jobType, kubernetes.jobSummaries, host.jobSummaries]);
9798

98-
const updateStart = useCallback((date: Moment) => {
99-
setStartDate(date);
100-
}, []);
99+
const updateStart = useCallback(
100+
(date: Moment) => {
101+
setStartDate(date);
102+
telemetry.reportAnomalyDetectionDateFieldChange({
103+
job_type: props.jobType,
104+
start_date: date.toISOString(),
105+
});
106+
},
107+
[telemetry, props.jobType]
108+
);
101109

102110
const createJobs = useCallback(() => {
111+
const date = moment(startDate).toDate();
103112
if (hasSummaries) {
113+
telemetry.reportAnomalyDetectionSetup({
114+
job_type: props.jobType,
115+
configured_fields: {
116+
start_date: date.toISOString(),
117+
partition_field: partitionField ? partitionField[0] : undefined,
118+
filter_field: filter ? filter : undefined,
119+
},
120+
});
104121
cleanUpAndSetUpModule(
105122
indices,
106-
moment(startDate).toDate().getTime(),
123+
date.getTime(),
107124
undefined,
108125
filterQuery,
109126
partitionField ? partitionField[0] : undefined
110127
);
111128
} else {
129+
telemetry.reportAnomalyDetectionSetup({
130+
job_type: props.jobType,
131+
configured_fields: {
132+
start_date: date.toISOString(),
133+
partition_field: partitionField ? partitionField[0] : undefined,
134+
filter_field: filter,
135+
},
136+
});
112137
setUpModule(
113138
indices,
114-
moment(startDate).toDate().getTime(),
139+
date.getTime(),
115140
undefined,
116141
filterQuery,
117142
partitionField ? partitionField[0] : undefined
@@ -125,22 +150,36 @@ export const JobSetupScreen = (props: Props) => {
125150
indices,
126151
partitionField,
127152
startDate,
153+
telemetry,
154+
filter,
155+
props.jobType,
128156
]);
129157

130158
const onFilterChange = useCallback(
131159
(f: string) => {
132160
setFilter(f || '');
133161
setFilterQuery(convertKueryToElasticSearchQuery(f, metricsView?.dataViewReference) || '');
162+
telemetry.reportAnomalyDetectionFilterFieldChange({
163+
job_type: props.jobType,
164+
filter_field: f ? f : undefined,
165+
});
134166
},
135-
[metricsView?.dataViewReference]
167+
[metricsView?.dataViewReference, telemetry, props.jobType]
136168
);
137169

138170
/* eslint-disable-next-line react-hooks/exhaustive-deps */
139171
const debouncedOnFilterChange = useCallback(debounce(onFilterChange, 500), [onFilterChange]);
140172

141-
const onPartitionFieldChange = useCallback((value: Array<{ label: string }>) => {
142-
setPartitionField(value.map((v) => v.label));
143-
}, []);
173+
const onPartitionFieldChange = useCallback(
174+
(value: Array<{ label: string }>) => {
175+
setPartitionField(value.map((v) => v.label));
176+
telemetry.reportAnomalyDetectionPartitionFieldChange({
177+
job_type: props.jobType,
178+
partition_field: value.length > 0 ? value[0].label : undefined,
179+
});
180+
},
181+
[telemetry, props.jobType]
182+
);
144183

145184
useEffect(() => {
146185
if (props.jobType === 'kubernetes') {

x-pack/plugins/observability_solution/infra/public/services/telemetry/telemetry_client.mock.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,8 @@ export const createTelemetryClientMock = (): jest.Mocked<ITelemetryClient> => ({
2121
reportAddMetricsCalloutTryItClicked: jest.fn(),
2222
reportAddMetricsCalloutLearnMoreClicked: jest.fn(),
2323
reportAddMetricsCalloutDismissed: jest.fn(),
24+
reportAnomalyDetectionSetup: jest.fn(),
25+
reportAnomalyDetectionDateFieldChange: jest.fn(),
26+
reportAnomalyDetectionFilterFieldChange: jest.fn(),
27+
reportAnomalyDetectionPartitionFieldChange: jest.fn(),
2428
});

x-pack/plugins/observability_solution/infra/public/services/telemetry/telemetry_client.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import type { AnalyticsServiceSetup } from '@kbn/core-analytics-server';
99
import { reportPerformanceMetricEvent } from '@kbn/ebt-tools';
1010
import {
1111
AddMetricsCalloutEventParams,
12+
AnomalyDetectionDateFieldChangeParams,
13+
AnomalyDetectionFilterFieldChangeParams,
14+
AnomalyDetectionPartitionFieldChangeParams,
15+
AnomalyDetectionSetupParams,
1216
AssetDashboardLoadedParams,
1317
AssetDetailsFlyoutViewedParams,
1418
AssetDetailsPageViewedParams,
@@ -114,4 +118,35 @@ export class TelemetryClient implements ITelemetryClient {
114118
public reportAddMetricsCalloutDismissed = (params: AddMetricsCalloutEventParams) => {
115119
this.analytics.reportEvent(InfraTelemetryEventTypes.ADD_METRICS_CALLOUT_DISMISSED, params);
116120
};
121+
122+
public reportAnomalyDetectionSetup = (params: AnomalyDetectionSetupParams) => {
123+
this.analytics.reportEvent(InfraTelemetryEventTypes.ANOMALY_DETECTION_SETUP, params);
124+
};
125+
126+
public reportAnomalyDetectionDateFieldChange = (
127+
params: AnomalyDetectionDateFieldChangeParams
128+
) => {
129+
this.analytics.reportEvent(
130+
InfraTelemetryEventTypes.ANOMALY_DETECTION_DATE_FIELD_CHANGE,
131+
params
132+
);
133+
};
134+
135+
public reportAnomalyDetectionPartitionFieldChange = (
136+
params: AnomalyDetectionPartitionFieldChangeParams
137+
) => {
138+
this.analytics.reportEvent(
139+
InfraTelemetryEventTypes.ANOMALY_DETECTION_PARTITION_FIELD_CHANGE,
140+
params
141+
);
142+
};
143+
144+
public reportAnomalyDetectionFilterFieldChange = (
145+
params: AnomalyDetectionFilterFieldChangeParams
146+
) => {
147+
this.analytics.reportEvent(
148+
InfraTelemetryEventTypes.ANOMALY_DETECTION_FILTER_FIELD_CHANGE,
149+
params
150+
);
151+
};
117152
}

x-pack/plugins/observability_solution/infra/public/services/telemetry/telemetry_events.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,98 @@ const addMetricsCalloutDismissed: InfraTelemetryEvent = {
264264
},
265265
};
266266

267+
const anomalyDetectionSetup: InfraTelemetryEvent = {
268+
eventType: InfraTelemetryEventTypes.ANOMALY_DETECTION_SETUP,
269+
schema: {
270+
job_type: {
271+
type: 'text',
272+
_meta: {
273+
description: 'Type of job for the anomaly detection',
274+
},
275+
},
276+
configured_fields: {
277+
properties: {
278+
start_date: {
279+
type: 'text',
280+
_meta: {
281+
description: 'Start date for the anomaly detection job',
282+
},
283+
},
284+
partition_field: {
285+
type: 'text',
286+
_meta: {
287+
description: 'Partition field for the anomaly detection job',
288+
optional: true,
289+
},
290+
},
291+
filter_field: {
292+
type: 'text',
293+
_meta: {
294+
description: 'Filter field for the anomaly detection job',
295+
optional: true,
296+
},
297+
},
298+
},
299+
},
300+
},
301+
};
302+
303+
const anomalyDetectionDateFieldChange: InfraTelemetryEvent = {
304+
eventType: InfraTelemetryEventTypes.ANOMALY_DETECTION_DATE_FIELD_CHANGE,
305+
schema: {
306+
job_type: {
307+
type: 'text',
308+
_meta: {
309+
description: 'Type of job for the anomaly detection',
310+
},
311+
},
312+
start_date: {
313+
type: 'text',
314+
_meta: {
315+
description: 'Start date for the anomaly detection job',
316+
},
317+
},
318+
},
319+
};
320+
321+
const anomalyDetectionPartitionFieldChange: InfraTelemetryEvent = {
322+
eventType: InfraTelemetryEventTypes.ANOMALY_DETECTION_PARTITION_FIELD_CHANGE,
323+
schema: {
324+
job_type: {
325+
type: 'text',
326+
_meta: {
327+
description: 'Type of job for the anomaly detection',
328+
},
329+
},
330+
partition_field: {
331+
type: 'text',
332+
_meta: {
333+
description: 'Partition field for the anomaly detection job',
334+
optional: true,
335+
},
336+
},
337+
},
338+
};
339+
340+
const anomalyDetectionFilterFieldChange: InfraTelemetryEvent = {
341+
eventType: InfraTelemetryEventTypes.ANOMALY_DETECTION_FILTER_FIELD_CHANGE,
342+
schema: {
343+
job_type: {
344+
type: 'text',
345+
_meta: {
346+
description: 'Type of job for the anomaly detection',
347+
},
348+
},
349+
filter_field: {
350+
type: 'text',
351+
_meta: {
352+
description: 'Filter field for the anomaly detection job',
353+
optional: true,
354+
},
355+
},
356+
},
357+
};
358+
267359
export const infraTelemetryEvents = [
268360
assetDetailsFlyoutViewed,
269361
assetDetailsPageViewed,
@@ -277,4 +369,8 @@ export const infraTelemetryEvents = [
277369
addMetricsCalloutTryItClicked,
278370
addMetricsCalloutLearnMoreClicked,
279371
addMetricsCalloutDismissed,
372+
anomalyDetectionSetup,
373+
anomalyDetectionDateFieldChange,
374+
anomalyDetectionPartitionFieldChange,
375+
anomalyDetectionFilterFieldChange,
280376
];

x-pack/plugins/observability_solution/infra/public/services/telemetry/telemetry_service.test.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,19 @@ describe('TelemetryService', () => {
5252
expect(telemetry).toHaveProperty('reportHostFlyoutFilterRemoved');
5353
expect(telemetry).toHaveProperty('reportHostFlyoutFilterAdded');
5454
expect(telemetry).toHaveProperty('reportHostsViewQuerySubmitted');
55+
expect(telemetry).toHaveProperty('reportHostsViewTotalHostCountRetrieved');
56+
expect(telemetry).toHaveProperty('reportAssetDetailsFlyoutViewed');
57+
expect(telemetry).toHaveProperty('reportAssetDetailsPageViewed');
58+
expect(telemetry).toHaveProperty('reportPerformanceMetricEvent');
59+
expect(telemetry).toHaveProperty('reportAssetDashboardLoaded');
60+
expect(telemetry).toHaveProperty('reportAddMetricsCalloutAddMetricsClicked');
61+
expect(telemetry).toHaveProperty('reportAddMetricsCalloutTryItClicked');
62+
expect(telemetry).toHaveProperty('reportAddMetricsCalloutLearnMoreClicked');
63+
expect(telemetry).toHaveProperty('reportAddMetricsCalloutDismissed');
64+
expect(telemetry).toHaveProperty('reportAnomalyDetectionSetup');
65+
expect(telemetry).toHaveProperty('reportAnomalyDetectionDateFieldChange');
66+
expect(telemetry).toHaveProperty('reportAnomalyDetectionPartitionFieldChange');
67+
expect(telemetry).toHaveProperty('reportAnomalyDetectionFilterFieldChange');
5568
});
5669
});
5770

@@ -343,4 +356,99 @@ describe('TelemetryService', () => {
343356
);
344357
});
345358
});
359+
360+
describe('#reportAnomalyDetectionSetup', () => {
361+
it('should report anomaly detection setup with properties', async () => {
362+
const setupParams = getSetupParams();
363+
service.setup(setupParams);
364+
const telemetry = service.start();
365+
const jobType = 'host';
366+
const configuredFields = {
367+
start_date: new Date().toISOString(),
368+
partition_field: 'partitionField',
369+
filter_field: 'filterField',
370+
};
371+
372+
telemetry.reportAnomalyDetectionSetup({
373+
job_type: jobType,
374+
configured_fields: configuredFields,
375+
});
376+
377+
expect(setupParams.analytics.reportEvent).toHaveBeenCalledTimes(1);
378+
expect(setupParams.analytics.reportEvent).toHaveBeenCalledWith(
379+
'Infra Anomaly Detection Job Setup',
380+
{
381+
job_type: jobType,
382+
configured_fields: configuredFields,
383+
}
384+
);
385+
});
386+
});
387+
388+
describe('#reportAnomalyDetectionDateFieldChange', () => {
389+
it('should report anomaly detection date field change with properties', async () => {
390+
const setupParams = getSetupParams();
391+
service.setup(setupParams);
392+
const telemetry = service.start();
393+
const startDate = new Date().toISOString();
394+
395+
telemetry.reportAnomalyDetectionDateFieldChange({
396+
job_type: 'host',
397+
start_date: startDate,
398+
});
399+
400+
expect(setupParams.analytics.reportEvent).toHaveBeenCalledTimes(1);
401+
expect(setupParams.analytics.reportEvent).toHaveBeenCalledWith(
402+
'Infra Anomaly Detection Job Date Field Change',
403+
{
404+
job_type: 'host',
405+
start_date: startDate,
406+
}
407+
);
408+
});
409+
});
410+
411+
describe('#reportAnomalyDetectionPartitionFieldChange', () => {
412+
it('should report anomaly detection partition field change with properties', async () => {
413+
const setupParams = getSetupParams();
414+
service.setup(setupParams);
415+
const telemetry = service.start();
416+
417+
telemetry.reportAnomalyDetectionPartitionFieldChange({
418+
job_type: 'host',
419+
partition_field: 'partitionField',
420+
});
421+
422+
expect(setupParams.analytics.reportEvent).toHaveBeenCalledTimes(1);
423+
expect(setupParams.analytics.reportEvent).toHaveBeenCalledWith(
424+
'Infra Anomaly Detection Job Partition Field Change',
425+
{
426+
job_type: 'host',
427+
partition_field: 'partitionField',
428+
}
429+
);
430+
});
431+
});
432+
433+
describe('#reportAnomalyDetectionFilterFieldChange', () => {
434+
it('should report anomaly detection filter field change with properties', async () => {
435+
const setupParams = getSetupParams();
436+
service.setup(setupParams);
437+
const telemetry = service.start();
438+
439+
telemetry.reportAnomalyDetectionFilterFieldChange({
440+
job_type: 'host',
441+
filter_field: 'filterField',
442+
});
443+
444+
expect(setupParams.analytics.reportEvent).toHaveBeenCalledTimes(1);
445+
expect(setupParams.analytics.reportEvent).toHaveBeenCalledWith(
446+
'Infra Anomaly Detection Job Filter Field Change',
447+
{
448+
job_type: 'host',
449+
filter_field: 'filterField',
450+
}
451+
);
452+
});
453+
});
346454
});

0 commit comments

Comments
 (0)