From d608f37c230219db8cb78dd9a97b35c561cc5eb7 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Fri, 21 Jun 2024 08:17:56 +0200 Subject: [PATCH] [Synthetucs] Added perf metrics for es queries (#186313) ## Summary Added perf metrics for es queries !! Fixes https://github.com/elastic/synthetics-dev/issues/351 Started reporting query time for exploratory based visualizations used in Synthetics Test data can be seen on staging telemetry cluster !! image --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../embeddable/embeddable.tsx | 18 ++++++- .../exploratory_view/embeddable/index.tsx | 6 ++- .../hooks/use_ebt_telemetry.ts | 52 +++++++++++++++++++ .../exploratory_view/public/plugin.ts | 10 +++- .../exploratory_view/tsconfig.json | 5 +- 5 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 x-pack/plugins/observability_solution/exploratory_view/public/components/shared/exploratory_view/hooks/use_ebt_telemetry.ts diff --git a/x-pack/plugins/observability_solution/exploratory_view/public/components/shared/exploratory_view/embeddable/embeddable.tsx b/x-pack/plugins/observability_solution/exploratory_view/public/components/shared/exploratory_view/embeddable/embeddable.tsx index ed06d786124f39..a0079568803b66 100644 --- a/x-pack/plugins/observability_solution/exploratory_view/public/components/shared/exploratory_view/embeddable/embeddable.tsx +++ b/x-pack/plugins/observability_solution/exploratory_view/public/components/shared/exploratory_view/embeddable/embeddable.tsx @@ -18,6 +18,8 @@ import { import { ViewMode } from '@kbn/embeddable-plugin/common'; import { observabilityFeatureId } from '@kbn/observability-shared-plugin/public'; import styled from 'styled-components'; +import { AnalyticsServiceSetup } from '@kbn/core-analytics-browser'; +import { useEBTTelemetry } from '../hooks/use_ebt_telemetry'; import { AllSeries } from '../../../..'; import { AppDataType, ReportViewType } from '../types'; import { OperationTypeComponent } from '../series_editor/columns/operation_type_select'; @@ -61,6 +63,7 @@ export interface ExploratoryEmbeddableComponentProps extends ExploratoryEmbeddab lens: LensPublicStart; dataViewState: DataViewState; lensFormulaHelper?: FormulaPublicApi; + analytics?: AnalyticsServiceSetup; } // eslint-disable-next-line import/no-default-export @@ -88,6 +91,7 @@ export default function Embeddable(props: ExploratoryEmbeddableComponentProps) { lineHeight = 32, searchSessionId, onLoad, + analytics, } = props; const LensComponent = lens?.EmbeddableComponent; const LensSaveModalComponent = lens?.SaveModalComponent; @@ -103,6 +107,15 @@ export default function Embeddable(props: ExploratoryEmbeddableComponentProps) { const timeRange = customTimeRange ?? series?.time; + const { reportEvent } = useEBTTelemetry({ + analytics, + queryName: series + ? `${series.dataType}_${series.name}` + : typeof title === 'string' + ? title + : 'Exp View embeddable query', + }); + const actions = useActions({ withActions, attributes, @@ -198,7 +211,10 @@ export default function Embeddable(props: ExploratoryEmbeddableComponentProps) { extraActions={actions} viewMode={ViewMode.VIEW} searchSessionId={searchSessionId} - onLoad={onLoad} + onLoad={(loading, inspectorAdapters) => { + reportEvent(inspectorAdapters); + onLoad?.(loading); + }} /> {isSaveOpen && attributesJSON && ( diff --git a/x-pack/plugins/observability_solution/exploratory_view/public/components/shared/exploratory_view/hooks/use_ebt_telemetry.ts b/x-pack/plugins/observability_solution/exploratory_view/public/components/shared/exploratory_view/hooks/use_ebt_telemetry.ts new file mode 100644 index 00000000000000..639b6332ab6122 --- /dev/null +++ b/x-pack/plugins/observability_solution/exploratory_view/public/components/shared/exploratory_view/hooks/use_ebt_telemetry.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DefaultInspectorAdapters } from '@kbn/expressions-plugin/common'; +import { reportPerformanceMetricEvent } from '@kbn/ebt-tools'; +import { AnalyticsServiceSetup } from '@kbn/core-analytics-browser'; + +export const useEBTTelemetry = ({ + analytics, + queryName, +}: { + analytics?: AnalyticsServiceSetup; + queryName?: string; +}) => { + const reportEvent = (inspectorAdapters?: Partial) => { + if (inspectorAdapters) { + const { requests } = inspectorAdapters; + if (requests && analytics) { + const listReq = requests.getRequests(); + + if (listReq.length > 0) { + // find the highest query time, since a lens chart can contains more than on query, it doesn't make sense to + // report all of them , only the query with highest latency needs to be reported + const duration = listReq.reduce((acc, req) => { + const queryTime = Number(req.stats?.queryTime.value.split('ms')?.[0]); + return queryTime > acc ? queryTime : acc; + }, 0); + + if (duration) { + reportPerformanceMetricEvent(analytics, { + eventName: 'exploratory_view_query_time', + duration, + meta: + (queryName && { + queryName, + }) || + undefined, + }); + } + } + } + } + }; + + return { + reportEvent, + }; +}; diff --git a/x-pack/plugins/observability_solution/exploratory_view/public/plugin.ts b/x-pack/plugins/observability_solution/exploratory_view/public/plugin.ts index 182884d42a51ac..a1101e0fb4e4ac 100644 --- a/x-pack/plugins/observability_solution/exploratory_view/public/plugin.ts +++ b/x-pack/plugins/observability_solution/exploratory_view/public/plugin.ts @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n'; import { BehaviorSubject } from 'rxjs'; import { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/public'; import { + AnalyticsServiceSetup, AppMountParameters, AppUpdater, CoreSetup, @@ -85,6 +86,8 @@ export class Plugin { private readonly appUpdater$ = new BehaviorSubject(() => ({})); + private analyticsService?: AnalyticsServiceSetup; + constructor(private readonly initContext: PluginInitializerContext) {} public setup( @@ -129,6 +132,8 @@ export class Plugin ], }); + this.analyticsService = core.analytics; + return { register: registerDataHandler, }; @@ -138,7 +143,10 @@ export class Plugin return { createExploratoryViewUrl, getAppDataView: getAppDataView(pluginsStart.dataViews), - ExploratoryViewEmbeddable: getExploratoryViewEmbeddable({ ...coreStart, ...pluginsStart }), + ExploratoryViewEmbeddable: getExploratoryViewEmbeddable( + { ...coreStart, ...pluginsStart }, + this.analyticsService + ), }; } } diff --git a/x-pack/plugins/observability_solution/exploratory_view/tsconfig.json b/x-pack/plugins/observability_solution/exploratory_view/tsconfig.json index 87002a070158a7..3aca08a23f4ef0 100644 --- a/x-pack/plugins/observability_solution/exploratory_view/tsconfig.json +++ b/x-pack/plugins/observability_solution/exploratory_view/tsconfig.json @@ -41,7 +41,10 @@ "@kbn/observability-ai-assistant-plugin", "@kbn/shared-ux-link-redirect-app", "@kbn/react-kibana-context-render", - "@kbn/react-kibana-mount" + "@kbn/react-kibana-mount", + "@kbn/core-analytics-browser", + "@kbn/expressions-plugin", + "@kbn/ebt-tools" ], "exclude": ["target/**/*"] }