[ObsUX][Infra] Add telemetry for anomaly job creation (#198061)

Closes https://github.com/elastic/kibana/issues/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\"
  }  
}
```
This commit is contained in:
Miriam 2024-10-30 20:45:48 +00:00 committed by GitHub
parent 0cc8945712
commit 227aaf3e14
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 343 additions and 11 deletions

View file

@ -38,7 +38,7 @@ import { FixedDatePicker } from '../../fixed_datepicker';
import { DEFAULT_K8S_PARTITION_FIELD } from '../../../containers/ml/modules/metrics_k8s/module_descriptor';
import { convertKueryToElasticSearchQuery } from '../../../utils/kuery';
import { INFRA_ML_FLYOUT_FEEDBACK_LINK } from './flyout_home';
import { KibanaEnvironmentContext } from '../../../hooks/use_kibana';
import { KibanaEnvironmentContext, useKibanaContextForPlugin } from '../../../hooks/use_kibana';
import { MetricsExplorerKueryBar } from '../../../pages/metrics/metrics_explorer/components/kuery_bar';
interface Props {
@ -60,6 +60,7 @@ export const JobSetupScreen = (props: Props) => {
const trackMetric = useUiTracker({ app: 'infra_metrics' });
const { kibanaVersion, isCloudEnv, isServerlessEnv } = useContext(KibanaEnvironmentContext);
const { euiTheme } = useEuiTheme();
const { telemetry } = useKibanaContextForPlugin().services;
const indices = host.sourceConfiguration.indices;
@ -95,23 +96,47 @@ export const JobSetupScreen = (props: Props) => {
}
}, [props.jobType, kubernetes.jobSummaries, host.jobSummaries]);
const updateStart = useCallback((date: Moment) => {
setStartDate(date);
}, []);
const updateStart = useCallback(
(date: Moment) => {
setStartDate(date);
telemetry.reportAnomalyDetectionDateFieldChange({
job_type: props.jobType,
start_date: date.toISOString(),
});
},
[telemetry, props.jobType]
);
const createJobs = useCallback(() => {
const date = moment(startDate).toDate();
if (hasSummaries) {
telemetry.reportAnomalyDetectionSetup({
job_type: props.jobType,
configured_fields: {
start_date: date.toISOString(),
partition_field: partitionField ? partitionField[0] : undefined,
filter_field: filter ? filter : undefined,
},
});
cleanUpAndSetUpModule(
indices,
moment(startDate).toDate().getTime(),
date.getTime(),
undefined,
filterQuery,
partitionField ? partitionField[0] : undefined
);
} else {
telemetry.reportAnomalyDetectionSetup({
job_type: props.jobType,
configured_fields: {
start_date: date.toISOString(),
partition_field: partitionField ? partitionField[0] : undefined,
filter_field: filter,
},
});
setUpModule(
indices,
moment(startDate).toDate().getTime(),
date.getTime(),
undefined,
filterQuery,
partitionField ? partitionField[0] : undefined
@ -125,22 +150,36 @@ export const JobSetupScreen = (props: Props) => {
indices,
partitionField,
startDate,
telemetry,
filter,
props.jobType,
]);
const onFilterChange = useCallback(
(f: string) => {
setFilter(f || '');
setFilterQuery(convertKueryToElasticSearchQuery(f, metricsView?.dataViewReference) || '');
telemetry.reportAnomalyDetectionFilterFieldChange({
job_type: props.jobType,
filter_field: f ? f : undefined,
});
},
[metricsView?.dataViewReference]
[metricsView?.dataViewReference, telemetry, props.jobType]
);
/* eslint-disable-next-line react-hooks/exhaustive-deps */
const debouncedOnFilterChange = useCallback(debounce(onFilterChange, 500), [onFilterChange]);
const onPartitionFieldChange = useCallback((value: Array<{ label: string }>) => {
setPartitionField(value.map((v) => v.label));
}, []);
const onPartitionFieldChange = useCallback(
(value: Array<{ label: string }>) => {
setPartitionField(value.map((v) => v.label));
telemetry.reportAnomalyDetectionPartitionFieldChange({
job_type: props.jobType,
partition_field: value.length > 0 ? value[0].label : undefined,
});
},
[telemetry, props.jobType]
);
useEffect(() => {
if (props.jobType === 'kubernetes') {

View file

@ -21,4 +21,8 @@ export const createTelemetryClientMock = (): jest.Mocked<ITelemetryClient> => ({
reportAddMetricsCalloutTryItClicked: jest.fn(),
reportAddMetricsCalloutLearnMoreClicked: jest.fn(),
reportAddMetricsCalloutDismissed: jest.fn(),
reportAnomalyDetectionSetup: jest.fn(),
reportAnomalyDetectionDateFieldChange: jest.fn(),
reportAnomalyDetectionFilterFieldChange: jest.fn(),
reportAnomalyDetectionPartitionFieldChange: jest.fn(),
});

View file

@ -9,6 +9,10 @@ import type { AnalyticsServiceSetup } from '@kbn/core-analytics-server';
import { reportPerformanceMetricEvent } from '@kbn/ebt-tools';
import {
AddMetricsCalloutEventParams,
AnomalyDetectionDateFieldChangeParams,
AnomalyDetectionFilterFieldChangeParams,
AnomalyDetectionPartitionFieldChangeParams,
AnomalyDetectionSetupParams,
AssetDashboardLoadedParams,
AssetDetailsFlyoutViewedParams,
AssetDetailsPageViewedParams,
@ -114,4 +118,35 @@ export class TelemetryClient implements ITelemetryClient {
public reportAddMetricsCalloutDismissed = (params: AddMetricsCalloutEventParams) => {
this.analytics.reportEvent(InfraTelemetryEventTypes.ADD_METRICS_CALLOUT_DISMISSED, params);
};
public reportAnomalyDetectionSetup = (params: AnomalyDetectionSetupParams) => {
this.analytics.reportEvent(InfraTelemetryEventTypes.ANOMALY_DETECTION_SETUP, params);
};
public reportAnomalyDetectionDateFieldChange = (
params: AnomalyDetectionDateFieldChangeParams
) => {
this.analytics.reportEvent(
InfraTelemetryEventTypes.ANOMALY_DETECTION_DATE_FIELD_CHANGE,
params
);
};
public reportAnomalyDetectionPartitionFieldChange = (
params: AnomalyDetectionPartitionFieldChangeParams
) => {
this.analytics.reportEvent(
InfraTelemetryEventTypes.ANOMALY_DETECTION_PARTITION_FIELD_CHANGE,
params
);
};
public reportAnomalyDetectionFilterFieldChange = (
params: AnomalyDetectionFilterFieldChangeParams
) => {
this.analytics.reportEvent(
InfraTelemetryEventTypes.ANOMALY_DETECTION_FILTER_FIELD_CHANGE,
params
);
};
}

View file

@ -264,6 +264,98 @@ const addMetricsCalloutDismissed: InfraTelemetryEvent = {
},
};
const anomalyDetectionSetup: InfraTelemetryEvent = {
eventType: InfraTelemetryEventTypes.ANOMALY_DETECTION_SETUP,
schema: {
job_type: {
type: 'text',
_meta: {
description: 'Type of job for the anomaly detection',
},
},
configured_fields: {
properties: {
start_date: {
type: 'text',
_meta: {
description: 'Start date for the anomaly detection job',
},
},
partition_field: {
type: 'text',
_meta: {
description: 'Partition field for the anomaly detection job',
optional: true,
},
},
filter_field: {
type: 'text',
_meta: {
description: 'Filter field for the anomaly detection job',
optional: true,
},
},
},
},
},
};
const anomalyDetectionDateFieldChange: InfraTelemetryEvent = {
eventType: InfraTelemetryEventTypes.ANOMALY_DETECTION_DATE_FIELD_CHANGE,
schema: {
job_type: {
type: 'text',
_meta: {
description: 'Type of job for the anomaly detection',
},
},
start_date: {
type: 'text',
_meta: {
description: 'Start date for the anomaly detection job',
},
},
},
};
const anomalyDetectionPartitionFieldChange: InfraTelemetryEvent = {
eventType: InfraTelemetryEventTypes.ANOMALY_DETECTION_PARTITION_FIELD_CHANGE,
schema: {
job_type: {
type: 'text',
_meta: {
description: 'Type of job for the anomaly detection',
},
},
partition_field: {
type: 'text',
_meta: {
description: 'Partition field for the anomaly detection job',
optional: true,
},
},
},
};
const anomalyDetectionFilterFieldChange: InfraTelemetryEvent = {
eventType: InfraTelemetryEventTypes.ANOMALY_DETECTION_FILTER_FIELD_CHANGE,
schema: {
job_type: {
type: 'text',
_meta: {
description: 'Type of job for the anomaly detection',
},
},
filter_field: {
type: 'text',
_meta: {
description: 'Filter field for the anomaly detection job',
optional: true,
},
},
},
};
export const infraTelemetryEvents = [
assetDetailsFlyoutViewed,
assetDetailsPageViewed,
@ -277,4 +369,8 @@ export const infraTelemetryEvents = [
addMetricsCalloutTryItClicked,
addMetricsCalloutLearnMoreClicked,
addMetricsCalloutDismissed,
anomalyDetectionSetup,
anomalyDetectionDateFieldChange,
anomalyDetectionPartitionFieldChange,
anomalyDetectionFilterFieldChange,
];

View file

@ -52,6 +52,19 @@ describe('TelemetryService', () => {
expect(telemetry).toHaveProperty('reportHostFlyoutFilterRemoved');
expect(telemetry).toHaveProperty('reportHostFlyoutFilterAdded');
expect(telemetry).toHaveProperty('reportHostsViewQuerySubmitted');
expect(telemetry).toHaveProperty('reportHostsViewTotalHostCountRetrieved');
expect(telemetry).toHaveProperty('reportAssetDetailsFlyoutViewed');
expect(telemetry).toHaveProperty('reportAssetDetailsPageViewed');
expect(telemetry).toHaveProperty('reportPerformanceMetricEvent');
expect(telemetry).toHaveProperty('reportAssetDashboardLoaded');
expect(telemetry).toHaveProperty('reportAddMetricsCalloutAddMetricsClicked');
expect(telemetry).toHaveProperty('reportAddMetricsCalloutTryItClicked');
expect(telemetry).toHaveProperty('reportAddMetricsCalloutLearnMoreClicked');
expect(telemetry).toHaveProperty('reportAddMetricsCalloutDismissed');
expect(telemetry).toHaveProperty('reportAnomalyDetectionSetup');
expect(telemetry).toHaveProperty('reportAnomalyDetectionDateFieldChange');
expect(telemetry).toHaveProperty('reportAnomalyDetectionPartitionFieldChange');
expect(telemetry).toHaveProperty('reportAnomalyDetectionFilterFieldChange');
});
});
@ -343,4 +356,99 @@ describe('TelemetryService', () => {
);
});
});
describe('#reportAnomalyDetectionSetup', () => {
it('should report anomaly detection setup with properties', async () => {
const setupParams = getSetupParams();
service.setup(setupParams);
const telemetry = service.start();
const jobType = 'host';
const configuredFields = {
start_date: new Date().toISOString(),
partition_field: 'partitionField',
filter_field: 'filterField',
};
telemetry.reportAnomalyDetectionSetup({
job_type: jobType,
configured_fields: configuredFields,
});
expect(setupParams.analytics.reportEvent).toHaveBeenCalledTimes(1);
expect(setupParams.analytics.reportEvent).toHaveBeenCalledWith(
'Infra Anomaly Detection Job Setup',
{
job_type: jobType,
configured_fields: configuredFields,
}
);
});
});
describe('#reportAnomalyDetectionDateFieldChange', () => {
it('should report anomaly detection date field change with properties', async () => {
const setupParams = getSetupParams();
service.setup(setupParams);
const telemetry = service.start();
const startDate = new Date().toISOString();
telemetry.reportAnomalyDetectionDateFieldChange({
job_type: 'host',
start_date: startDate,
});
expect(setupParams.analytics.reportEvent).toHaveBeenCalledTimes(1);
expect(setupParams.analytics.reportEvent).toHaveBeenCalledWith(
'Infra Anomaly Detection Job Date Field Change',
{
job_type: 'host',
start_date: startDate,
}
);
});
});
describe('#reportAnomalyDetectionPartitionFieldChange', () => {
it('should report anomaly detection partition field change with properties', async () => {
const setupParams = getSetupParams();
service.setup(setupParams);
const telemetry = service.start();
telemetry.reportAnomalyDetectionPartitionFieldChange({
job_type: 'host',
partition_field: 'partitionField',
});
expect(setupParams.analytics.reportEvent).toHaveBeenCalledTimes(1);
expect(setupParams.analytics.reportEvent).toHaveBeenCalledWith(
'Infra Anomaly Detection Job Partition Field Change',
{
job_type: 'host',
partition_field: 'partitionField',
}
);
});
});
describe('#reportAnomalyDetectionFilterFieldChange', () => {
it('should report anomaly detection filter field change with properties', async () => {
const setupParams = getSetupParams();
service.setup(setupParams);
const telemetry = service.start();
telemetry.reportAnomalyDetectionFilterFieldChange({
job_type: 'host',
filter_field: 'filterField',
});
expect(setupParams.analytics.reportEvent).toHaveBeenCalledTimes(1);
expect(setupParams.analytics.reportEvent).toHaveBeenCalledWith(
'Infra Anomaly Detection Job Filter Field Change',
{
job_type: 'host',
filter_field: 'filterField',
}
);
});
});
});

View file

@ -26,6 +26,10 @@ export enum InfraTelemetryEventTypes {
ADD_METRICS_CALLOUT_TRY_IT_CLICKED = 'Add Metrics Callout Try It Clicked',
ADD_METRICS_CALLOUT_LEARN_MORE_CLICKED = 'Add Metrics Callout Learn More Clicked',
ADD_METRICS_CALLOUT_DISMISSED = 'Add Metrics Callout Dismissed',
ANOMALY_DETECTION_SETUP = 'Infra Anomaly Detection Job Setup',
ANOMALY_DETECTION_DATE_FIELD_CHANGE = 'Infra Anomaly Detection Job Date Field Change',
ANOMALY_DETECTION_PARTITION_FIELD_CHANGE = 'Infra Anomaly Detection Job Partition Field Change',
ANOMALY_DETECTION_FILTER_FIELD_CHANGE = 'Infra Anomaly Detection Job Filter Field Change',
}
export interface HostsViewQuerySubmittedParams {
@ -69,6 +73,26 @@ export interface AddMetricsCalloutEventParams {
view: string;
}
export interface AnomalyDetectionSetupParams {
job_type: string;
configured_fields: { start_date: string; partition_field?: string; filter_field?: string };
}
export interface AnomalyDetectionDateFieldChangeParams {
job_type: string;
start_date: string;
}
export interface AnomalyDetectionPartitionFieldChangeParams {
job_type: string;
partition_field?: string;
}
export interface AnomalyDetectionFilterFieldChangeParams {
job_type: string;
filter_field?: string;
}
export type InfraTelemetryEventParams =
| HostsViewQuerySubmittedParams
| HostEntryClickedParams
@ -76,7 +100,11 @@ export type InfraTelemetryEventParams =
| HostsViewQueryHostsCountRetrievedParams
| AssetDetailsFlyoutViewedParams
| AssetDashboardLoadedParams
| AddMetricsCalloutEventParams;
| AddMetricsCalloutEventParams
| AnomalyDetectionSetupParams
| AnomalyDetectionDateFieldChangeParams
| AnomalyDetectionPartitionFieldChangeParams
| AnomalyDetectionFilterFieldChangeParams;
export interface PerformanceMetricInnerEvents {
key1?: string;
@ -102,6 +130,12 @@ export interface ITelemetryClient {
reportAddMetricsCalloutTryItClicked(params: AddMetricsCalloutEventParams): void;
reportAddMetricsCalloutLearnMoreClicked(params: AddMetricsCalloutEventParams): void;
reportAddMetricsCalloutDismissed(params: AddMetricsCalloutEventParams): void;
reportAnomalyDetectionSetup(params: AnomalyDetectionSetupParams): void;
reportAnomalyDetectionDateFieldChange(params: AnomalyDetectionDateFieldChangeParams): void;
reportAnomalyDetectionPartitionFieldChange(
params: AnomalyDetectionPartitionFieldChangeParams
): void;
reportAnomalyDetectionFilterFieldChange(params: AnomalyDetectionFilterFieldChangeParams): void;
}
export type InfraTelemetryEvent =
@ -152,4 +186,20 @@ export type InfraTelemetryEvent =
| {
eventType: InfraTelemetryEventTypes.ADD_METRICS_CALLOUT_DISMISSED;
schema: RootSchema<AddMetricsCalloutEventParams>;
}
| {
eventType: InfraTelemetryEventTypes.ANOMALY_DETECTION_SETUP;
schema: RootSchema<AnomalyDetectionSetupParams>;
}
| {
eventType: InfraTelemetryEventTypes.ANOMALY_DETECTION_DATE_FIELD_CHANGE;
schema: RootSchema<AnomalyDetectionDateFieldChangeParams>;
}
| {
eventType: InfraTelemetryEventTypes.ANOMALY_DETECTION_PARTITION_FIELD_CHANGE;
schema: RootSchema<AnomalyDetectionPartitionFieldChangeParams>;
}
| {
eventType: InfraTelemetryEventTypes.ANOMALY_DETECTION_FILTER_FIELD_CHANGE;
schema: RootSchema<AnomalyDetectionFilterFieldChangeParams>;
};