[ML] Transforms: Add performance journey for transform wizard source index loading. (#160837)

Add a performance journey for transform wizard source index loading.
This commit is contained in:
Walter Rafelsberger 2023-06-30 13:03:22 +02:00 committed by GitHub
parent 4fb883a1e0
commit a8e07e8709
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 70 additions and 9 deletions

View file

@ -400,6 +400,7 @@ enabled:
- x-pack/performance/journeys/flight_dashboard.ts
- x-pack/performance/journeys/login.ts
- x-pack/performance/journeys/many_fields_discover.ts
- x-pack/performance/journeys/many_fields_transform.ts
- x-pack/performance/journeys/promotion_tracking_dashboard.ts
- x-pack/performance/journeys/web_logs_dashboard.ts
- x-pack/performance/journeys/data_stress_test_lens.ts

View file

@ -12,7 +12,7 @@ In order to achieve our goal of creating best user experience in Kibana, it is i
To make things easier, we introduced performance journeys, that mimics end-user experience with Kibana.
Journey runs a flow of user interactions with Kibana in a browser and collects APM metrics for both server and client-side.
It is possible to instrument Kibana with [custom performance metrics](https://docs.elastic.dev/kibana-dev-docs/tutorials/performance/adding_custom_performance_metrics),
It is possible to instrument Kibana with [custom performance metrics](https://docs.elastic.dev/kibana-dev-docs/tutorial/performance/adding_custom_performance_metrics),
that will provide more detailed information about feature performance.
Journeys core is [kbn-journeys](packages/kbn-journeys/README.mdx) package. It is a function test by design and is powered
@ -61,7 +61,7 @@ Scripts steps include:
You can skip warmup phase for debug purpose by using `--skip-warmup` flag
Since the tests are run on a local machine, there is also realistic throttling applied to the network to
Since the tests are run on a local machine, there is also realistic throttling applied to the network to
simulate real life internet connection. This means that all requests have a fixed latency and limited bandwidth.
### Benchmarking performance on CI

View file

@ -240,9 +240,8 @@ export class JourneyFtrHarness {
return await block();
}
const span = this.apm?.startSpan(name, type ?? null, {
childOf: this.currentTransaction,
});
const span = this.currentTransaction.startSpan(name, type ?? null);
if (!span) {
return await block();
}

View file

@ -0,0 +1,32 @@
/*
* 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 { Journey } from '@kbn/journeys';
import { subj } from '@kbn/test-subj-selector';
import { waitForChrome } from '../utils';
export const journey = new Journey({
kbnArchives: ['test/functional/fixtures/kbn_archiver/many_fields_data_view'],
esArchives: ['test/functional/fixtures/es_archiver/many_fields'],
})
.step('Go to Transforms', async ({ page, kbnUrl }) => {
await page.goto(kbnUrl.get(`app/management/data/transform`));
await waitForChrome(page);
await page.waitForSelector(subj('transformCreateFirstButton'));
await page.waitForSelector(subj('globalLoadingIndicator-hidden'));
})
.step('Go to data view selection', async ({ page }) => {
const createButtons = page.locator(subj('transformCreateFirstButton'));
await createButtons.first().click();
await page.waitForSelector(subj('savedObjectsFinderTable'));
})
.step('Go to Transform Wizard', async ({ page }) => {
await page.click(subj('savedObjectTitleindices-stats*'));
// Extended the timeout, this one tracks a known issue with slow data grid performance with many fields
await page.waitForSelector(subj('transformIndexPreview loaded'), { timeout: 120000 });
await page.waitForSelector(subj('globalLoadingIndicator-hidden'), { timeout: 120000 });
});

View file

@ -71,6 +71,7 @@ dataStart.search.search = jest.fn(({ params }: IKibanaSearchRequest) => {
}) as ISearchGeneric;
const appDependencies: AppDependencies = {
analytics: coreStart.analytics,
application: coreStart.application,
charts: chartPluginMock.createStartContract(),
chrome: coreStart.chrome,

View file

@ -6,6 +6,7 @@
*/
import type {
AnalyticsServiceStart,
ApplicationStart,
ChromeStart,
DocLinksStart,
@ -15,12 +16,12 @@ import type {
NotificationsStart,
OverlayStart,
SavedObjectsStart,
ScopedHistory,
ThemeServiceStart,
} from '@kbn/core/public';
import type { SavedObjectsStart as SavedObjectsPluginStart } from '@kbn/saved-objects-plugin/public';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import type { ScopedHistory } from '@kbn/core/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import type { SpacesPluginStart } from '@kbn/spaces-plugin/public';
import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
@ -38,6 +39,7 @@ import type { SettingsStart } from '@kbn/core-ui-settings-browser';
import type { GetMlSharedImportsReturnType } from '../shared_imports';
export interface AppDependencies {
analytics: AnalyticsServiceStart;
application: ApplicationStart;
charts: ChartsPluginStart;
chrome: ChromeStart;

View file

@ -5,11 +5,12 @@
* 2.0.
*/
import { useEffect, useMemo, useState } from 'react';
import { useEffect, useMemo, useRef, useState } from 'react';
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import type { EuiDataGridColumn } from '@elastic/eui';
import { reportPerformanceMetricEvent } from '@kbn/ebt-tools';
import { isRuntimeMappings } from '@kbn/ml-runtime-field-utils';
import { buildBaseFilterCriteria } from '@kbn/ml-query-utils';
import {
@ -39,7 +40,7 @@ import {
import { getErrorMessage } from '../../../common/utils/errors';
import { isDefaultQuery, matchAllQuery, TransformConfigQuery } from '../common';
import { useToastNotifications } from '../app_dependencies';
import { useToastNotifications, useAppDependencies } from '../app_dependencies';
import type { StepDefineExposedState } from '../sections/create_transform/components/step_define/common';
import { SearchItems } from './use_search_items';
@ -52,6 +53,12 @@ export const useIndexData = (
combinedRuntimeMappings?: StepDefineExposedState['runtimeMappings'],
timeRangeMs?: TimeRangeMs
): UseIndexDataReturnType => {
const { analytics } = useAppDependencies();
// Store the performance metric's start time using a ref
// to be able to track it across rerenders.
const loadIndexDataStartTime = useRef<number | undefined>(window.performance.now());
const indexPattern = useMemo(() => dataView.getIndexPattern(), [dataView]);
const api = useApi();
@ -315,6 +322,22 @@ export const useIndexData = (
const renderCellValue = useRenderCellValue(dataView, pagination, tableItems);
if (
dataGrid.status === INDEX_STATUS.LOADED &&
dataViewFields !== undefined &&
loadIndexDataStartTime.current !== undefined
) {
const loadIndexDataDuration = window.performance.now() - loadIndexDataStartTime.current;
// Set this to undefined so reporting the metric gets triggered only once.
loadIndexDataStartTime.current = undefined;
reportPerformanceMetricEvent(analytics, {
eventName: 'transformLoadIndexPreview',
duration: loadIndexDataDuration,
});
}
return {
...dataGrid,
renderCellValue,

View file

@ -29,6 +29,7 @@ export async function mountManagementSection(
const startServices = await getStartServices();
const [core, plugins] = startServices;
const {
analytics,
application,
chrome,
docLinks,
@ -61,6 +62,7 @@ export async function mountManagementSection(
// AppCore/AppPlugins to be passed on as React context
const appDependencies: AppDependencies = {
analytics,
application,
chrome,
data,

View file

@ -65,7 +65,8 @@
"@kbn/ml-runtime-field-utils",
"@kbn/ml-date-utils",
"@kbn/saved-search-plugin",
"@kbn/unified-field-list"
"@kbn/unified-field-list",
"@kbn/ebt-tools"
],
"exclude": [
"target/**/*",