Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;

Expand Down Expand Up @@ -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
Expand All @@ -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') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
});
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -277,4 +369,8 @@ export const infraTelemetryEvents = [
addMetricsCalloutTryItClicked,
addMetricsCalloutLearnMoreClicked,
addMetricsCalloutDismissed,
anomalyDetectionSetup,
anomalyDetectionDateFieldChange,
anomalyDetectionPartitionFieldChange,
anomalyDetectionFilterFieldChange,
];
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});
});

Expand Down Expand Up @@ -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',
}
);
});
});
});
Loading