From 7e97dd90e78199f2b90725b075d60df427fab876 Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Wed, 25 Oct 2023 08:34:06 -0600 Subject: [PATCH] [ML][AIOps] Telemetry: Track change point detection runs (#169158) ## Summary This PR adds UI tracking for Change Point Detection for AIOps. - tracks type of analysis and source (where the analysis is being run from) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Quynh Nguyen (Quinn) <43350163+qn895@users.noreply.github.com> --- x-pack/plugins/aiops/common/constants.ts | 2 ++ .../change_point_detection_root.tsx | 3 ++ .../change_point_detection/constants.ts | 6 ++++ .../use_change_point_agg_request.ts | 29 +++++++++++++++++++ .../embeddable_change_point_chart.tsx | 11 +++++-- ...mbeddable_change_point_chart_component.tsx | 1 - .../embeddable_change_point_chart_factory.ts | 7 +++-- .../public/hooks/use_aiops_app_context.ts | 7 +++++ x-pack/plugins/aiops/public/types.ts | 2 ++ x-pack/plugins/aiops/tsconfig.json | 1 + .../aiops/change_point_detection.tsx | 1 + 11 files changed, 65 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/aiops/common/constants.ts b/x-pack/plugins/aiops/common/constants.ts index 47bdee0d5e6c6a..5916464e909804 100644 --- a/x-pack/plugins/aiops/common/constants.ts +++ b/x-pack/plugins/aiops/common/constants.ts @@ -30,3 +30,5 @@ export const AIOPS_TELEMETRY_ID = { AIOPS_DEFAULT_SOURCE: 'ml_aiops_labs', AIOPS_ANALYSIS_RUN_ORIGIN: 'aiops-analysis-run-origin', } as const; + +export const EMBEDDABLE_ORIGIN = 'embeddable'; diff --git a/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_root.tsx b/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_root.tsx index 414e214fd1fe74..b63e17e2e0d867 100644 --- a/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_root.tsx +++ b/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_root.tsx @@ -37,6 +37,7 @@ import { } from './change_point_detection_context'; import { timeSeriesDataViewWarning } from '../../application/utils/time_series_dataview_check'; import { ReloadContextProvider } from '../../hooks/use_reload'; +import { AIOPS_TELEMETRY_ID } from '../../../common/constants'; const localStorage = new Storage(window.localStorage); @@ -76,6 +77,8 @@ export const ChangePointDetectionAppState: FC return <>{warning}; } + appDependencies.embeddingOrigin = AIOPS_TELEMETRY_ID.AIOPS_DEFAULT_SOURCE; + const PresentationContextProvider = appDependencies.presentationUtil?.ContextProvider ?? React.Fragment; diff --git a/x-pack/plugins/aiops/public/components/change_point_detection/constants.ts b/x-pack/plugins/aiops/public/components/change_point_detection/constants.ts index 0219b3ac87fc00..6e49f9fe0fa707 100644 --- a/x-pack/plugins/aiops/public/components/change_point_detection/constants.ts +++ b/x-pack/plugins/aiops/public/components/change_point_detection/constants.ts @@ -38,3 +38,9 @@ export const EXCLUDED_CHANGE_POINT_TYPES = new Set([ ]); export const MAX_CHANGE_POINT_CONFIGS = 6; + +export const CHANGE_POINT_DETECTION_EVENT = { + RUN: 'ran_aiops_change_point_detection', + SUCCESS: 'aiops_change_point_detection_success', + ERROR: 'aiops_change_point_detection_error', +} as const; diff --git a/x-pack/plugins/aiops/public/components/change_point_detection/use_change_point_agg_request.ts b/x-pack/plugins/aiops/public/components/change_point_detection/use_change_point_agg_request.ts index a574ae7abd09ba..0393ab5e5a6fca 100644 --- a/x-pack/plugins/aiops/public/components/change_point_detection/use_change_point_agg_request.ts +++ b/x-pack/plugins/aiops/public/components/change_point_detection/use_change_point_agg_request.ts @@ -13,6 +13,7 @@ import type { MappingRuntimeFields, SearchRequest, } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { METRIC_TYPE } from '@kbn/analytics'; import { useReload } from '../../hooks/use_reload'; import { useAiopsAppContext } from '../../hooks/use_aiops_app_context'; import { @@ -28,6 +29,7 @@ import { COMPOSITE_AGG_SIZE, EXCLUDED_CHANGE_POINT_TYPES, SPLIT_FIELD_CARDINALITY_LIMIT, + CHANGE_POINT_DETECTION_EVENT, } from './constants'; interface RequestOptions { @@ -122,6 +124,8 @@ export function useChangePointResults( ) { const { notifications: { toasts }, + usageCollection, + embeddingOrigin, } = useAiopsAppContext(); const { dataView } = useDataSource(); @@ -187,11 +191,27 @@ export function useChangePointResults( runtimeMappings ); + if (usageCollection?.reportUiCounter && embeddingOrigin) { + usageCollection.reportUiCounter( + embeddingOrigin, + METRIC_TYPE.COUNT, + CHANGE_POINT_DETECTION_EVENT.RUN + ); + } + const result = await runRequest< { params: SearchRequest }, { rawResponse: ChangePointAggResponse } >({ params: requestPayload }); + if (usageCollection?.reportUiCounter && embeddingOrigin) { + usageCollection.reportUiCounter( + embeddingOrigin, + METRIC_TYPE.COUNT, + CHANGE_POINT_DETECTION_EVENT.SUCCESS + ); + } + if (result === null) { setProgress(null); return; @@ -257,6 +277,13 @@ export function useChangePointResults( ); } } catch (e) { + if (usageCollection?.reportUiCounter && embeddingOrigin) { + usageCollection.reportUiCounter( + embeddingOrigin, + METRIC_TYPE.COUNT, + CHANGE_POINT_DETECTION_EVENT.ERROR + ); + } toasts.addError(e, { title: i18n.translate('xpack.aiops.changePointDetection.fetchErrorTitle', { defaultMessage: 'Failed to fetch change points', @@ -265,6 +292,7 @@ export function useChangePointResults( } }, [ + embeddingOrigin, isSingleMetric, totalAggPages, dataView, @@ -278,6 +306,7 @@ export function useChangePointResults( splitFieldsOptions, runRequest, toasts, + usageCollection, ] ); diff --git a/x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart.tsx b/x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart.tsx index af5942024ec99d..f9d2109d88df6b 100644 --- a/x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart.tsx +++ b/x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart.tsx @@ -21,9 +21,10 @@ import { DatePickerContextProvider } from '@kbn/ml-date-picker'; import { pick } from 'lodash'; import { LensPublicStart } from '@kbn/lens-plugin/public'; import { Subject } from 'rxjs'; +import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/common'; import { EmbeddableInputTracker } from './embeddable_chart_component_wrapper'; -import { EMBEDDABLE_CHANGE_POINT_CHART_TYPE } from '../../common/constants'; +import { EMBEDDABLE_CHANGE_POINT_CHART_TYPE, EMBEDDABLE_ORIGIN } from '../../common/constants'; import { AiopsAppContext, type AiopsAppDependencies } from '../hooks/use_aiops_app_context'; import { EmbeddableChangePointChartProps } from './embeddable_change_point_chart_component'; @@ -40,6 +41,7 @@ export interface EmbeddableChangePointChartDeps { notifications: CoreStart['notifications']; i18n: CoreStart['i18n']; lens: LensPublicStart; + usageCollection: UsageCollectionSetup; } export type IEmbeddableChangePointChart = typeof EmbeddableChangePointChart; @@ -121,10 +123,15 @@ export class EmbeddableChangePointChart extends AbstractEmbeddable< const input = this.getInput(); const input$ = this.getInput$(); + const aiopsAppContextValue = { + ...this.deps, + embeddingOrigin: this.parent?.type ?? EMBEDDABLE_ORIGIN, + } as unknown as AiopsAppDependencies; + ReactDOM.render( - + ( diff --git a/x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart_factory.ts b/x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart_factory.ts index 9bf35b0ca2b1a8..ef7c3a431cc180 100644 --- a/x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart_factory.ts +++ b/x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart_factory.ts @@ -71,8 +71,10 @@ export class EmbeddableChangePointChartFactory implements EmbeddableFactoryDefin async create(input: EmbeddableChangePointChartInput, parent?: IContainer) { try { - const [{ i18n: i18nService, theme, http, uiSettings, notifications }, { lens, data }] = - await this.getStartServices(); + const [ + { i18n: i18nService, theme, http, uiSettings, notifications }, + { lens, data, usageCollection }, + ] = await this.getStartServices(); return new EmbeddableChangePointChart( { @@ -83,6 +85,7 @@ export class EmbeddableChangePointChartFactory implements EmbeddableFactoryDefin data, notifications, lens, + usageCollection, }, input, parent diff --git a/x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts b/x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts index aa364a416a0468..5714ae5283fb29 100644 --- a/x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts +++ b/x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts @@ -32,6 +32,7 @@ import type { TimeRange as TimeRangeMs } from '@kbn/ml-date-picker'; import type { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public'; import type { EmbeddableStart } from '@kbn/embeddable-plugin/public'; import type { CasesUiStart } from '@kbn/cases-plugin/public'; +import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public'; /** * AIOps App Dependencies to be provided via React context. @@ -84,6 +85,10 @@ export interface AiopsAppDependencies { * Unified search. */ unifiedSearch: UnifiedSearchPublicPluginStart; + /** + * Usage collection. + */ + usageCollection?: UsageCollectionSetup; /** * Used to create deep links to other plugins. */ @@ -115,6 +120,8 @@ export interface AiopsAppDependencies { embeddable?: EmbeddableStart; cases?: CasesUiStart; isServerless?: boolean; + /** Identifier to indicate the plugin utilizing the component */ + embeddingOrigin?: string; } /** diff --git a/x-pack/plugins/aiops/public/types.ts b/x-pack/plugins/aiops/public/types.ts index e0f86c68864bd3..8b40d4c257434c 100755 --- a/x-pack/plugins/aiops/public/types.ts +++ b/x-pack/plugins/aiops/public/types.ts @@ -18,6 +18,7 @@ import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/ import type { EmbeddableSetup, EmbeddableStart } from '@kbn/embeddable-plugin/public'; import type { CasesUiSetup } from '@kbn/cases-plugin/public'; import type { LicensingPluginSetup } from '@kbn/licensing-plugin/public'; +import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public'; import type { EmbeddableChangePointChartInput } from './embeddable/embeddable_change_point_chart'; export interface AiopsPluginSetupDeps { @@ -40,6 +41,7 @@ export interface AiopsPluginStartDeps { licensing: LicensingPluginStart; executionContext: ExecutionContextStart; embeddable: EmbeddableStart; + usageCollection: UsageCollectionSetup; } export type AiopsPluginSetup = void; diff --git a/x-pack/plugins/aiops/tsconfig.json b/x-pack/plugins/aiops/tsconfig.json index 1c0095046c7359..67e8908f5c4213 100644 --- a/x-pack/plugins/aiops/tsconfig.json +++ b/x-pack/plugins/aiops/tsconfig.json @@ -65,6 +65,7 @@ "@kbn/react-kibana-mount", "@kbn/ml-chi2test", "@kbn/usage-collection-plugin", + "@kbn/analytics", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/ml/public/application/aiops/change_point_detection.tsx b/x-pack/plugins/ml/public/application/aiops/change_point_detection.tsx index 774c3ac6f9d2d6..551e19a2644634 100644 --- a/x-pack/plugins/ml/public/application/aiops/change_point_detection.tsx +++ b/x-pack/plugins/ml/public/application/aiops/change_point_detection.tsx @@ -67,6 +67,7 @@ export const ChangePointDetectionPage: FC = () => { 'embeddable', 'cases', 'i18n', + 'usageCollection', ]), fieldStats: { useFieldStatsTrigger, FieldStatsFlyoutProvider }, }}