From c96659e8060cc7234e1150b70a66c63931f28ed1 Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 14 Jul 2022 16:02:52 +0300 Subject: [PATCH 01/45] use flexible performancce event schema --- src/core/public/core_system.test.ts | 5 +- src/core/public/core_system.ts | 85 +++++++---------- .../public/fetch_optional_memory_info.test.ts | 35 ------- src/core/public/fetch_optional_memory_info.ts | 42 -------- src/core/public/index.ts | 2 + src/core/public/kbn_bootstrap.ts | 4 +- src/core/public/utils/events.ts | 95 +++++++++++++++++++ src/core/public/utils/index.ts | 14 ++- src/core/server/index.ts | 2 + .../render_template.test.ts.snap | 2 +- .../rendering/bootstrap/render_template.ts | 2 +- src/core/server/server.ts | 2 +- src/core/utils/events.ts | 10 ++ src/core/utils/index.ts | 1 + .../embeddable/dashboard_container.tsx | 21 +++- .../embeddable/grid/dashboard_grid.tsx | 12 ++- .../public/application/embeddable/types.ts | 8 +- .../viewport/dashboard_viewport.tsx | 9 +- .../dashboard/public/events.ts} | 3 +- src/plugins/dashboard/public/plugin.tsx | 19 +--- .../core_context_providers.ts | 3 +- .../from_the_browser/loaded_dashboard.ts | 4 +- .../from_the_browser/loaded_kibana.ts | 7 +- x-pack/plugins/cloud/server/config.ts | 4 +- .../maps/public/embeddable/map_embeddable.tsx | 2 +- 25 files changed, 215 insertions(+), 178 deletions(-) delete mode 100644 src/core/public/fetch_optional_memory_info.test.ts delete mode 100644 src/core/public/fetch_optional_memory_info.ts create mode 100644 src/core/public/utils/events.ts create mode 100644 src/core/utils/events.ts rename src/{core/public/utils/consts.ts => plugins/dashboard/public/events.ts} (85%) diff --git a/src/core/public/core_system.test.ts b/src/core/public/core_system.test.ts index eb8b564c2e9ea..c3c7f232cba3b 100644 --- a/src/core/public/core_system.test.ts +++ b/src/core/public/core_system.test.ts @@ -41,6 +41,7 @@ import { } from './core_system.test.mocks'; import { CoreSystem } from './core_system'; +import { KIBANA_LOADED_EVENT } from './utils'; jest.spyOn(CoreSystem.prototype, 'stop'); @@ -251,7 +252,7 @@ describe('#start()', () => { it('reports the event Loaded Kibana and clears marks', async () => { await startCore(); expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledTimes(1); - expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledWith('Loaded Kibana', { + expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledWith(KIBANA_LOADED_EVENT, { kibana_version: '1.2.3', load_started: 456, bootstrap_started: 123, @@ -272,7 +273,7 @@ describe('#start()', () => { await startCore(); expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledTimes(1); - expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledWith('Loaded Kibana', { + expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledWith(KIBANA_LOADED_EVENT, { load_started: 456, bootstrap_started: 123, kibana_version: '1.2.3', diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 636c44dd3a6e0..0176e479c77b9 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -36,8 +36,17 @@ import { IntegrationsService } from './integrations'; import { DeprecationsService } from './deprecations'; import { CoreApp } from './core_app'; import type { InternalApplicationSetup, InternalApplicationStart } from './application/types'; -import { fetchOptionalMemoryInfo } from './fetch_optional_memory_info'; -import { KBN_LOAD_MARKS } from './utils'; +import { + KBN_LOAD_MARKS, + LOAD_SETUP_DONE, + LOAD_START_DONE, + KIBANA_LOADED_EVENT, + LOAD_CORE_CREATED, + PERFORMANCE_METRIC_EVENT_SCHEMA, + LOAD_FIRST_NAV, + LOAD_BOOTSTRAP_START, + LOAD_START, +} from './utils'; interface Params { rootDomElement: HTMLElement; @@ -129,12 +138,12 @@ export class CoreSystem { this.coreApp = new CoreApp(this.coreContext); performance.mark(KBN_LOAD_MARKS, { - detail: 'core_created', + detail: LOAD_CORE_CREATED, }); } - private getLoadMarksInfo() { - if (!performance) return []; + private getLoadMarksInfo(): Record { + if (!performance) return {}; const reportData: Record = {}; const marks = performance.getEntriesByName(KBN_LOAD_MARKS); for (const mark of marks) { @@ -145,11 +154,23 @@ export class CoreSystem { } private reportKibanaLoadedEvent(analytics: AnalyticsServiceStart) { - analytics.reportEvent('Loaded Kibana', { + const timing = this.getLoadMarksInfo(); + analytics.reportEvent(KIBANA_LOADED_EVENT, { kibana_version: this.coreContext.env.packageInfo.version, protocol: window.location.protocol, - ...fetchOptionalMemoryInfo(), - ...this.getLoadMarksInfo(), + duration: timing[LOAD_FIRST_NAV], + // @ts-expect-error 2339 + ...performance.memory, + key1: LOAD_START, + value1: timing[LOAD_START], + key2: LOAD_BOOTSTRAP_START, + value2: timing[LOAD_CORE_CREATED], + key3: LOAD_CORE_CREATED, + value3: timing[LOAD_CORE_CREATED], + key4: LOAD_SETUP_DONE, + value4: timing[LOAD_SETUP_DONE], + key5: LOAD_START_DONE, + value5: timing[LOAD_START_DONE], }); performance.clearMarks(KBN_LOAD_MARKS); } @@ -200,7 +221,7 @@ export class CoreSystem { await this.plugins.setup(core); performance.mark(KBN_LOAD_MARKS, { - detail: 'setup_done', + detail: LOAD_SETUP_DONE, }); return { fatalErrors: this.fatalErrorsSetup }; @@ -300,13 +321,13 @@ export class CoreSystem { }); performance.mark(KBN_LOAD_MARKS, { - detail: 'start_done', + detail: LOAD_START_DONE, }); // Wait for the first app navigation to report Kibana Loaded firstValueFrom(application.currentAppId$.pipe(filter(Boolean))).then(() => { performance.mark(KBN_LOAD_MARKS, { - detail: 'first_app_nav', + detail: LOAD_FIRST_NAV, }); this.reportKibanaLoadedEvent(analytics); }); @@ -344,51 +365,13 @@ export class CoreSystem { private registerLoadedKibanaEventType(analytics: AnalyticsServiceSetup) { analytics.registerEventType({ - eventType: 'Loaded Kibana', + eventType: KIBANA_LOADED_EVENT, schema: { + ...PERFORMANCE_METRIC_EVENT_SCHEMA, kibana_version: { type: 'keyword', _meta: { description: 'The version of Kibana' }, }, - memory_js_heap_size_limit: { - type: 'long', - _meta: { description: 'The maximum size of the heap', optional: true }, - }, - memory_js_heap_size_total: { - type: 'long', - _meta: { description: 'The total size of the heap', optional: true }, - }, - memory_js_heap_size_used: { - type: 'long', - _meta: { description: 'The used size of the heap', optional: true }, - }, - load_started: { - type: 'long', - _meta: { description: 'When the render template starts loading assets', optional: true }, - }, - bootstrap_started: { - type: 'long', - _meta: { description: 'When kbnBootstrap callback is called', optional: true }, - }, - core_created: { - type: 'long', - _meta: { description: 'When core system is created', optional: true }, - }, - setup_done: { - type: 'long', - _meta: { description: 'When core system setup is complete', optional: true }, - }, - start_done: { - type: 'long', - _meta: { description: 'When core system start is complete', optional: true }, - }, - first_app_nav: { - type: 'long', - _meta: { - description: 'When the application emits the first app navigation', - optional: true, - }, - }, protocol: { type: 'keyword', _meta: { diff --git a/src/core/public/fetch_optional_memory_info.test.ts b/src/core/public/fetch_optional_memory_info.test.ts deleted file mode 100644 index f92fad9c14d63..0000000000000 --- a/src/core/public/fetch_optional_memory_info.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { fetchOptionalMemoryInfo } from './fetch_optional_memory_info'; - -describe('fetchOptionalMemoryInfo', () => { - test('should return undefined if no memory info is available', () => { - expect(fetchOptionalMemoryInfo()).toBeUndefined(); - }); - - test('should return the memory info when available', () => { - // @ts-expect-error 2339 - window.performance.memory = { - get jsHeapSizeLimit() { - return 3; - }, - get totalJSHeapSize() { - return 2; - }, - get usedJSHeapSize() { - return 1; - }, - }; - expect(fetchOptionalMemoryInfo()).toEqual({ - memory_js_heap_size_limit: 3, - memory_js_heap_size_total: 2, - memory_js_heap_size_used: 1, - }); - }); -}); diff --git a/src/core/public/fetch_optional_memory_info.ts b/src/core/public/fetch_optional_memory_info.ts deleted file mode 100644 index b18f3ca2698da..0000000000000 --- a/src/core/public/fetch_optional_memory_info.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -/** - * `Performance.memory` output. - * https://developer.mozilla.org/en-US/docs/Web/API/Performance/memory - */ -export interface BrowserPerformanceMemoryInfo { - /** - * The maximum size of the heap, in bytes, that is available to the context. - */ - memory_js_heap_size_limit: number; - /** - * The total allocated heap size, in bytes. - */ - memory_js_heap_size_total: number; - /** - * The currently active segment of JS heap, in bytes. - */ - memory_js_heap_size_used: number; -} - -/** - * Get performance information from the browser (non-standard property). - * @remarks Only available in Google Chrome and MS Edge for now. - */ -export function fetchOptionalMemoryInfo(): BrowserPerformanceMemoryInfo | undefined { - // @ts-expect-error 2339 - const memory = window.performance.memory; - if (memory) { - return { - memory_js_heap_size_limit: memory.jsHeapSizeLimit, - memory_js_heap_size_total: memory.totalJSHeapSize, - memory_js_heap_size_used: memory.usedJSHeapSize, - }; - } -} diff --git a/src/core/public/index.ts b/src/core/public/index.ts index 5e224c38a2dc4..a23422ddf2723 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -354,4 +354,6 @@ export type { NavType, }; +export type { PerformanceMetricEvent } from './utils'; + export { __kbnBootstrap__ } from './kbn_bootstrap'; diff --git a/src/core/public/kbn_bootstrap.ts b/src/core/public/kbn_bootstrap.ts index 79283daaf9a3a..e4b1b2f1bd927 100644 --- a/src/core/public/kbn_bootstrap.ts +++ b/src/core/public/kbn_bootstrap.ts @@ -9,12 +9,12 @@ import { i18n } from '@kbn/i18n'; import { CoreSystem } from './core_system'; import { ApmSystem } from './apm_system'; -import { KBN_LOAD_MARKS } from './utils'; +import { KBN_LOAD_MARKS, LOAD_BOOTSTRAP_START } from './utils'; /** @internal */ export async function __kbnBootstrap__() { performance.mark(KBN_LOAD_MARKS, { - detail: 'bootstrap_started', + detail: LOAD_BOOTSTRAP_START, }); const injectedMetadata = JSON.parse( diff --git a/src/core/public/utils/events.ts b/src/core/public/utils/events.ts new file mode 100644 index 0000000000000..f9c43aa4ac7d0 --- /dev/null +++ b/src/core/public/utils/events.ts @@ -0,0 +1,95 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** @internal */ +export const KBN_LOAD_MARKS = 'kbnLoad'; + +export { KIBANA_LOADED_EVENT } from '../../utils'; + +export const LOAD_START = 'load-started'; +export const LOAD_BOOTSTRAP_START = 'bootstrap-start'; +export const LOAD_CORE_CREATED = 'core-created'; +export const LOAD_SETUP_DONE = 'setup-done'; +export const LOAD_START_DONE = 'start-done'; +export const LOAD_FIRST_NAV = 'first-app-nav'; + +export interface PerformanceMetricEvent { + duration?: number; + jsHeapSizeLimit?: number; + totalJSHeapSize?: number; + usedJSHeapSize?: number; + key1?: string; + value1?: number; + key2?: string; + value2?: number; + key3?: string; + value3?: number; + key4?: string; + value4?: number; + key5?: string; + value5?: number; +} + +export const PERFORMANCE_METRIC_EVENT_SCHEMA: Record = { + duration: { + type: 'long', + _meta: { description: 'The main event duration', optional: true }, + }, + jsHeapSizeLimit: { + type: 'long', + _meta: { description: 'performance.memory.jsHeapSizeLimit', optional: true }, + }, + totalJSHeapSize: { + type: 'long', + _meta: { description: 'performance.memory.totalJSHeapSize', optional: true }, + }, + usedJSHeapSize: { + type: 'long', + _meta: { description: 'performance.memory.usedJSHeapSize', optional: true }, + }, + key1: { + type: 'keyword', + _meta: { description: 'Performance metric label', optional: true }, + }, + value1: { + type: 'long', + _meta: { description: 'Performance metric value', optional: true }, + }, + key2: { + type: 'keyword', + _meta: { description: 'Performance metric label', optional: true }, + }, + value2: { + type: 'long', + _meta: { description: 'Performance metric value', optional: true }, + }, + key3: { + type: 'keyword', + _meta: { description: 'Performance metric label', optional: true }, + }, + value3: { + type: 'long', + _meta: { description: 'Performance metric value', optional: true }, + }, + key4: { + type: 'keyword', + _meta: { description: 'Performance metric label', optional: true }, + }, + value4: { + type: 'long', + _meta: { description: 'Performance metric value', optional: true }, + }, + key5: { + type: 'keyword', + _meta: { description: 'Performance metric label', optional: true }, + }, + value5: { + type: 'long', + _meta: { description: 'Performance metric value', optional: true }, + }, +}; diff --git a/src/core/public/utils/index.ts b/src/core/public/utils/index.ts index 2164c31f1ea29..7cd84fcf61ac4 100644 --- a/src/core/public/utils/index.ts +++ b/src/core/public/utils/index.ts @@ -7,4 +7,16 @@ */ export { MountWrapper, mountReactNode } from './mount'; -export { KBN_LOAD_MARKS } from './consts'; +export { + KBN_LOAD_MARKS, + LOAD_START, + LOAD_CORE_CREATED, + KIBANA_LOADED_EVENT, + LOAD_SETUP_DONE, + LOAD_START_DONE, + LOAD_FIRST_NAV, + LOAD_BOOTSTRAP_START, +} from './events'; + +export type { PerformanceMetricEvent } from './events'; +export { PERFORMANCE_METRIC_EVENT_SCHEMA } from './events'; diff --git a/src/core/server/index.ts b/src/core/server/index.ts index e87c814dca851..fa16a1eae6d44 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -656,3 +656,5 @@ export type { PublicHttpServiceSetup as HttpServiceSetup, HttpServiceSetup as BaseHttpServiceSetup, }; + +export { KIBANA_LOADED_EVENT } from '../utils'; diff --git a/src/core/server/rendering/bootstrap/__snapshots__/render_template.test.ts.snap b/src/core/server/rendering/bootstrap/__snapshots__/render_template.test.ts.snap index f7e28eebd1a61..109bcd710f434 100644 --- a/src/core/server/rendering/bootstrap/__snapshots__/render_template.test.ts.snap +++ b/src/core/server/rendering/bootstrap/__snapshots__/render_template.test.ts.snap @@ -105,7 +105,7 @@ if (window.__kbnStrictCsp__ && window.__kbnCspNotEnforced__) { } performance.mark('kbnLoad', { - detail: 'load_started', + detail: 'load-started', }) load([ diff --git a/src/core/server/rendering/bootstrap/render_template.ts b/src/core/server/rendering/bootstrap/render_template.ts index 996aacd5e3ede..8c85f42f737cd 100644 --- a/src/core/server/rendering/bootstrap/render_template.ts +++ b/src/core/server/rendering/bootstrap/render_template.ts @@ -121,7 +121,7 @@ if (window.__kbnStrictCsp__ && window.__kbnCspNotEnforced__) { } performance.mark('kbnLoad', { - detail: 'load_started', + detail: 'load-started', }) load([ diff --git a/src/core/server/server.ts b/src/core/server/server.ts index b8f47cdda45f7..d41831b105bd0 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -61,7 +61,7 @@ import type { RequestHandlerContext, PrebootRequestHandlerContext } from '.'; const coreId = Symbol('core'); const rootConfigPath = ''; -const KIBANA_STARTED_EVENT = 'kibana_started'; +const KIBANA_STARTED_EVENT = 'kibana-started'; /** @internal */ interface UptimePerStep { diff --git a/src/core/utils/events.ts b/src/core/utils/events.ts new file mode 100644 index 0000000000000..a50b66bf51bfc --- /dev/null +++ b/src/core/utils/events.ts @@ -0,0 +1,10 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +// TODO: replace with kibana-loaded +export const KIBANA_LOADED_EVENT = 'Loaded Kibana'; diff --git a/src/core/utils/index.ts b/src/core/utils/index.ts index 73980983a12e1..0cef965c6509d 100644 --- a/src/core/utils/index.ts +++ b/src/core/utils/index.ts @@ -8,3 +8,4 @@ export { DEFAULT_APP_CATEGORIES } from './default_app_categories'; export { APP_WRAPPER_CLASS } from './app_wrapper_class'; +export { KIBANA_LOADED_EVENT } from './events'; diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx index aa2588c1b3b54..1f163f9fdb1e0 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx @@ -31,7 +31,7 @@ import { } from '../../services/embeddable'; import { DASHBOARD_CONTAINER_TYPE } from './dashboard_constants'; import { createPanelState } from './panel'; -import { DashboardLoadedEvent, DashboardPanelState } from './types'; +import { DashboardPanelState } from './types'; import { DashboardViewport } from './viewport/dashboard_viewport'; import { KibanaContextProvider, @@ -40,6 +40,7 @@ import { KibanaThemeProvider, } from '../../services/kibana_react'; import { PLACEHOLDER_EMBEDDABLE } from './placeholder'; +import { DASHBOARD_LOADED_EVENT } from '../../events'; import { DashboardAppCapabilities, DashboardContainerInput } from '../../types'; import { PresentationUtilPluginStart } from '../../services/presentation_util'; import type { ScreenshotModePluginStart } from '../../services/screenshot_mode'; @@ -66,6 +67,13 @@ export interface DashboardContainerServices { analytics?: CoreStart['analytics']; } +export interface DashboardLoadedInfo { + timeToData: number; + timeToDone: number; + numOfPanels: number; + status: string; +} + interface IndexSignature { [key: string]: unknown; } @@ -155,9 +163,14 @@ export class DashboardContainer extends Container void; + onDataLoaded?: (data: DashboardLoadedInfo) => void; } interface State { @@ -272,7 +276,7 @@ class DashboardGridUi extends React.Component { doneCount++; if (doneCount === panelsInOrder.length) { const doneTime = performance.now(); - const data: DashboardLoadedEvent = { + const data: DashboardLoadedInfo = { timeToData: (lastTimeToData || doneTime) - loadStartTime, timeToDone: doneTime - loadStartTime, numOfPanels: panelsInOrder.length, diff --git a/src/plugins/dashboard/public/application/embeddable/types.ts b/src/plugins/dashboard/public/application/embeddable/types.ts index f8e37b07d721c..434479106e532 100644 --- a/src/plugins/dashboard/public/application/embeddable/types.ts +++ b/src/plugins/dashboard/public/application/embeddable/types.ts @@ -7,14 +7,10 @@ */ export * from '../../../common/types'; +import type { PerformanceMetricEvent } from '@kbn/core/public'; export type DashboardLoadedEventStatus = 'done' | 'error'; -export interface DashboardLoadedEvent { - // Time from start to when data is loaded - timeToData: number; - // Time from start until render or error - timeToDone: number; - numOfPanels: number; +export interface DashboardLoadedEvent extends PerformanceMetricEvent { status: DashboardLoadedEventStatus; } diff --git a/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.tsx b/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.tsx index 7726258b399e2..9bd2fe6238590 100644 --- a/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.tsx +++ b/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.tsx @@ -14,18 +14,21 @@ import { LazyControlsCallout, } from '@kbn/controls-plugin/public'; import { ViewMode } from '../../../services/embeddable'; -import { DashboardContainer, DashboardReactContextValue } from '../dashboard_container'; +import { + DashboardContainer, + DashboardReactContextValue, + DashboardLoadedInfo, +} from '../dashboard_container'; import { DashboardGrid } from '../grid'; import { context } from '../../../services/kibana_react'; import { DashboardEmptyScreen } from '../empty_screen/dashboard_empty_screen'; import { withSuspense } from '../../../services/presentation_util'; -import { DashboardLoadedEvent } from '../types'; export interface DashboardViewportProps { container: DashboardContainer; controlGroup?: ControlGroupContainer; controlsEnabled?: boolean; - onDataLoaded?: (data: DashboardLoadedEvent) => void; + onDataLoaded?: (data: DashboardLoadedInfo) => void; } interface State { diff --git a/src/core/public/utils/consts.ts b/src/plugins/dashboard/public/events.ts similarity index 85% rename from src/core/public/utils/consts.ts rename to src/plugins/dashboard/public/events.ts index 8372eafec8147..30d7a81f84c31 100644 --- a/src/core/public/utils/consts.ts +++ b/src/plugins/dashboard/public/events.ts @@ -6,5 +6,4 @@ * Side Public License, v 1. */ -/** @internal */ -export const KBN_LOAD_MARKS = 'kbnLoad'; +export const DASHBOARD_LOADED_EVENT = 'dashboard-loaded'; diff --git a/src/plugins/dashboard/public/plugin.tsx b/src/plugins/dashboard/public/plugin.tsx index a9564ac0db49a..1905ee4342544 100644 --- a/src/plugins/dashboard/public/plugin.tsx +++ b/src/plugins/dashboard/public/plugin.tsx @@ -72,6 +72,7 @@ import { CopyToDashboardAction, DashboardCapabilities, DashboardLoadedEvent, + PERFORMANCE_METRIC_EVENT_SCHEMA, } from './application'; import { DashboardAppLocatorDefinition, DashboardAppLocator } from './locator'; import { createSavedDashboardLoader } from './saved_dashboards'; @@ -80,6 +81,7 @@ import { PlaceholderEmbeddableFactory } from './application/embeddable/placehold import { ExportCSVAction } from './application/actions/export_csv_action'; import { dashboardFeatureCatalog } from './dashboard_strings'; import { SpacesPluginStart } from './services/spaces'; +import { DASHBOARD_LOADED_EVENT } from './events'; export interface DashboardFeatureFlagConfig { allowByValueEmbeddables: boolean; @@ -141,23 +143,12 @@ export class DashboardPlugin private registerEvents(analytics: CoreSetup['analytics']) { analytics.registerEventType({ - eventType: 'dashboard-data-loaded', + eventType: DASHBOARD_LOADED_EVENT, schema: { - timeToData: { - type: 'long', - _meta: { description: 'Time all embeddables took to load data' }, - }, - timeToDone: { - type: 'long', - _meta: { description: 'Time all embeddables took to load data' }, - }, + ...PERFORMANCE_METRIC_EVENT_SCHEMA, status: { type: 'keyword', - _meta: { description: 'Error ok' }, - }, - numOfPanels: { - type: 'long', - _meta: { description: 'Number of panels loaded' }, + _meta: { description: 'Dashborad load status' }, }, }, }); diff --git a/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts b/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts index 6543b3c7955ef..b2da32f570a8c 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts @@ -8,6 +8,7 @@ import expect from '@kbn/expect'; import { Event } from '@kbn/core/public'; +import { KIBANA_LOADED_EVENT } from '@kbn/core/utils'; import { FtrProviderContext } from '../../../services'; export default function ({ getService, getPageObjects }: FtrProviderContext) { @@ -19,7 +20,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { let event: Event; before(async () => { await common.navigateToApp('home'); - [event] = await ebtUIHelper.getEvents(1, { eventTypes: ['Loaded Kibana'] }); // Get the loaded Kibana event + [event] = await ebtUIHelper.getEvents(1, { eventTypes: [KIBANA_LOADED_EVENT] }); // Get the loaded Kibana event }); it('should have the properties provided by the "cluster info" context provider', () => { diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts index 178bed7cbbbe5..c0d8c077facf0 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts @@ -29,7 +29,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const getEvents = async (count: number, options?: GetEventsOptions) => ebtUIHelper.getEvents(count, { - eventTypes: ['dashboard-data-loaded'], + eventTypes: [DASHBOARD_LOADED_EVENT], fromTimestamp, withTimeoutMs: 1000, ...options, @@ -39,7 +39,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const events = await getEvents(Number.MAX_SAFE_INTEGER, options); expect(events.length).to.be(1); const event = events[0]; - expect(event.event_type).to.eql('dashboard-data-loaded'); + expect(event.event_type).to.eql(DASHBOARD_LOADED_EVENT); expect(event.context.applicationId).to.be('dashboards'); expect(event.context.page).to.be('app'); expect(event.context.pageName).to.be('application:dashboards:app'); diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts index 7ed47db35cbeb..d884fc75cd230 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { KIBANA_LOADED_EVENT } from '@kbn/core/utils'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../services'; @@ -14,14 +15,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const { common } = getPageObjects(['common']); const browser = getService('browser'); - describe('Loaded Kibana', () => { + describe('Loaded kibana', () => { beforeEach(async () => { await common.navigateToApp('home'); }); it('should emit the "Loaded Kibana" event', async () => { - const [event] = await ebtUIHelper.getEvents(1, { eventTypes: ['Loaded Kibana'] }); - expect(event.event_type).to.eql('Loaded Kibana'); + const [event] = await ebtUIHelper.getEvents(1, { eventTypes: [KIBANA_LOADED_EVENT] }); + expect(event.event_type).to.eql(KIBANA_LOADED_EVENT); expect(event.properties).to.have.property('kibana_version'); expect(event.properties.kibana_version).to.be.a('string'); expect(event.properties).to.have.property('protocol'); diff --git a/x-pack/plugins/cloud/server/config.ts b/x-pack/plugins/cloud/server/config.ts index aebbc65e50f18..27da9b05dc8ee 100644 --- a/x-pack/plugins/cloud/server/config.ts +++ b/x-pack/plugins/cloud/server/config.ts @@ -6,7 +6,7 @@ */ import { schema, TypeOf } from '@kbn/config-schema'; -import { PluginConfigDescriptor } from '@kbn/core/server'; +import { PluginConfigDescriptor, KIBANA_LOADED_EVENT } from '@kbn/core/server'; const apmConfigSchema = schema.object({ url: schema.maybe(schema.string()), @@ -27,7 +27,7 @@ const fullStoryConfigSchema = schema.object({ schema.maybe(schema.string()) ), eventTypesAllowlist: schema.arrayOf(schema.string(), { - defaultValue: ['Loaded Kibana'], + defaultValue: [KIBANA_LOADED_EVENT], }), }); diff --git a/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx b/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx index 8a1064a8725bb..79018d48aa548 100644 --- a/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx +++ b/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx @@ -728,7 +728,7 @@ export class MapEmbeddable ) { /** * Maps emit rendered when the data is loaded, as we don't have feedback from the maps rendering library atm. - * This means that the dashboard-loaded event might be fired while a map is still rendering in some cases. + * This means that the DASHBOARD_LOADED_EVENT event might be fired while a map is still rendering in some cases. * For more details please contact the maps team. */ this.updateOutput({ From 4a4f5c8880b6a4ab16b96ae40f923efb888a8a5e Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 14 Jul 2022 16:45:16 +0300 Subject: [PATCH 02/45] fix --- src/plugins/dashboard/public/plugin.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/dashboard/public/plugin.tsx b/src/plugins/dashboard/public/plugin.tsx index 1905ee4342544..288455e8636ae 100644 --- a/src/plugins/dashboard/public/plugin.tsx +++ b/src/plugins/dashboard/public/plugin.tsx @@ -72,7 +72,6 @@ import { CopyToDashboardAction, DashboardCapabilities, DashboardLoadedEvent, - PERFORMANCE_METRIC_EVENT_SCHEMA, } from './application'; import { DashboardAppLocatorDefinition, DashboardAppLocator } from './locator'; import { createSavedDashboardLoader } from './saved_dashboards'; @@ -82,6 +81,7 @@ import { ExportCSVAction } from './application/actions/export_csv_action'; import { dashboardFeatureCatalog } from './dashboard_strings'; import { SpacesPluginStart } from './services/spaces'; import { DASHBOARD_LOADED_EVENT } from './events'; +import { PERFORMANCE_METRIC_EVENT_SCHEMA } from '@kbn/core/public/utils'; export interface DashboardFeatureFlagConfig { allowByValueEmbeddables: boolean; From d86ea423e47379e258422032ee9e87376aed9912 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 14 Jul 2022 13:50:57 +0000 Subject: [PATCH 03/45] [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' --- src/plugins/dashboard/public/plugin.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/dashboard/public/plugin.tsx b/src/plugins/dashboard/public/plugin.tsx index 288455e8636ae..f5fe7997f9704 100644 --- a/src/plugins/dashboard/public/plugin.tsx +++ b/src/plugins/dashboard/public/plugin.tsx @@ -29,6 +29,7 @@ import { VisualizationsStart } from '@kbn/visualizations-plugin/public'; import { replaceUrlHashQuery } from '@kbn/kibana-utils-plugin/public'; import { DataViewEditorStart } from '@kbn/data-view-editor-plugin/public'; +import { PERFORMANCE_METRIC_EVENT_SCHEMA } from '@kbn/core/public/utils'; import { createKbnUrlTracker } from './services/kibana_utils'; import { UsageCollectionSetup } from './services/usage_collection'; import { UiActionsSetup, UiActionsStart } from './services/ui_actions'; @@ -81,7 +82,6 @@ import { ExportCSVAction } from './application/actions/export_csv_action'; import { dashboardFeatureCatalog } from './dashboard_strings'; import { SpacesPluginStart } from './services/spaces'; import { DASHBOARD_LOADED_EVENT } from './events'; -import { PERFORMANCE_METRIC_EVENT_SCHEMA } from '@kbn/core/public/utils'; export interface DashboardFeatureFlagConfig { allowByValueEmbeddables: boolean; From 266d2d870a223ac64e87017a7e34cc488cc1e611 Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 14 Jul 2022 18:44:55 +0300 Subject: [PATCH 04/45] import --- .../instrumented_events/from_the_browser/loaded_dashboard.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts index c0d8c077facf0..6e484bce7b25e 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts @@ -9,6 +9,7 @@ import { GetEventsOptions } from '@kbn/analytics-ftr-helpers-plugin/common/types'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../services'; +import { DASHBOARD_LOADED_EVENT } from '../../../../../src/plugins/dashboard/public/events'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const ebtUIHelper = getService('kibana_ebt_ui'); From 70dbbbe2e4eb0a8e32e97b25b8cba61889837b20 Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 14 Jul 2022 18:48:05 +0300 Subject: [PATCH 05/45] code review --- src/core/public/utils/events.ts | 4 ++-- .../public/application/embeddable/dashboard_container.tsx | 2 +- src/plugins/dashboard/public/plugin.tsx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/public/utils/events.ts b/src/core/public/utils/events.ts index f9c43aa4ac7d0..46745cf1574e6 100644 --- a/src/core/public/utils/events.ts +++ b/src/core/public/utils/events.ts @@ -37,8 +37,8 @@ export interface PerformanceMetricEvent { export const PERFORMANCE_METRIC_EVENT_SCHEMA: Record = { duration: { - type: 'long', - _meta: { description: 'The main event duration', optional: true }, + type: 'integer', + _meta: { description: 'The main event duration in ms', optional: true }, }, jsHeapSizeLimit: { type: 'long', diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx index 1f163f9fdb1e0..f4d5513efe0ac 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx @@ -170,7 +170,7 @@ export class DashboardContainer extends Container Date: Thu, 14 Jul 2022 16:44:16 +0000 Subject: [PATCH 06/45] [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' --- .../instrumented_events/from_the_browser/loaded_dashboard.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts index 6e484bce7b25e..32a8412268953 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts @@ -8,8 +8,8 @@ import { GetEventsOptions } from '@kbn/analytics-ftr-helpers-plugin/common/types'; import expect from '@kbn/expect'; +import { DASHBOARD_LOADED_EVENT } from '@kbn/dashboard-plugin/public/events'; import { FtrProviderContext } from '../../../services'; -import { DASHBOARD_LOADED_EVENT } from '../../../../../src/plugins/dashboard/public/events'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const ebtUIHelper = getService('kibana_ebt_ui'); From e7dae103b214fa949af00455e80feb6c6ee9a213 Mon Sep 17 00:00:00 2001 From: lizozom Date: Mon, 18 Jul 2022 13:11:19 +0300 Subject: [PATCH 07/45] fixes --- src/core/public/core_system.test.mocks.ts | 5 ---- src/core/public/utils/events.ts | 2 +- .../from_the_browser/loaded_kibana.ts | 28 ++++++++++--------- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/core/public/core_system.test.mocks.ts b/src/core/public/core_system.test.mocks.ts index 0d46af80b34eb..bce72112265c9 100644 --- a/src/core/public/core_system.test.mocks.ts +++ b/src/core/public/core_system.test.mocks.ts @@ -31,11 +31,6 @@ jest.doMock('@kbn/core-analytics-browser-internal', () => ({ AnalyticsService: AnalyticsServiceConstructor, })); -export const fetchOptionalMemoryInfoMock = jest.fn(); -jest.doMock('./fetch_optional_memory_info', () => ({ - fetchOptionalMemoryInfo: fetchOptionalMemoryInfoMock, -})); - export const MockInjectedMetadataService = injectedMetadataServiceMock.create(); export const InjectedMetadataServiceConstructor = jest .fn() diff --git a/src/core/public/utils/events.ts b/src/core/public/utils/events.ts index 46745cf1574e6..9145355fe3676 100644 --- a/src/core/public/utils/events.ts +++ b/src/core/public/utils/events.ts @@ -12,7 +12,7 @@ export const KBN_LOAD_MARKS = 'kbnLoad'; export { KIBANA_LOADED_EVENT } from '../../utils'; export const LOAD_START = 'load-started'; -export const LOAD_BOOTSTRAP_START = 'bootstrap-start'; +export const LOAD_BOOTSTRAP_START = 'bootstrap-started'; export const LOAD_CORE_CREATED = 'core-created'; export const LOAD_SETUP_DONE = 'setup-done'; export const LOAD_START_DONE = 'start-done'; diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts index d884fc75cd230..ca92a325e5fa9 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts @@ -13,7 +13,6 @@ import { FtrProviderContext } from '../../../services'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const ebtUIHelper = getService('kibana_ebt_ui'); const { common } = getPageObjects(['common']); - const browser = getService('browser'); describe('Loaded kibana', () => { beforeEach(async () => { @@ -29,8 +28,21 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(event.properties.protocol).to.be.a('string'); // Kibana Loaded timings - expect(event.properties).to.have.property('load_started'); - expect(event.properties.load_started).to.be.a('number'); + expect(event.properties).to.have.property('duration'); + expect(event.properties.duration).to.be.a('number'); + + expect(event.properties).to.have.property('key1', 'load-started'); + expect(event.properties).to.have.property('key2', 'bootstrap-started'); + expect(event.properties).to.have.property('key3', 'core-created'); + expect(event.properties).to.have.property('key4', 'setup-done'); + expect(event.properties).to.have.property('key5', 'start-done'); + + expect(event.properties.value1).to.be.a('number'); + expect(event.properties.value2).to.be.a('number'); + expect(event.properties.value3).to.be.a('number'); + expect(event.properties.value4).to.be.a('number'); + expect(event.properties.value5).to.be.a('number'); + expect(event.properties).to.have.property('bootstrap_started'); expect(event.properties.bootstrap_started).to.be.a('number'); expect(event.properties).to.have.property('core_created'); @@ -41,16 +53,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(event.properties.start_done).to.be.a('number'); expect(event.properties).to.have.property('first_app_nav'); expect(event.properties.start_done).to.be.a('number'); - - if (browser.isChromium) { - // Kibana Loaded memory - expect(event.properties).to.have.property('memory_js_heap_size_limit'); - expect(event.properties.memory_js_heap_size_limit).to.be.a('number'); - expect(event.properties).to.have.property('memory_js_heap_size_total'); - expect(event.properties.memory_js_heap_size_total).to.be.a('number'); - expect(event.properties).to.have.property('memory_js_heap_size_used'); - expect(event.properties.memory_js_heap_size_used).to.be.a('number'); - } }); }); } From dd4821776c1786d835287f35eb6d32e07a635413 Mon Sep 17 00:00:00 2001 From: lizozom Date: Mon, 18 Jul 2022 15:34:46 +0300 Subject: [PATCH 08/45] jest --- src/core/public/core_system.test.ts | 59 +++++++++++++++++++---------- src/core/public/core_system.ts | 2 +- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/core/public/core_system.test.ts b/src/core/public/core_system.test.ts index c3c7f232cba3b..0008085009fef 100644 --- a/src/core/public/core_system.test.ts +++ b/src/core/public/core_system.test.ts @@ -37,11 +37,18 @@ import { AnalyticsServiceConstructor, MockAnalyticsService, analyticsServiceStartMock, - fetchOptionalMemoryInfoMock, } from './core_system.test.mocks'; import { CoreSystem } from './core_system'; -import { KIBANA_LOADED_EVENT } from './utils'; +import { + KIBANA_LOADED_EVENT, + LOAD_START, + LOAD_BOOTSTRAP_START, + LOAD_CORE_CREATED, + LOAD_FIRST_NAV, + LOAD_SETUP_DONE, + LOAD_START_DONE, +} from './utils'; jest.spyOn(CoreSystem.prototype, 'stop'); @@ -76,12 +83,28 @@ beforeEach(() => { window.performance.clearMarks = jest.fn(); window.performance.getEntriesByName = jest.fn().mockReturnValue([ { - detail: 'load_started', - startTime: 456, + detail: LOAD_START, + startTime: 111, + }, + { + detail: LOAD_BOOTSTRAP_START, + startTime: 222, + }, + { + detail: LOAD_CORE_CREATED, + startTime: 333, + }, + { + detail: LOAD_SETUP_DONE, + startTime: 444, }, { - detail: 'bootstrap_started', - startTime: 123, + detail: LOAD_START_DONE, + startTime: 555, + }, + { + detail: LOAD_FIRST_NAV, + startTime: 666, }, ]); }); @@ -263,23 +286,21 @@ describe('#start()', () => { }); it('reports the event Loaded Kibana (with memory)', async () => { - fetchOptionalMemoryInfoMock.mockReturnValue({ - load_started: 456, - bootstrap_started: 123, - memory_js_heap_size_limit: 3, - memory_js_heap_size_total: 2, - memory_js_heap_size_used: 1, - }); - await startCore(); expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledTimes(1); expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledWith(KIBANA_LOADED_EVENT, { - load_started: 456, - bootstrap_started: 123, kibana_version: '1.2.3', - memory_js_heap_size_limit: 3, - memory_js_heap_size_total: 2, - memory_js_heap_size_used: 1, + duration: 666, + key1: LOAD_START, + key2: LOAD_BOOTSTRAP_START, + key3: LOAD_CORE_CREATED, + key4: LOAD_SETUP_DONE, + key5: LOAD_START_DONE, + value1: 111, + value2: 222, + value3: 333, + value4: 444, + value5: 555, protocol: 'http:', }); }); diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 67a9277fa794d..c5148a2609ccd 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -164,7 +164,7 @@ export class CoreSystem { key1: LOAD_START, value1: timing[LOAD_START], key2: LOAD_BOOTSTRAP_START, - value2: timing[LOAD_CORE_CREATED], + value2: timing[LOAD_BOOTSTRAP_START], key3: LOAD_CORE_CREATED, value3: timing[LOAD_CORE_CREATED], key4: LOAD_SETUP_DONE, From a1f742d1947771339cc64472aba8a2fff02eea3c Mon Sep 17 00:00:00 2001 From: lizozom Date: Mon, 18 Jul 2022 15:36:38 +0300 Subject: [PATCH 09/45] dd --- src/core/public/core_system.test.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/core/public/core_system.test.ts b/src/core/public/core_system.test.ts index 0008085009fef..a38be3648018d 100644 --- a/src/core/public/core_system.test.ts +++ b/src/core/public/core_system.test.ts @@ -277,9 +277,18 @@ describe('#start()', () => { expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledTimes(1); expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledWith(KIBANA_LOADED_EVENT, { kibana_version: '1.2.3', - load_started: 456, - bootstrap_started: 123, protocol: 'http:', + key1: LOAD_START, + key2: LOAD_BOOTSTRAP_START, + key3: LOAD_CORE_CREATED, + key4: LOAD_SETUP_DONE, + key5: LOAD_START_DONE, + value1: 111, + value2: 222, + value3: 333, + value4: 444, + value5: 555, + duration: 666, }); expect(window.performance.clearMarks).toHaveBeenCalledTimes(1); From 5791c431e3408cec3166990e1f7ff3cb20281198 Mon Sep 17 00:00:00 2001 From: lizozom Date: Mon, 18 Jul 2022 16:53:43 +0300 Subject: [PATCH 10/45] fix --- .../from_the_browser/loaded_kibana.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts index ca92a325e5fa9..a755e47c831d6 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts @@ -42,17 +42,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(event.properties.value3).to.be.a('number'); expect(event.properties.value4).to.be.a('number'); expect(event.properties.value5).to.be.a('number'); - - expect(event.properties).to.have.property('bootstrap_started'); - expect(event.properties.bootstrap_started).to.be.a('number'); - expect(event.properties).to.have.property('core_created'); - expect(event.properties.core_created).to.be.a('number'); - expect(event.properties).to.have.property('setup_done'); - expect(event.properties.setup_done).to.be.a('number'); - expect(event.properties).to.have.property('start_done'); - expect(event.properties.start_done).to.be.a('number'); - expect(event.properties).to.have.property('first_app_nav'); - expect(event.properties.start_done).to.be.a('number'); }); }); } From daa56fac73174d9484ecb63f6bf620595022852f Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 19 Jul 2022 13:23:36 +0300 Subject: [PATCH 11/45] tests --- .../from_the_browser/loaded_dashboard.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts index 32a8412268953..167c1751c795e 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts @@ -101,7 +101,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const event = await checkEmitsOnce(); expect(event.context.entityId).to.be('new'); - expect(event.properties.numOfPanels).to.be(1); + expect(event.properties.key2).to.be('num-of-panels'); + expect(event.properties.value2).to.be(1); }); it('emits on saved search refreshed', async () => { @@ -188,10 +189,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const event = await checkEmitsOnce(); expect(event.context.entityId).to.be('7adfa750-4c81-11e8-b3d7-01146121b73d'); - expect(event.properties.numOfPanels).to.be(17); - expect(event.properties.timeToDone as number).to.be.greaterThan( - event.properties.timeToData as number + + expect(event.properties.key1).to.be('time-to-data'); + expect(event.properties.duration as number).to.be.greaterThan( + event.properties.value1 as number ); + + expect(event.properties.key2).to.be('num-of-panels'); + expect(event.properties.value2).to.be(17); }); /** From 03dc26a833e32c8dbca2d1cf1ac3595cfc9c48d9 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 19 Jul 2022 16:27:25 +0300 Subject: [PATCH 12/45] Review 1 --- src/core/public/core_system.test.ts | 17 ++++++++-- src/core/public/core_system.ts | 14 ++++++-- src/core/public/{utils => }/events.ts | 32 +++++++++++++------ src/core/public/index.ts | 2 +- src/core/public/utils/index.ts | 13 -------- src/core/server/index.ts | 1 - src/core/server/server.ts | 2 +- src/core/utils/events.ts | 10 ------ src/core/utils/index.ts | 1 - .../public/application/embeddable/types.ts | 4 +-- src/plugins/dashboard/public/plugin.tsx | 4 +-- .../from_the_browser/loaded_kibana.ts | 29 ++++++++++++----- x-pack/plugins/cloud/server/config.ts | 4 +-- 13 files changed, 77 insertions(+), 56 deletions(-) rename src/core/public/{utils => }/events.ts (77%) delete mode 100644 src/core/utils/events.ts diff --git a/src/core/public/core_system.test.ts b/src/core/public/core_system.test.ts index a38be3648018d..7e6d1a30c042e 100644 --- a/src/core/public/core_system.test.ts +++ b/src/core/public/core_system.test.ts @@ -48,7 +48,7 @@ import { LOAD_FIRST_NAV, LOAD_SETUP_DONE, LOAD_START_DONE, -} from './utils'; +} from './events'; jest.spyOn(CoreSystem.prototype, 'stop'); @@ -272,7 +272,18 @@ describe('#start()', () => { ); }); - it('reports the event Loaded Kibana and clears marks', async () => { + it('reports the deprecated event Loaded Kibana', async () => { + await startCore(); + expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledTimes(1); + expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledWith('Loaded Kibana', { + kibana_version: '1.2.3', + protocol: 'http:', + }); + + expect(window.performance.clearMarks).toHaveBeenCalledTimes(1); + }); + + it('reports the event kibana-loaded and clears marks', async () => { await startCore(); expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledTimes(1); expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledWith(KIBANA_LOADED_EVENT, { @@ -294,7 +305,7 @@ describe('#start()', () => { expect(window.performance.clearMarks).toHaveBeenCalledTimes(1); }); - it('reports the event Loaded Kibana (with memory)', async () => { + it('reports the event kibana-loaded (with memory)', async () => { await startCore(); expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledTimes(1); expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledWith(KIBANA_LOADED_EVENT, { diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index c5148a2609ccd..7224a2f7ce28c 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -42,11 +42,11 @@ import { LOAD_START_DONE, KIBANA_LOADED_EVENT, LOAD_CORE_CREATED, - PERFORMANCE_METRIC_EVENT_SCHEMA, + METRIC_EVENT_SCHEMA, LOAD_FIRST_NAV, LOAD_BOOTSTRAP_START, LOAD_START, -} from './utils'; +} from './events'; interface Params { rootDomElement: HTMLElement; @@ -154,6 +154,14 @@ export class CoreSystem { } private reportKibanaLoadedEvent(analytics: AnalyticsServiceStart) { + /** + * @deprecated here for backwards compatibility in Fullstory + **/ + analytics.reportEvent('Loaded Kibana', { + kibana_version: this.coreContext.env.packageInfo.version, + protocol: window.location.protocol, + }); + const timing = this.getLoadMarksInfo(); analytics.reportEvent(KIBANA_LOADED_EVENT, { kibana_version: this.coreContext.env.packageInfo.version, @@ -367,7 +375,7 @@ export class CoreSystem { analytics.registerEventType({ eventType: KIBANA_LOADED_EVENT, schema: { - ...PERFORMANCE_METRIC_EVENT_SCHEMA, + ...METRIC_EVENT_SCHEMA, kibana_version: { type: 'keyword', _meta: { description: 'The version of Kibana' }, diff --git a/src/core/public/utils/events.ts b/src/core/public/events.ts similarity index 77% rename from src/core/public/utils/events.ts rename to src/core/public/events.ts index 9145355fe3676..2f8ea03ce80fe 100644 --- a/src/core/public/utils/events.ts +++ b/src/core/public/events.ts @@ -9,20 +9,30 @@ /** @internal */ export const KBN_LOAD_MARKS = 'kbnLoad'; -export { KIBANA_LOADED_EVENT } from '../../utils'; +export const KIBANA_LOADED_EVENT = 'kibana_loaded'; -export const LOAD_START = 'load-started'; -export const LOAD_BOOTSTRAP_START = 'bootstrap-started'; -export const LOAD_CORE_CREATED = 'core-created'; -export const LOAD_SETUP_DONE = 'setup-done'; -export const LOAD_START_DONE = 'start-done'; -export const LOAD_FIRST_NAV = 'first-app-nav'; +export const LOAD_START = 'load_started'; +export const LOAD_BOOTSTRAP_START = 'bootstrap_started'; +export const LOAD_CORE_CREATED = 'core_created'; +export const LOAD_SETUP_DONE = 'setup_done'; +export const LOAD_START_DONE = 'start_done'; +export const LOAD_FIRST_NAV = 'first_app_nav'; -export interface PerformanceMetricEvent { + + + +/// remove from this file + +export interface MetricEvent { + type: string; + + // Standardized fields duration?: number; jsHeapSizeLimit?: number; totalJSHeapSize?: number; usedJSHeapSize?: number; + + // Free fields - will be mapped in the index; key1?: string; value1?: number; key2?: string; @@ -35,7 +45,11 @@ export interface PerformanceMetricEvent { value5?: number; } -export const PERFORMANCE_METRIC_EVENT_SCHEMA: Record = { +export const METRIC_EVENT_SCHEMA: Record = { + type: { + type: 'keyword', + _meta: { description: 'Type of the event' }, + }, duration: { type: 'integer', _meta: { description: 'The main event duration in ms', optional: true }, diff --git a/src/core/public/index.ts b/src/core/public/index.ts index 922f197a616a4..68315e851feef 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -362,6 +362,6 @@ export type { NavType, }; -export type { PerformanceMetricEvent } from './utils'; +export type { MetricEvent } from './events'; export { __kbnBootstrap__ } from './kbn_bootstrap'; diff --git a/src/core/public/utils/index.ts b/src/core/public/utils/index.ts index 7cd84fcf61ac4..dc7546b0d4b66 100644 --- a/src/core/public/utils/index.ts +++ b/src/core/public/utils/index.ts @@ -7,16 +7,3 @@ */ export { MountWrapper, mountReactNode } from './mount'; -export { - KBN_LOAD_MARKS, - LOAD_START, - LOAD_CORE_CREATED, - KIBANA_LOADED_EVENT, - LOAD_SETUP_DONE, - LOAD_START_DONE, - LOAD_FIRST_NAV, - LOAD_BOOTSTRAP_START, -} from './events'; - -export type { PerformanceMetricEvent } from './events'; -export { PERFORMANCE_METRIC_EVENT_SCHEMA } from './events'; diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 4852f944a01b1..87767470330df 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -654,4 +654,3 @@ export type { HttpServiceSetup as BaseHttpServiceSetup, }; -export { KIBANA_LOADED_EVENT } from '../utils'; diff --git a/src/core/server/server.ts b/src/core/server/server.ts index f8c7ec968df30..5f811723845c1 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -65,7 +65,7 @@ import type { RequestHandlerContext, PrebootRequestHandlerContext } from '.'; const coreId = Symbol('core'); const rootConfigPath = ''; -const KIBANA_STARTED_EVENT = 'kibana-started'; +const KIBANA_STARTED_EVENT = 'kibana_started'; /** @internal */ interface UptimePerStep { diff --git a/src/core/utils/events.ts b/src/core/utils/events.ts deleted file mode 100644 index a50b66bf51bfc..0000000000000 --- a/src/core/utils/events.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* - * 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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -// TODO: replace with kibana-loaded -export const KIBANA_LOADED_EVENT = 'Loaded Kibana'; diff --git a/src/core/utils/index.ts b/src/core/utils/index.ts index 0cef965c6509d..73980983a12e1 100644 --- a/src/core/utils/index.ts +++ b/src/core/utils/index.ts @@ -8,4 +8,3 @@ export { DEFAULT_APP_CATEGORIES } from './default_app_categories'; export { APP_WRAPPER_CLASS } from './app_wrapper_class'; -export { KIBANA_LOADED_EVENT } from './events'; diff --git a/src/plugins/dashboard/public/application/embeddable/types.ts b/src/plugins/dashboard/public/application/embeddable/types.ts index 434479106e532..30c6fb8bd7b78 100644 --- a/src/plugins/dashboard/public/application/embeddable/types.ts +++ b/src/plugins/dashboard/public/application/embeddable/types.ts @@ -7,10 +7,10 @@ */ export * from '../../../common/types'; -import type { PerformanceMetricEvent } from '@kbn/core/public'; +import type { MetricEvent } from '@kbn/core/public'; export type DashboardLoadedEventStatus = 'done' | 'error'; -export interface DashboardLoadedEvent extends PerformanceMetricEvent { +export interface DashboardLoadedEvent extends MetricEvent { status: DashboardLoadedEventStatus; } diff --git a/src/plugins/dashboard/public/plugin.tsx b/src/plugins/dashboard/public/plugin.tsx index 975f8166c8b3b..3fbd497c13a53 100644 --- a/src/plugins/dashboard/public/plugin.tsx +++ b/src/plugins/dashboard/public/plugin.tsx @@ -29,7 +29,7 @@ import { VisualizationsStart } from '@kbn/visualizations-plugin/public'; import { replaceUrlHashQuery } from '@kbn/kibana-utils-plugin/public'; import { DataViewEditorStart } from '@kbn/data-view-editor-plugin/public'; -import { PERFORMANCE_METRIC_EVENT_SCHEMA } from '@kbn/core/public/utils'; +import { METRIC_EVENT_SCHEMA } from '@kbn/core/public'; import { createKbnUrlTracker } from './services/kibana_utils'; import { UsageCollectionSetup } from './services/usage_collection'; import { UiActionsSetup, UiActionsStart } from './services/ui_actions'; @@ -145,7 +145,7 @@ export class DashboardPlugin analytics.registerEventType({ eventType: DASHBOARD_LOADED_EVENT, schema: { - ...PERFORMANCE_METRIC_EVENT_SCHEMA, + ...METRIC_EVENT_SCHEMA, status: { type: 'keyword', _meta: { description: 'Dashboard load status' }, diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts index a755e47c831d6..4c5e532f00e95 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { Event } from '@kbn/analytics-client'; import { KIBANA_LOADED_EVENT } from '@kbn/core/utils'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../services'; @@ -14,13 +15,25 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const ebtUIHelper = getService('kibana_ebt_ui'); const { common } = getPageObjects(['common']); - describe('Loaded kibana', () => { + describe('Loaded Kibana', () => { beforeEach(async () => { await common.navigateToApp('home'); }); - it('should emit the "Loaded Kibana" event', async () => { - const [event] = await ebtUIHelper.getEvents(1, { eventTypes: [KIBANA_LOADED_EVENT] }); + it('should emit the legacy "Loaded Kibana" and new kibana-loaded events', async () => { + const events = await ebtUIHelper.getEvents(2, { eventTypes: [KIBANA_LOADED_EVENT, 'Loaded Kibana'] }); + + const legacyEvent = events.find(e => e.event_type !== KIBANA_LOADED_EVENT) as unknown as Event; + const event = events.find(e => e.event_type === KIBANA_LOADED_EVENT) as unknown as Event; + + // Legacy event + expect(legacyEvent.event_type).to.eql('Loaded Kibana'); + expect(event.properties).to.have.property('kibana_version'); + expect(event.properties.kibana_version).to.be.a('string'); + expect(event.properties).to.have.property('protocol'); + expect(event.properties.protocol).to.be.a('string'); + + // New event expect(event.event_type).to.eql(KIBANA_LOADED_EVENT); expect(event.properties).to.have.property('kibana_version'); expect(event.properties.kibana_version).to.be.a('string'); @@ -31,11 +44,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(event.properties).to.have.property('duration'); expect(event.properties.duration).to.be.a('number'); - expect(event.properties).to.have.property('key1', 'load-started'); - expect(event.properties).to.have.property('key2', 'bootstrap-started'); - expect(event.properties).to.have.property('key3', 'core-created'); - expect(event.properties).to.have.property('key4', 'setup-done'); - expect(event.properties).to.have.property('key5', 'start-done'); + expect(event.properties).to.have.property('key1', 'load_started'); + expect(event.properties).to.have.property('key2', 'bootstrap_started'); + expect(event.properties).to.have.property('key3', 'core_created'); + expect(event.properties).to.have.property('key4', 'setup_done'); + expect(event.properties).to.have.property('key5', 'start_done'); expect(event.properties.value1).to.be.a('number'); expect(event.properties.value2).to.be.a('number'); diff --git a/x-pack/plugins/cloud/server/config.ts b/x-pack/plugins/cloud/server/config.ts index 27da9b05dc8ee..aebbc65e50f18 100644 --- a/x-pack/plugins/cloud/server/config.ts +++ b/x-pack/plugins/cloud/server/config.ts @@ -6,7 +6,7 @@ */ import { schema, TypeOf } from '@kbn/config-schema'; -import { PluginConfigDescriptor, KIBANA_LOADED_EVENT } from '@kbn/core/server'; +import { PluginConfigDescriptor } from '@kbn/core/server'; const apmConfigSchema = schema.object({ url: schema.maybe(schema.string()), @@ -27,7 +27,7 @@ const fullStoryConfigSchema = schema.object({ schema.maybe(schema.string()) ), eventTypesAllowlist: schema.arrayOf(schema.string(), { - defaultValue: [KIBANA_LOADED_EVENT], + defaultValue: ['Loaded Kibana'], }), }); From f5e846dfffccfcf713548f210524f7399d31a7c3 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 19 Jul 2022 17:00:10 +0300 Subject: [PATCH 13/45] Move code to package --- package.json | 2 + packages/BUILD.bazel | 2 + packages/kbn-ebt-tools/BUILD.bazel | 109 ++++++++++++++++++ packages/kbn-ebt-tools/README.md | 3 + packages/kbn-ebt-tools/jest.config.js | 13 +++ packages/kbn-ebt-tools/package.json | 7 ++ packages/kbn-ebt-tools/src/index.ts | 9 ++ .../kbn-ebt-tools/src/metric-events/index.ts | 8 ++ .../kbn-ebt-tools/src/metric-events/schema.ts | 86 ++++++++++++++ packages/kbn-ebt-tools/tsconfig.json | 16 +++ src/core/public/core_system.ts | 2 +- src/core/public/events.ts | 89 -------------- src/core/public/index.ts | 2 - .../public/application/embeddable/types.ts | 2 +- src/plugins/dashboard/public/plugin.tsx | 2 +- yarn.lock | 10 +- 16 files changed, 267 insertions(+), 95 deletions(-) create mode 100644 packages/kbn-ebt-tools/BUILD.bazel create mode 100644 packages/kbn-ebt-tools/README.md create mode 100644 packages/kbn-ebt-tools/jest.config.js create mode 100644 packages/kbn-ebt-tools/package.json create mode 100644 packages/kbn-ebt-tools/src/index.ts create mode 100644 packages/kbn-ebt-tools/src/metric-events/index.ts create mode 100644 packages/kbn-ebt-tools/src/metric-events/schema.ts create mode 100644 packages/kbn-ebt-tools/tsconfig.json diff --git a/package.json b/package.json index 0ac03ee814d60..fdaa17a49f364 100644 --- a/package.json +++ b/package.json @@ -583,6 +583,7 @@ "@kbn/dev-proc-runner": "link:bazel-bin/packages/kbn-dev-proc-runner", "@kbn/dev-utils": "link:bazel-bin/packages/kbn-dev-utils", "@kbn/docs-utils": "link:bazel-bin/packages/kbn-docs-utils", + "@kbn/ebt-tools": "link:bazel-bin/packages/kbn-ebt-tools", "@kbn/es": "link:bazel-bin/packages/kbn-es", "@kbn/es-archiver": "link:bazel-bin/packages/kbn-es-archiver", "@kbn/eslint-config": "link:bazel-bin/packages/kbn-eslint-config", @@ -813,6 +814,7 @@ "@types/kbn__dev-utils": "link:bazel-bin/packages/kbn-dev-utils/npm_module_types", "@types/kbn__doc-links": "link:bazel-bin/packages/kbn-doc-links/npm_module_types", "@types/kbn__docs-utils": "link:bazel-bin/packages/kbn-docs-utils/npm_module_types", + "@types/kbn__ebt-tools": "link:bazel-bin/packages/kbn-kbn__ebt-tools/npm_module_types", "@types/kbn__es-archiver": "link:bazel-bin/packages/kbn-es-archiver/npm_module_types", "@types/kbn__es-errors": "link:bazel-bin/packages/kbn-es-errors/npm_module_types", "@types/kbn__es-query": "link:bazel-bin/packages/kbn-es-query/npm_module_types", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index 8941724c39751..b8f68ad18fc18 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -178,6 +178,7 @@ filegroup( "//packages/kbn-storybook:build", "//packages/kbn-synthetic-package-map:build", "//packages/kbn-telemetry-tools:build", + "//packages/kbn-ebt-tools:build", "//packages/kbn-test-jest-helpers:build", "//packages/kbn-test-subj-selector:build", "//packages/kbn-test:build", @@ -375,6 +376,7 @@ filegroup( "//packages/kbn-stdio-dev-helpers:build_types", "//packages/kbn-storybook:build_types", "//packages/kbn-telemetry-tools:build_types", + "//packages/kbn-ebt-tools:build_types", "//packages/kbn-test-jest-helpers:build_types", "//packages/kbn-test:build_types", "//packages/kbn-tooling-log:build_types", diff --git a/packages/kbn-ebt-tools/BUILD.bazel b/packages/kbn-ebt-tools/BUILD.bazel new file mode 100644 index 0000000000000..c35b535dbcd1d --- /dev/null +++ b/packages/kbn-ebt-tools/BUILD.bazel @@ -0,0 +1,109 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_BASE_NAME = "kbn-ebt-tools" +PKG_REQUIRE_NAME = "@kbn/ebt-tools" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + ], + exclude = ["**/*.test.*"], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", + "README.md" +] + +RUNTIME_DEPS = [ + "//packages/analytics/client", + "//packages/kbn-config-schema", + "@npm//load-json-file", + "@npm//tslib", +] + +TYPES_DEPS = [ + "//packages/kbn-config-schema:npm_module_types", + "//packages/analytics/client:npm_module_types", + "@npm//load-json-file", + "@npm//tslib", + "@npm//@types/jest", + "@npm//@types/node", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + root_dir = "src", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_BASE_NAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node", ":tsc_types"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [ + ":%s" % PKG_BASE_NAME, + ] +) + +filegroup( + name = "build", + srcs = [ + ":npm_module", + ], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-ebt-tools/README.md b/packages/kbn-ebt-tools/README.md new file mode 100644 index 0000000000000..72aae680b49b8 --- /dev/null +++ b/packages/kbn-ebt-tools/README.md @@ -0,0 +1,3 @@ +# @kbn/ebt-tools + +Shared tools for event based telemetry \ No newline at end of file diff --git a/packages/kbn-ebt-tools/jest.config.js b/packages/kbn-ebt-tools/jest.config.js new file mode 100644 index 0000000000000..56faeaaa0b324 --- /dev/null +++ b/packages/kbn-ebt-tools/jest.config.js @@ -0,0 +1,13 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../..', + roots: ['/packages/kbn-ebt-tools'], +}; diff --git a/packages/kbn-ebt-tools/package.json b/packages/kbn-ebt-tools/package.json new file mode 100644 index 0000000000000..78d0978698987 --- /dev/null +++ b/packages/kbn-ebt-tools/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/ebt-tools", + "main": "./target_node/index.js", + "version": "1.0.0", + "license": "SSPL-1.0 OR Elastic License 2.0", + "private": true +} \ No newline at end of file diff --git a/packages/kbn-ebt-tools/src/index.ts b/packages/kbn-ebt-tools/src/index.ts new file mode 100644 index 0000000000000..bfb91f4098fb7 --- /dev/null +++ b/packages/kbn-ebt-tools/src/index.ts @@ -0,0 +1,9 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export * from './metric-events'; diff --git a/packages/kbn-ebt-tools/src/metric-events/index.ts b/packages/kbn-ebt-tools/src/metric-events/index.ts new file mode 100644 index 0000000000000..f7917ef92090b --- /dev/null +++ b/packages/kbn-ebt-tools/src/metric-events/index.ts @@ -0,0 +1,8 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +export { METRIC_EVENT_SCHEMA, MetricEvent } from './schema'; \ No newline at end of file diff --git a/packages/kbn-ebt-tools/src/metric-events/schema.ts b/packages/kbn-ebt-tools/src/metric-events/schema.ts new file mode 100644 index 0000000000000..06dacb7cbc3fe --- /dev/null +++ b/packages/kbn-ebt-tools/src/metric-events/schema.ts @@ -0,0 +1,86 @@ + + +export interface MetricEvent { + type: string; + + // Standardized fields + duration?: number; + jsHeapSizeLimit?: number; + totalJSHeapSize?: number; + usedJSHeapSize?: number; + + // Free fields - will be mapped in the index; + key1?: string; + value1?: number; + key2?: string; + value2?: number; + key3?: string; + value3?: number; + key4?: string; + value4?: number; + key5?: string; + value5?: number; +} + +export const METRIC_EVENT_SCHEMA: Record = { + type: { + type: 'keyword', + _meta: { description: 'Type of the event' }, + }, + duration: { + type: 'integer', + _meta: { description: 'The main event duration in ms', optional: true }, + }, + jsHeapSizeLimit: { + type: 'long', + _meta: { description: 'performance.memory.jsHeapSizeLimit', optional: true }, + }, + totalJSHeapSize: { + type: 'long', + _meta: { description: 'performance.memory.totalJSHeapSize', optional: true }, + }, + usedJSHeapSize: { + type: 'long', + _meta: { description: 'performance.memory.usedJSHeapSize', optional: true }, + }, + key1: { + type: 'keyword', + _meta: { description: 'Performance metric label', optional: true }, + }, + value1: { + type: 'long', + _meta: { description: 'Performance metric value', optional: true }, + }, + key2: { + type: 'keyword', + _meta: { description: 'Performance metric label', optional: true }, + }, + value2: { + type: 'long', + _meta: { description: 'Performance metric value', optional: true }, + }, + key3: { + type: 'keyword', + _meta: { description: 'Performance metric label', optional: true }, + }, + value3: { + type: 'long', + _meta: { description: 'Performance metric value', optional: true }, + }, + key4: { + type: 'keyword', + _meta: { description: 'Performance metric label', optional: true }, + }, + value4: { + type: 'long', + _meta: { description: 'Performance metric value', optional: true }, + }, + key5: { + type: 'keyword', + _meta: { description: 'Performance metric label', optional: true }, + }, + value5: { + type: 'long', + _meta: { description: 'Performance metric value', optional: true }, + }, +}; diff --git a/packages/kbn-ebt-tools/tsconfig.json b/packages/kbn-ebt-tools/tsconfig.json new file mode 100644 index 0000000000000..bb93370ed412f --- /dev/null +++ b/packages/kbn-ebt-tools/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "types": [ + "jest", + "node" + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 7224a2f7ce28c..f0d4dbde06147 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -25,6 +25,7 @@ import { FatalErrorsService } from '@kbn/core-fatal-errors-browser-internal'; import { HttpService } from '@kbn/core-http-browser-internal'; import { UiSettingsService } from '@kbn/core-ui-settings-browser-internal'; import { DeprecationsService } from '@kbn/core-deprecations-browser-internal'; +import { METRIC_EVENT_SCHEMA } from '@kbn/ebt-tools'; import { CoreSetup, CoreStart } from '.'; import { ChromeService } from './chrome'; import { NotificationsService } from './notifications'; @@ -42,7 +43,6 @@ import { LOAD_START_DONE, KIBANA_LOADED_EVENT, LOAD_CORE_CREATED, - METRIC_EVENT_SCHEMA, LOAD_FIRST_NAV, LOAD_BOOTSTRAP_START, LOAD_START, diff --git a/src/core/public/events.ts b/src/core/public/events.ts index 2f8ea03ce80fe..59c2db7a672c5 100644 --- a/src/core/public/events.ts +++ b/src/core/public/events.ts @@ -18,92 +18,3 @@ export const LOAD_SETUP_DONE = 'setup_done'; export const LOAD_START_DONE = 'start_done'; export const LOAD_FIRST_NAV = 'first_app_nav'; - - - -/// remove from this file - -export interface MetricEvent { - type: string; - - // Standardized fields - duration?: number; - jsHeapSizeLimit?: number; - totalJSHeapSize?: number; - usedJSHeapSize?: number; - - // Free fields - will be mapped in the index; - key1?: string; - value1?: number; - key2?: string; - value2?: number; - key3?: string; - value3?: number; - key4?: string; - value4?: number; - key5?: string; - value5?: number; -} - -export const METRIC_EVENT_SCHEMA: Record = { - type: { - type: 'keyword', - _meta: { description: 'Type of the event' }, - }, - duration: { - type: 'integer', - _meta: { description: 'The main event duration in ms', optional: true }, - }, - jsHeapSizeLimit: { - type: 'long', - _meta: { description: 'performance.memory.jsHeapSizeLimit', optional: true }, - }, - totalJSHeapSize: { - type: 'long', - _meta: { description: 'performance.memory.totalJSHeapSize', optional: true }, - }, - usedJSHeapSize: { - type: 'long', - _meta: { description: 'performance.memory.usedJSHeapSize', optional: true }, - }, - key1: { - type: 'keyword', - _meta: { description: 'Performance metric label', optional: true }, - }, - value1: { - type: 'long', - _meta: { description: 'Performance metric value', optional: true }, - }, - key2: { - type: 'keyword', - _meta: { description: 'Performance metric label', optional: true }, - }, - value2: { - type: 'long', - _meta: { description: 'Performance metric value', optional: true }, - }, - key3: { - type: 'keyword', - _meta: { description: 'Performance metric label', optional: true }, - }, - value3: { - type: 'long', - _meta: { description: 'Performance metric value', optional: true }, - }, - key4: { - type: 'keyword', - _meta: { description: 'Performance metric label', optional: true }, - }, - value4: { - type: 'long', - _meta: { description: 'Performance metric value', optional: true }, - }, - key5: { - type: 'keyword', - _meta: { description: 'Performance metric label', optional: true }, - }, - value5: { - type: 'long', - _meta: { description: 'Performance metric value', optional: true }, - }, -}; diff --git a/src/core/public/index.ts b/src/core/public/index.ts index 68315e851feef..ccde84105ea89 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -362,6 +362,4 @@ export type { NavType, }; -export type { MetricEvent } from './events'; - export { __kbnBootstrap__ } from './kbn_bootstrap'; diff --git a/src/plugins/dashboard/public/application/embeddable/types.ts b/src/plugins/dashboard/public/application/embeddable/types.ts index 30c6fb8bd7b78..5cc527111c615 100644 --- a/src/plugins/dashboard/public/application/embeddable/types.ts +++ b/src/plugins/dashboard/public/application/embeddable/types.ts @@ -7,7 +7,7 @@ */ export * from '../../../common/types'; -import type { MetricEvent } from '@kbn/core/public'; +import type { MetricEvent } from '@kbn/ebt-tools'; export type DashboardLoadedEventStatus = 'done' | 'error'; diff --git a/src/plugins/dashboard/public/plugin.tsx b/src/plugins/dashboard/public/plugin.tsx index 3fbd497c13a53..a83eca68f8c14 100644 --- a/src/plugins/dashboard/public/plugin.tsx +++ b/src/plugins/dashboard/public/plugin.tsx @@ -29,7 +29,7 @@ import { VisualizationsStart } from '@kbn/visualizations-plugin/public'; import { replaceUrlHashQuery } from '@kbn/kibana-utils-plugin/public'; import { DataViewEditorStart } from '@kbn/data-view-editor-plugin/public'; -import { METRIC_EVENT_SCHEMA } from '@kbn/core/public'; +import { METRIC_EVENT_SCHEMA } from '@kbn/ebt-tools'; import { createKbnUrlTracker } from './services/kibana_utils'; import { UsageCollectionSetup } from './services/usage_collection'; import { UiActionsSetup, UiActionsStart } from './services/ui_actions'; diff --git a/yarn.lock b/yarn.lock index 09706189e02aa..47728c741f4d2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3387,6 +3387,10 @@ version "0.0.0" uid "" +"@kbn/ebt-tools@link:bazel-bin/packages/kbn-ebt-tools": + version "0.0.0" + uid "" + "@kbn/es-archiver@link:bazel-bin/packages/kbn-es-archiver": version "0.0.0" uid "" @@ -7065,6 +7069,10 @@ version "0.0.0" uid "" +"@types/kbn__ebt-tools@link:bazel-bin/packages/kbn-kbn__ebt-tools/npm_module_types": + version "0.0.0" + uid "" + "@types/kbn__es-archiver@link:bazel-bin/packages/kbn-es-archiver/npm_module_types": version "0.0.0" uid "" @@ -11835,7 +11843,7 @@ core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.9: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== -core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2, core-js@^3.8.3, core-js@^3.23.5: +core-js@^3.0.4, core-js@^3.23.5, core-js@^3.6.5, core-js@^3.8.2, core-js@^3.8.3: version "3.23.5" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.23.5.tgz#1f82b0de5eece800827a2f59d597509c67650475" integrity sha512-7Vh11tujtAZy82da4duVreQysIoO2EvVrur7y6IzZkH1IHPSekuDi8Vuw1+YKjkbfWLRD7Nc9ICQ/sIUDutcyg== From 4f217a4c3f34de9036e4c64eb92beca1f92c6a91 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 19 Jul 2022 17:04:33 +0300 Subject: [PATCH 14/45] rename --- packages/kbn-ebt-tools/src/index.ts | 2 +- .../kbn-ebt-tools/src/metric-events/schema.ts | 86 ----------------- .../{metric-events => metric_events}/index.ts | 0 .../kbn-ebt-tools/src/metric_events/schema.ts | 92 +++++++++++++++++++ 4 files changed, 93 insertions(+), 87 deletions(-) delete mode 100644 packages/kbn-ebt-tools/src/metric-events/schema.ts rename packages/kbn-ebt-tools/src/{metric-events => metric_events}/index.ts (100%) create mode 100644 packages/kbn-ebt-tools/src/metric_events/schema.ts diff --git a/packages/kbn-ebt-tools/src/index.ts b/packages/kbn-ebt-tools/src/index.ts index bfb91f4098fb7..334913623b12a 100644 --- a/packages/kbn-ebt-tools/src/index.ts +++ b/packages/kbn-ebt-tools/src/index.ts @@ -6,4 +6,4 @@ * Side Public License, v 1. */ -export * from './metric-events'; +export * from './metric_events'; diff --git a/packages/kbn-ebt-tools/src/metric-events/schema.ts b/packages/kbn-ebt-tools/src/metric-events/schema.ts deleted file mode 100644 index 06dacb7cbc3fe..0000000000000 --- a/packages/kbn-ebt-tools/src/metric-events/schema.ts +++ /dev/null @@ -1,86 +0,0 @@ - - -export interface MetricEvent { - type: string; - - // Standardized fields - duration?: number; - jsHeapSizeLimit?: number; - totalJSHeapSize?: number; - usedJSHeapSize?: number; - - // Free fields - will be mapped in the index; - key1?: string; - value1?: number; - key2?: string; - value2?: number; - key3?: string; - value3?: number; - key4?: string; - value4?: number; - key5?: string; - value5?: number; -} - -export const METRIC_EVENT_SCHEMA: Record = { - type: { - type: 'keyword', - _meta: { description: 'Type of the event' }, - }, - duration: { - type: 'integer', - _meta: { description: 'The main event duration in ms', optional: true }, - }, - jsHeapSizeLimit: { - type: 'long', - _meta: { description: 'performance.memory.jsHeapSizeLimit', optional: true }, - }, - totalJSHeapSize: { - type: 'long', - _meta: { description: 'performance.memory.totalJSHeapSize', optional: true }, - }, - usedJSHeapSize: { - type: 'long', - _meta: { description: 'performance.memory.usedJSHeapSize', optional: true }, - }, - key1: { - type: 'keyword', - _meta: { description: 'Performance metric label', optional: true }, - }, - value1: { - type: 'long', - _meta: { description: 'Performance metric value', optional: true }, - }, - key2: { - type: 'keyword', - _meta: { description: 'Performance metric label', optional: true }, - }, - value2: { - type: 'long', - _meta: { description: 'Performance metric value', optional: true }, - }, - key3: { - type: 'keyword', - _meta: { description: 'Performance metric label', optional: true }, - }, - value3: { - type: 'long', - _meta: { description: 'Performance metric value', optional: true }, - }, - key4: { - type: 'keyword', - _meta: { description: 'Performance metric label', optional: true }, - }, - value4: { - type: 'long', - _meta: { description: 'Performance metric value', optional: true }, - }, - key5: { - type: 'keyword', - _meta: { description: 'Performance metric label', optional: true }, - }, - value5: { - type: 'long', - _meta: { description: 'Performance metric value', optional: true }, - }, -}; diff --git a/packages/kbn-ebt-tools/src/metric-events/index.ts b/packages/kbn-ebt-tools/src/metric_events/index.ts similarity index 100% rename from packages/kbn-ebt-tools/src/metric-events/index.ts rename to packages/kbn-ebt-tools/src/metric_events/index.ts diff --git a/packages/kbn-ebt-tools/src/metric_events/schema.ts b/packages/kbn-ebt-tools/src/metric_events/schema.ts new file mode 100644 index 0000000000000..6b2b7cef0539f --- /dev/null +++ b/packages/kbn-ebt-tools/src/metric_events/schema.ts @@ -0,0 +1,92 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export interface MetricEvent { + type: string; + + // Standardized fields + duration?: number; + jsHeapSizeLimit?: number; + totalJSHeapSize?: number; + usedJSHeapSize?: number; + + // Free fields - will be mapped in the index; + key1?: string; + value1?: number; + key2?: string; + value2?: number; + key3?: string; + value3?: number; + key4?: string; + value4?: number; + key5?: string; + value5?: number; +} + +export const METRIC_EVENT_SCHEMA: Record = { + type: { + type: 'keyword', + _meta: { description: 'Type of the event' }, + }, + duration: { + type: 'integer', + _meta: { description: 'The main event duration in ms', optional: true }, + }, + jsHeapSizeLimit: { + type: 'long', + _meta: { description: 'performance.memory.jsHeapSizeLimit', optional: true }, + }, + totalJSHeapSize: { + type: 'long', + _meta: { description: 'performance.memory.totalJSHeapSize', optional: true }, + }, + usedJSHeapSize: { + type: 'long', + _meta: { description: 'performance.memory.usedJSHeapSize', optional: true }, + }, + key1: { + type: 'keyword', + _meta: { description: 'Performance metric label', optional: true }, + }, + value1: { + type: 'long', + _meta: { description: 'Performance metric value', optional: true }, + }, + key2: { + type: 'keyword', + _meta: { description: 'Performance metric label', optional: true }, + }, + value2: { + type: 'long', + _meta: { description: 'Performance metric value', optional: true }, + }, + key3: { + type: 'keyword', + _meta: { description: 'Performance metric label', optional: true }, + }, + value3: { + type: 'long', + _meta: { description: 'Performance metric value', optional: true }, + }, + key4: { + type: 'keyword', + _meta: { description: 'Performance metric label', optional: true }, + }, + value4: { + type: 'long', + _meta: { description: 'Performance metric value', optional: true }, + }, + key5: { + type: 'keyword', + _meta: { description: 'Performance metric label', optional: true }, + }, + value5: { + type: 'long', + _meta: { description: 'Performance metric value', optional: true }, + }, +}; From ce91896b56a2d4db407aa7d27dc59aee3570dea1 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 19 Jul 2022 17:10:12 +0300 Subject: [PATCH 15/45] lint --- packages/kbn-ebt-tools/src/metric_events/index.ts | 2 +- src/core/server/index.ts | 1 - .../bootstrap/__snapshots__/render_template.test.ts.snap | 2 +- src/core/server/rendering/bootstrap/render_template.ts | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/kbn-ebt-tools/src/metric_events/index.ts b/packages/kbn-ebt-tools/src/metric_events/index.ts index f7917ef92090b..668479c4e9af1 100644 --- a/packages/kbn-ebt-tools/src/metric_events/index.ts +++ b/packages/kbn-ebt-tools/src/metric_events/index.ts @@ -5,4 +5,4 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -export { METRIC_EVENT_SCHEMA, MetricEvent } from './schema'; \ No newline at end of file +export { METRIC_EVENT_SCHEMA, MetricEvent } from './schema'; diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 87767470330df..82d98f875241e 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -653,4 +653,3 @@ export type { PublicHttpServiceSetup as HttpServiceSetup, HttpServiceSetup as BaseHttpServiceSetup, }; - diff --git a/src/core/server/rendering/bootstrap/__snapshots__/render_template.test.ts.snap b/src/core/server/rendering/bootstrap/__snapshots__/render_template.test.ts.snap index 109bcd710f434..f7e28eebd1a61 100644 --- a/src/core/server/rendering/bootstrap/__snapshots__/render_template.test.ts.snap +++ b/src/core/server/rendering/bootstrap/__snapshots__/render_template.test.ts.snap @@ -105,7 +105,7 @@ if (window.__kbnStrictCsp__ && window.__kbnCspNotEnforced__) { } performance.mark('kbnLoad', { - detail: 'load-started', + detail: 'load_started', }) load([ diff --git a/src/core/server/rendering/bootstrap/render_template.ts b/src/core/server/rendering/bootstrap/render_template.ts index 8c85f42f737cd..996aacd5e3ede 100644 --- a/src/core/server/rendering/bootstrap/render_template.ts +++ b/src/core/server/rendering/bootstrap/render_template.ts @@ -121,7 +121,7 @@ if (window.__kbnStrictCsp__ && window.__kbnCspNotEnforced__) { } performance.mark('kbnLoad', { - detail: 'load-started', + detail: 'load_started', }) load([ From af0f047e12df7674ea0868dbec8b9d1dffc22c34 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 19 Jul 2022 17:11:23 +0300 Subject: [PATCH 16/45] ts --- .../public/application/embeddable/dashboard_container.tsx | 4 ++-- src/plugins/dashboard/public/events.ts | 2 +- .../from_the_browser/loaded_dashboard.ts | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx index f4d5513efe0ac..d204ba3c2ab95 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx @@ -167,9 +167,9 @@ export class DashboardContainer extends Container Date: Tue, 19 Jul 2022 17:16:24 +0300 Subject: [PATCH 17/45] import --- .../from_the_browser/core_context_providers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts b/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts index b2da32f570a8c..e413aea8e410e 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts @@ -8,8 +8,8 @@ import expect from '@kbn/expect'; import { Event } from '@kbn/core/public'; -import { KIBANA_LOADED_EVENT } from '@kbn/core/utils'; import { FtrProviderContext } from '../../../services'; +import { KIBANA_LOADED_EVENT } from '@kbn/core/public/events'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const deployment = getService('deployment'); From 0c7de8b7ac846cdf23156b20442cd62dd9d87326 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 19 Jul 2022 14:22:25 +0000 Subject: [PATCH 18/45] [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' --- .../from_the_browser/core_context_providers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts b/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts index e413aea8e410e..4fda618fffb07 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts @@ -8,8 +8,8 @@ import expect from '@kbn/expect'; import { Event } from '@kbn/core/public'; -import { FtrProviderContext } from '../../../services'; import { KIBANA_LOADED_EVENT } from '@kbn/core/public/events'; +import { FtrProviderContext } from '../../../services'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const deployment = getService('deployment'); From 8fcf8c31b2c4cf475de422cd2bbaff1a3bfcdd1a Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 19 Jul 2022 14:29:05 +0000 Subject: [PATCH 19/45] [CI] Auto-commit changed files from 'node scripts/generate packages_build_manifest' --- packages/BUILD.bazel | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index a735ecfa71dd8..f96f7d65179b4 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -118,6 +118,7 @@ filegroup( "//packages/kbn-dev-utils:build", "//packages/kbn-doc-links:build", "//packages/kbn-docs-utils:build", + "//packages/kbn-ebt-tools:build", "//packages/kbn-es-archiver:build", "//packages/kbn-es-errors:build", "//packages/kbn-es-query:build", @@ -180,7 +181,6 @@ filegroup( "//packages/kbn-storybook:build", "//packages/kbn-synthetic-package-map:build", "//packages/kbn-telemetry-tools:build", - "//packages/kbn-ebt-tools:build", "//packages/kbn-test-jest-helpers:build", "//packages/kbn-test-subj-selector:build", "//packages/kbn-test:build", @@ -325,6 +325,7 @@ filegroup( "//packages/kbn-dev-utils:build_types", "//packages/kbn-doc-links:build_types", "//packages/kbn-docs-utils:build_types", + "//packages/kbn-ebt-tools:build_types", "//packages/kbn-es-archiver:build_types", "//packages/kbn-es-errors:build_types", "//packages/kbn-es-query:build_types", @@ -380,7 +381,6 @@ filegroup( "//packages/kbn-stdio-dev-helpers:build_types", "//packages/kbn-storybook:build_types", "//packages/kbn-telemetry-tools:build_types", - "//packages/kbn-ebt-tools:build_types", "//packages/kbn-test-jest-helpers:build_types", "//packages/kbn-test:build_types", "//packages/kbn-tooling-log:build_types", From 1b1598167a3d7adb3bd1126dada04555d63cce75 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 19 Jul 2022 17:40:01 +0300 Subject: [PATCH 20/45] import --- src/core/public/kbn_bootstrap.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/public/kbn_bootstrap.ts b/src/core/public/kbn_bootstrap.ts index e4b1b2f1bd927..167aa712aab6f 100644 --- a/src/core/public/kbn_bootstrap.ts +++ b/src/core/public/kbn_bootstrap.ts @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n'; import { CoreSystem } from './core_system'; import { ApmSystem } from './apm_system'; -import { KBN_LOAD_MARKS, LOAD_BOOTSTRAP_START } from './utils'; +import { KBN_LOAD_MARKS, LOAD_BOOTSTRAP_START } from './events'; /** @internal */ export async function __kbnBootstrap__() { From cb98b78495b0599288b93ce06a0df52494c6362b Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 19 Jul 2022 15:36:57 +0000 Subject: [PATCH 21/45] [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' --- src/core/public/core_system.ts | 4 ++-- src/core/public/events.ts | 1 - .../from_the_browser/loaded_kibana.ts | 10 +++++++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 8c953fdf0a42d..d43d11f0ac603 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -156,12 +156,12 @@ export class CoreSystem { private reportKibanaLoadedEvent(analytics: AnalyticsServiceStart) { /** * @deprecated here for backwards compatibility in Fullstory - **/ + **/ analytics.reportEvent('Loaded Kibana', { kibana_version: this.coreContext.env.packageInfo.version, protocol: window.location.protocol, }); - + const timing = this.getLoadMarksInfo(); analytics.reportEvent(KIBANA_LOADED_EVENT, { kibana_version: this.coreContext.env.packageInfo.version, diff --git a/src/core/public/events.ts b/src/core/public/events.ts index 59c2db7a672c5..e2f5d48ddfe3d 100644 --- a/src/core/public/events.ts +++ b/src/core/public/events.ts @@ -17,4 +17,3 @@ export const LOAD_CORE_CREATED = 'core_created'; export const LOAD_SETUP_DONE = 'setup_done'; export const LOAD_START_DONE = 'start_done'; export const LOAD_FIRST_NAV = 'first_app_nav'; - diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts index 4c5e532f00e95..34ad45c92008e 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts @@ -21,10 +21,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should emit the legacy "Loaded Kibana" and new kibana-loaded events', async () => { - const events = await ebtUIHelper.getEvents(2, { eventTypes: [KIBANA_LOADED_EVENT, 'Loaded Kibana'] }); + const events = await ebtUIHelper.getEvents(2, { + eventTypes: [KIBANA_LOADED_EVENT, 'Loaded Kibana'], + }); - const legacyEvent = events.find(e => e.event_type !== KIBANA_LOADED_EVENT) as unknown as Event; - const event = events.find(e => e.event_type === KIBANA_LOADED_EVENT) as unknown as Event; + const legacyEvent = events.find( + (e) => e.event_type !== KIBANA_LOADED_EVENT + ) as unknown as Event; + const event = events.find((e) => e.event_type === KIBANA_LOADED_EVENT) as unknown as Event; // Legacy event expect(legacyEvent.event_type).to.eql('Loaded Kibana'); From 27f6d5c5e297c95fd702beeeae4e45e4313ed951 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 19 Jul 2022 19:44:52 +0300 Subject: [PATCH 22/45] fix package + create wrapper --- package.json | 2 +- packages/kbn-ebt-tools/BUILD.bazel | 2 - packages/kbn-ebt-tools/package.json | 3 +- .../src/metric_events/helpers.ts | 23 +++++++++++ .../kbn-ebt-tools/src/metric_events/index.ts | 3 +- .../kbn-ebt-tools/src/metric_events/schema.ts | 16 ++++++-- src/core/public/core_system.ts | 39 ++++++------------- src/core/server/server.ts | 8 +++- .../embeddable/dashboard_container.tsx | 4 +- .../public/application/embeddable/types.ts | 3 +- src/plugins/dashboard/public/plugin.tsx | 18 --------- 11 files changed, 64 insertions(+), 57 deletions(-) create mode 100644 packages/kbn-ebt-tools/src/metric_events/helpers.ts diff --git a/package.json b/package.json index 1e5d594bf8e1e..4bbd07caf2d38 100644 --- a/package.json +++ b/package.json @@ -222,6 +222,7 @@ "@kbn/crypto-browser": "link:bazel-bin/packages/kbn-crypto-browser", "@kbn/datemath": "link:bazel-bin/packages/kbn-datemath", "@kbn/doc-links": "link:bazel-bin/packages/kbn-doc-links", + "@kbn/ebt-tools": "link:bazel-bin/packages/kbn-ebt-tools", "@kbn/es-errors": "link:bazel-bin/packages/kbn-es-errors", "@kbn/es-query": "link:bazel-bin/packages/kbn-es-query", "@kbn/eslint-plugin-imports": "link:bazel-bin/packages/kbn-eslint-plugin-imports", @@ -585,7 +586,6 @@ "@kbn/dev-proc-runner": "link:bazel-bin/packages/kbn-dev-proc-runner", "@kbn/dev-utils": "link:bazel-bin/packages/kbn-dev-utils", "@kbn/docs-utils": "link:bazel-bin/packages/kbn-docs-utils", - "@kbn/ebt-tools": "link:bazel-bin/packages/kbn-ebt-tools", "@kbn/es": "link:bazel-bin/packages/kbn-es", "@kbn/es-archiver": "link:bazel-bin/packages/kbn-es-archiver", "@kbn/eslint-config": "link:bazel-bin/packages/kbn-eslint-config", diff --git a/packages/kbn-ebt-tools/BUILD.bazel b/packages/kbn-ebt-tools/BUILD.bazel index c35b535dbcd1d..3b4e37ca356ff 100644 --- a/packages/kbn-ebt-tools/BUILD.bazel +++ b/packages/kbn-ebt-tools/BUILD.bazel @@ -26,13 +26,11 @@ NPM_MODULE_EXTRA_FILES = [ RUNTIME_DEPS = [ "//packages/analytics/client", - "//packages/kbn-config-schema", "@npm//load-json-file", "@npm//tslib", ] TYPES_DEPS = [ - "//packages/kbn-config-schema:npm_module_types", "//packages/analytics/client:npm_module_types", "@npm//load-json-file", "@npm//tslib", diff --git a/packages/kbn-ebt-tools/package.json b/packages/kbn-ebt-tools/package.json index 78d0978698987..5e5136966b5f9 100644 --- a/packages/kbn-ebt-tools/package.json +++ b/packages/kbn-ebt-tools/package.json @@ -1,7 +1,8 @@ { "name": "@kbn/ebt-tools", - "main": "./target_node/index.js", "version": "1.0.0", "license": "SSPL-1.0 OR Elastic License 2.0", + "browser": "./target_web/index.js", + "main": "./target_node/index.js", "private": true } \ No newline at end of file diff --git a/packages/kbn-ebt-tools/src/metric_events/helpers.ts b/packages/kbn-ebt-tools/src/metric_events/helpers.ts new file mode 100644 index 0000000000000..af2b1f66127a3 --- /dev/null +++ b/packages/kbn-ebt-tools/src/metric_events/helpers.ts @@ -0,0 +1,23 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { AnalyticsClient } from '@kbn/analytics-client'; +import { MetricEvent, METRIC_EVENT_SCHEMA } from './schema'; + +const METRIC_EVENT_TYPE = 'metric-event'; + +export function registerMetricEvent(analytics: AnalyticsClient) { + analytics.registerEventType({ + eventType: METRIC_EVENT_TYPE, + schema: METRIC_EVENT_SCHEMA, + }); +} + +export function reportMetricEvent(analytics: AnalyticsClient, eventData: MetricEvent) { + analytics.reportEvent(METRIC_EVENT_TYPE, eventData); +} diff --git a/packages/kbn-ebt-tools/src/metric_events/index.ts b/packages/kbn-ebt-tools/src/metric_events/index.ts index 668479c4e9af1..82a7dee173c7f 100644 --- a/packages/kbn-ebt-tools/src/metric_events/index.ts +++ b/packages/kbn-ebt-tools/src/metric_events/index.ts @@ -5,4 +5,5 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -export { METRIC_EVENT_SCHEMA, MetricEvent } from './schema'; +export type { MetricEvent } from './schema'; +export type { registerMetricEvent, reportMetricEvent } from './helpers'; diff --git a/packages/kbn-ebt-tools/src/metric_events/schema.ts b/packages/kbn-ebt-tools/src/metric_events/schema.ts index 6b2b7cef0539f..01c49b1fc95c9 100644 --- a/packages/kbn-ebt-tools/src/metric_events/schema.ts +++ b/packages/kbn-ebt-tools/src/metric_events/schema.ts @@ -6,11 +6,13 @@ * Side Public License, v 1. */ -export interface MetricEvent { - type: string; +export interface MetricEvent extends Record { + event_name: string; + meta?: Record; // Standardized fields duration?: number; + status?: string; jsHeapSizeLimit?: number; totalJSHeapSize?: number; usedJSHeapSize?: number; @@ -29,14 +31,22 @@ export interface MetricEvent { } export const METRIC_EVENT_SCHEMA: Record = { - type: { + event_name: { type: 'keyword', _meta: { description: 'Type of the event' }, }, + meta: { + type: 'passthrough', + _meta: { description: 'Meta data that is searchable but not aggregatable', optional: true }, + }, duration: { type: 'integer', _meta: { description: 'The main event duration in ms', optional: true }, }, + status: { + type: 'keyword', + _meta: { description: 'A status', optional: true }, + }, jsHeapSizeLimit: { type: 'long', _meta: { description: 'performance.memory.jsHeapSizeLimit', optional: true }, diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 8c953fdf0a42d..f6a73e157e76a 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -16,7 +16,7 @@ import { } from '@kbn/core-injected-metadata-browser-internal'; import { DocLinksService } from '@kbn/core-doc-links-browser-internal'; import { ThemeService } from '@kbn/core-theme-browser-internal'; -import type { AnalyticsServiceSetup, AnalyticsServiceStart } from '@kbn/core-analytics-browser'; +import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import { AnalyticsService } from '@kbn/core-analytics-browser-internal'; import { I18nService } from '@kbn/core-i18n-browser-internal'; import { ExecutionContextService } from '@kbn/core-execution-context-browser-internal'; @@ -25,8 +25,8 @@ import { FatalErrorsService } from '@kbn/core-fatal-errors-browser-internal'; import { HttpService } from '@kbn/core-http-browser-internal'; import { UiSettingsService } from '@kbn/core-ui-settings-browser-internal'; import { DeprecationsService } from '@kbn/core-deprecations-browser-internal'; -import { METRIC_EVENT_SCHEMA } from '@kbn/ebt-tools'; import { IntegrationsService } from '@kbn/core-integrations-browser-internal'; +import { registerMetricEvent, reportMetricEvent } from '@kbn/ebt-tools'; import { CoreSetup, CoreStart } from '.'; import { ChromeService } from './chrome'; import { NotificationsService } from './notifications'; @@ -156,16 +156,19 @@ export class CoreSystem { private reportKibanaLoadedEvent(analytics: AnalyticsServiceStart) { /** * @deprecated here for backwards compatibility in Fullstory - **/ + **/ analytics.reportEvent('Loaded Kibana', { kibana_version: this.coreContext.env.packageInfo.version, protocol: window.location.protocol, }); - + const timing = this.getLoadMarksInfo(); - analytics.reportEvent(KIBANA_LOADED_EVENT, { - kibana_version: this.coreContext.env.packageInfo.version, - protocol: window.location.protocol, + reportMetricEvent({ + event_name: KIBANA_LOADED_EVENT, + meta: { + kibana_version: this.coreContext.env.packageInfo.version, + protocol: window.location.protocol, + }, duration: timing[LOAD_FIRST_NAV], // @ts-expect-error 2339 ...performance.memory, @@ -199,7 +202,8 @@ export class CoreSystem { this.docLinks.setup(); const analytics = this.analytics.setup({ injectedMetadata }); - this.registerLoadedKibanaEventType(analytics); + + registerMetricEvent(analytics); const executionContext = this.executionContext.setup({ analytics }); const http = this.http.setup({ @@ -370,23 +374,4 @@ export class CoreSystem { this.analytics.stop(); this.rootDomElement.textContent = ''; } - - private registerLoadedKibanaEventType(analytics: AnalyticsServiceSetup) { - analytics.registerEventType({ - eventType: KIBANA_LOADED_EVENT, - schema: { - ...METRIC_EVENT_SCHEMA, - kibana_version: { - type: 'keyword', - _meta: { description: 'The version of Kibana' }, - }, - protocol: { - type: 'keyword', - _meta: { - description: 'Value from window.location.protocol', - }, - }, - }, - }); - } } diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 5f811723845c1..8958591032470 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -24,6 +24,7 @@ import { import { NodeService, nodeConfig } from '@kbn/core-node-server-internal'; import { AnalyticsService } from '@kbn/core-analytics-server-internal'; import type { AnalyticsServiceSetup } from '@kbn/core-analytics-server'; +import { reportMetricEvent } from '@kbn/ebt-tools'; import { EnvironmentService, pidConfig } from '@kbn/core-environment-server-internal'; import { ExecutionContextService, @@ -399,7 +400,12 @@ export class Server { startTransaction?.end(); this.uptimePerStep.start = { start: startStartUptime, end: process.uptime() }; - analyticsStart.reportEvent(KIBANA_STARTED_EVENT, { uptime_per_step: this.uptimePerStep }); + + reportMetricEvent({ + event_name: KIBANA_STARTED_EVENT, + duration: this.uptimePerStep, + uptime_per_step: this.uptimePerStep, + }); return this.coreStart; } diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx index d204ba3c2ab95..9ea6552f30bf4 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx @@ -12,6 +12,7 @@ import { I18nProvider } from '@kbn/i18n-react'; import uuid from 'uuid'; import { CoreStart, IUiSettingsClient, KibanaExecutionContext } from '@kbn/core/public'; import { Start as InspectorStartContract } from '@kbn/inspector-plugin/public'; +import { reportMetricEvent } from '@kbn/ebt-tools'; import { ControlGroupContainer } from '@kbn/controls-plugin/public'; import { Filter, TimeRange } from '@kbn/es-query'; @@ -164,7 +165,8 @@ export class DashboardContainer extends Container({ - eventType: DASHBOARD_LOADED_EVENT, - schema: { - ...METRIC_EVENT_SCHEMA, - status: { - type: 'keyword', - _meta: { description: 'Dashboard load status' }, - }, - }, - }); - } - public setup( core: CoreSetup, { @@ -303,8 +287,6 @@ export class DashboardPlugin }, }; - this.registerEvents(core.analytics); - core.application.register(app); urlForwarding.forwardApp( DashboardConstants.DASHBOARDS_ID, From 5214952406f723a4e3f0751d3b336f558d6c6572 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 19 Jul 2022 20:47:01 +0300 Subject: [PATCH 23/45] reporting wrappers --- .../src/metric_events/helpers.ts | 2 +- .../kbn-ebt-tools/src/metric_events/index.ts | 2 +- .../kbn-ebt-tools/src/metric_events/schema.ts | 2 +- src/core/public/core_system.ts | 2 +- src/core/server/server.ts | 108 +++--------------- .../embeddable/dashboard_container.tsx | 2 +- .../from_the_server/kibana_started.ts | 3 +- 7 files changed, 22 insertions(+), 99 deletions(-) diff --git a/packages/kbn-ebt-tools/src/metric_events/helpers.ts b/packages/kbn-ebt-tools/src/metric_events/helpers.ts index af2b1f66127a3..ba30d10633261 100644 --- a/packages/kbn-ebt-tools/src/metric_events/helpers.ts +++ b/packages/kbn-ebt-tools/src/metric_events/helpers.ts @@ -9,7 +9,7 @@ import type { AnalyticsClient } from '@kbn/analytics-client'; import { MetricEvent, METRIC_EVENT_SCHEMA } from './schema'; -const METRIC_EVENT_TYPE = 'metric-event'; +const METRIC_EVENT_TYPE = 'metric'; export function registerMetricEvent(analytics: AnalyticsClient) { analytics.registerEventType({ diff --git a/packages/kbn-ebt-tools/src/metric_events/index.ts b/packages/kbn-ebt-tools/src/metric_events/index.ts index 82a7dee173c7f..5a23ca6627c6d 100644 --- a/packages/kbn-ebt-tools/src/metric_events/index.ts +++ b/packages/kbn-ebt-tools/src/metric_events/index.ts @@ -6,4 +6,4 @@ * Side Public License, v 1. */ export type { MetricEvent } from './schema'; -export type { registerMetricEvent, reportMetricEvent } from './helpers'; +export { registerMetricEvent, reportMetricEvent } from './helpers'; diff --git a/packages/kbn-ebt-tools/src/metric_events/schema.ts b/packages/kbn-ebt-tools/src/metric_events/schema.ts index 01c49b1fc95c9..079a84f9a42a7 100644 --- a/packages/kbn-ebt-tools/src/metric_events/schema.ts +++ b/packages/kbn-ebt-tools/src/metric_events/schema.ts @@ -36,7 +36,7 @@ export const METRIC_EVENT_SCHEMA: Record = { _meta: { description: 'Type of the event' }, }, meta: { - type: 'passthrough', + type: 'pass_through', _meta: { description: 'Meta data that is searchable but not aggregatable', optional: true }, }, duration: { diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index f6a73e157e76a..e98bbdcb7d657 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -163,7 +163,7 @@ export class CoreSystem { }); const timing = this.getLoadMarksInfo(); - reportMetricEvent({ + reportMetricEvent(analytics, { event_name: KIBANA_LOADED_EVENT, meta: { kibana_version: this.coreContext.env.packageInfo.version, diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 8958591032470..699ad46ab7af8 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -23,8 +23,7 @@ import { } from '@kbn/core-config-server-internal'; import { NodeService, nodeConfig } from '@kbn/core-node-server-internal'; import { AnalyticsService } from '@kbn/core-analytics-server-internal'; -import type { AnalyticsServiceSetup } from '@kbn/core-analytics-server'; -import { reportMetricEvent } from '@kbn/ebt-tools'; +import { registerMetricEvent, reportMetricEvent } from '@kbn/ebt-tools'; import { EnvironmentService, pidConfig } from '@kbn/core-environment-server-internal'; import { ExecutionContextService, @@ -236,7 +235,7 @@ export class Server { const analyticsSetup = this.analytics.setup(); - this.registerKibanaStartedEventType(analyticsSetup); + registerMetricEvent(analyticsSetup); const environmentSetup = this.environment.setup(); @@ -401,9 +400,20 @@ export class Server { this.uptimePerStep.start = { start: startStartUptime, end: process.uptime() }; - reportMetricEvent({ + const ups = this.uptimePerStep; + + reportMetricEvent(this.coreStart.analytics, { event_name: KIBANA_STARTED_EVENT, - duration: this.uptimePerStep, + duration: ups.start!.end - ups.constructor!.start, + key1: 'constructor-time', + value1: ups.constructor!.end - ups.constructor!.start, + key2: 'preboot-time', + value2: ups.preboot!.end - ups.preboot!.start, + key3: 'setup-time', + value3: ups.setup!.end - ups.setup!.start, + key4: 'start-time', + value4: ups.start!.end - ups.start!.start, + // backwards compatibility uptime_per_step: this.uptimePerStep, }); @@ -466,92 +476,4 @@ export class Server { this.configService.setSchema(descriptor.path, descriptor.schema); } } - - private registerKibanaStartedEventType(analyticsSetup: AnalyticsServiceSetup) { - analyticsSetup.registerEventType<{ uptime_per_step: UptimeSteps }>({ - eventType: KIBANA_STARTED_EVENT, - schema: { - uptime_per_step: { - properties: { - constructor: { - properties: { - start: { - type: 'float', - _meta: { - description: - 'Number of seconds the Node.js process has been running until the constructor was called', - }, - }, - end: { - type: 'float', - _meta: { - description: - 'Number of seconds the Node.js process has been running until the constructor finished', - }, - }, - }, - }, - preboot: { - properties: { - start: { - type: 'float', - _meta: { - description: - 'Number of seconds the Node.js process has been running until `preboot` was called', - }, - }, - end: { - type: 'float', - _meta: { - description: - 'Number of seconds the Node.js process has been running until `preboot` finished', - }, - }, - }, - }, - setup: { - properties: { - start: { - type: 'float', - _meta: { - description: - 'Number of seconds the Node.js process has been running until `setup` was called', - }, - }, - end: { - type: 'float', - _meta: { - description: - 'Number of seconds the Node.js process has been running until `setup` finished', - }, - }, - }, - }, - start: { - properties: { - start: { - type: 'float', - _meta: { - description: - 'Number of seconds the Node.js process has been running until `start` was called', - }, - }, - end: { - type: 'float', - _meta: { - description: - 'Number of seconds the Node.js process has been running until `start` finished', - }, - }, - }, - }, - }, - _meta: { - description: - 'Number of seconds the Node.js process has been running until each phase of the server execution is called and finished.', - }, - }, - }, - }); - } } diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx index 9ea6552f30bf4..8108fc3def244 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx @@ -165,7 +165,7 @@ export class DashboardContainer extends Container { it('should emit the "kibana_started" event', async () => { const [event] = await ebtServerHelper.getEvents(1, { eventTypes: ['kibana_started'] }); - expect(event.event_type).to.eql('kibana_started'); + expect(event.event_type).to.eql('metric'); + expect(event.properties.event_name).to.eql('kibana_started'); const uptimePerStep = event.properties.uptime_per_step as Record< 'constructor' | 'preboot' | 'setup' | 'start', Record<'start' | 'end', number> From e3ce4f232da5bc37f43b1039986d3552835d3188 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 19 Jul 2022 20:54:48 +0300 Subject: [PATCH 24/45] naming consistency --- packages/kbn-ebt-tools/src/metric_events/schema.ts | 4 ++-- src/core/public/core_system.ts | 2 +- src/core/server/server.ts | 2 +- .../public/application/embeddable/dashboard_container.tsx | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/kbn-ebt-tools/src/metric_events/schema.ts b/packages/kbn-ebt-tools/src/metric_events/schema.ts index 079a84f9a42a7..121317dc2464b 100644 --- a/packages/kbn-ebt-tools/src/metric_events/schema.ts +++ b/packages/kbn-ebt-tools/src/metric_events/schema.ts @@ -7,7 +7,7 @@ */ export interface MetricEvent extends Record { - event_name: string; + eventName: string; meta?: Record; // Standardized fields @@ -31,7 +31,7 @@ export interface MetricEvent extends Record { } export const METRIC_EVENT_SCHEMA: Record = { - event_name: { + eventName: { type: 'keyword', _meta: { description: 'Type of the event' }, }, diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index e98bbdcb7d657..55d9e91716d6c 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -164,7 +164,7 @@ export class CoreSystem { const timing = this.getLoadMarksInfo(); reportMetricEvent(analytics, { - event_name: KIBANA_LOADED_EVENT, + eventName: KIBANA_LOADED_EVENT, meta: { kibana_version: this.coreContext.env.packageInfo.version, protocol: window.location.protocol, diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 699ad46ab7af8..188576dd6d9bb 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -403,7 +403,7 @@ export class Server { const ups = this.uptimePerStep; reportMetricEvent(this.coreStart.analytics, { - event_name: KIBANA_STARTED_EVENT, + eventName: KIBANA_STARTED_EVENT, duration: ups.start!.end - ups.constructor!.start, key1: 'constructor-time', value1: ups.constructor!.end - ups.constructor!.start, diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx index 8108fc3def244..57325222dc8bf 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx @@ -166,7 +166,7 @@ export class DashboardContainer extends Container Date: Tue, 19 Jul 2022 20:59:00 +0300 Subject: [PATCH 25/45] meta --- src/core/server/server.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 188576dd6d9bb..1f6cb6a5272cf 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -414,7 +414,9 @@ export class Server { key4: 'start-time', value4: ups.start!.end - ups.start!.start, // backwards compatibility - uptime_per_step: this.uptimePerStep, + meta: { + uptime_per_step: this.uptimePerStep, + }, }); return this.coreStart; From fa20280fbb5ab6bf981fe417ccfdf8f550a987e6 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 19 Jul 2022 21:09:07 +0300 Subject: [PATCH 26/45] AnalyticsServiceSetup --- src/core/public/core_system.ts | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 55d9e91716d6c..75a43832b5d38 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -16,7 +16,7 @@ import { } from '@kbn/core-injected-metadata-browser-internal'; import { DocLinksService } from '@kbn/core-doc-links-browser-internal'; import { ThemeService } from '@kbn/core-theme-browser-internal'; -import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; +import type { AnalyticsServiceSetup, AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import { AnalyticsService } from '@kbn/core-analytics-browser-internal'; import { I18nService } from '@kbn/core-i18n-browser-internal'; import { ExecutionContextService } from '@kbn/core-execution-context-browser-internal'; @@ -203,6 +203,7 @@ export class CoreSystem { const analytics = this.analytics.setup({ injectedMetadata }); + this.registerLoadedKibanaEventType(analytics); registerMetricEvent(analytics); const executionContext = this.executionContext.setup({ analytics }); @@ -374,4 +375,25 @@ export class CoreSystem { this.analytics.stop(); this.rootDomElement.textContent = ''; } + + /** + * @deprecated + */ + private registerLoadedKibanaEventType(analytics: AnalyticsServiceSetup) { + analytics.registerEventType({ + eventType: 'Loaded Kibana', + schema: { + kibana_version: { + type: 'keyword', + _meta: { description: 'The version of Kibana' }, + }, + protocol: { + type: 'keyword', + _meta: { + description: 'Value from window.location.protocol', + }, + }, + }, + }); + } } From 25c9659861a567415152d19f3e8bd7fa0810023f Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 19 Jul 2022 21:17:11 +0300 Subject: [PATCH 27/45] func --- .../from_the_browser/loaded_kibana.ts | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts index 34ad45c92008e..f3f7f980115aa 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts @@ -7,10 +7,11 @@ */ import { Event } from '@kbn/analytics-client'; -import { KIBANA_LOADED_EVENT } from '@kbn/core/utils'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../services'; +const KIBANA_LOADED_EVENT = 'kibana_loaded'; + export default function ({ getService, getPageObjects }: FtrProviderContext) { const ebtUIHelper = getService('kibana_ebt_ui'); const { common } = getPageObjects(['common']); @@ -32,17 +33,21 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // Legacy event expect(legacyEvent.event_type).to.eql('Loaded Kibana'); - expect(event.properties).to.have.property('kibana_version'); - expect(event.properties.kibana_version).to.be.a('string'); - expect(event.properties).to.have.property('protocol'); - expect(event.properties.protocol).to.be.a('string'); + expect(legacyEvent.properties).to.have.property('kibana_version'); + expect(legacyEvent.properties.kibana_version).to.be.a('string'); + expect(legacyEvent.properties).to.have.property('protocol'); + expect(legacyEvent.properties.protocol).to.be.a('string'); // New event - expect(event.event_type).to.eql(KIBANA_LOADED_EVENT); - expect(event.properties).to.have.property('kibana_version'); - expect(event.properties.kibana_version).to.be.a('string'); - expect(event.properties).to.have.property('protocol'); - expect(event.properties.protocol).to.be.a('string'); + expect(event.event_type).to.eql('metric'); + expect(event.properties.eventName).to.eql(KIBANA_LOADED_EVENT); + + // meta + expect(event.properties).to.have.property('meta'); + + const meta = event.properties.meta as Record; + expect(meta.kibana_version).to.be.a('string'); + expect(meta.protocol).to.be.a('string'); // Kibana Loaded timings expect(event.properties).to.have.property('duration'); From bde7a42c5ba5389d78a5f0d292cbc4f22061ff8c Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Tue, 19 Jul 2022 20:02:00 +0100 Subject: [PATCH 28/45] fix(NA): types typo for @kbn/ebt-tools --- package.json | 2 +- yarn.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 28e3a082d9a8e..aa0c9cf68622f 100644 --- a/package.json +++ b/package.json @@ -819,7 +819,7 @@ "@types/kbn__dev-utils": "link:bazel-bin/packages/kbn-dev-utils/npm_module_types", "@types/kbn__doc-links": "link:bazel-bin/packages/kbn-doc-links/npm_module_types", "@types/kbn__docs-utils": "link:bazel-bin/packages/kbn-docs-utils/npm_module_types", - "@types/kbn__ebt-tools": "link:bazel-bin/packages/kbn-kbn__ebt-tools/npm_module_types", + "@types/kbn__ebt-tools": "link:bazel-bin/packages/kbn-ebt-tools/npm_module_types", "@types/kbn__es-archiver": "link:bazel-bin/packages/kbn-es-archiver/npm_module_types", "@types/kbn__es-errors": "link:bazel-bin/packages/kbn-es-errors/npm_module_types", "@types/kbn__es-query": "link:bazel-bin/packages/kbn-es-query/npm_module_types", diff --git a/yarn.lock b/yarn.lock index 2bf57bc45cb9a..92b8154ca5f8a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7138,7 +7138,7 @@ version "0.0.0" uid "" -"@types/kbn__ebt-tools@link:bazel-bin/packages/kbn-kbn__ebt-tools/npm_module_types": +"@types/kbn__ebt-tools@link:bazel-bin/packages/kbn-ebt-tools/npm_module_types": version "0.0.0" uid "" From a5d57d3818a33a3118a5be9e5c63b8bc410d2872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Wed, 20 Jul 2022 14:31:39 +0200 Subject: [PATCH 29/45] Fix tests, add docs, apply nits, fix types --- .../src/analytics_client/analytics_client.ts | 16 +- .../client/src/analytics_client/types.ts | 2 +- packages/analytics/client/src/events/types.ts | 4 +- .../shippers/fullstory/src/format_payload.ts | 2 +- .../BUILD.bazel | 2 + .../src/analytics_service.test.ts | 179 +++++++++++++++-- .../src/analytics_service.ts | 3 + .../BUILD.bazel | 2 + .../src/analytics_service.test.mocks.ts | 25 +++ .../src/analytics_service.test.ts | 187 ++++++++++++++++++ .../src/analytics_service.ts | 3 + packages/kbn-ebt-tools/BUILD.bazel | 8 +- .../src/metric_events/helpers.test.ts | 97 +++++++++ .../src/metric_events/helpers.ts | 21 +- .../kbn-ebt-tools/src/metric_events/index.ts | 2 +- .../kbn-ebt-tools/src/metric_events/schema.ts | 99 ++++++++-- src/core/public/core_system.test.mocks.ts | 5 + src/core/public/core_system.test.ts | 40 ++-- src/core/public/core_system.ts | 9 +- .../public/fetch_optional_memory_info.test.ts | 35 ++++ src/core/public/fetch_optional_memory_info.ts | 42 ++++ src/core/server/server.ts | 146 ++++++++++++-- .../embeddable/dashboard_container.tsx | 20 +- .../common/fetch_events.ts | 25 ++- .../analytics_ftr_helpers/common/types.ts | 21 +- .../public/plugin.test.ts | 27 +++ .../analytics_ftr_helpers/server/plugin.ts | 15 ++ .../core_context_providers.ts | 5 +- .../from_the_browser/loaded_dashboard.ts | 26 ++- .../from_the_browser/loaded_kibana.ts | 43 ++-- .../from_the_server/core_context_providers.ts | 2 +- .../core_overall_status_changed.ts | 4 +- .../from_the_server/kibana_started.ts | 25 ++- 33 files changed, 1004 insertions(+), 138 deletions(-) create mode 100644 packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.mocks.ts create mode 100644 packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts create mode 100644 packages/kbn-ebt-tools/src/metric_events/helpers.test.ts create mode 100644 src/core/public/fetch_optional_memory_info.test.ts create mode 100644 src/core/public/fetch_optional_memory_info.ts diff --git a/packages/analytics/client/src/analytics_client/analytics_client.ts b/packages/analytics/client/src/analytics_client/analytics_client.ts index e6815b4415254..57741f098c6ac 100644 --- a/packages/analytics/client/src/analytics_client/analytics_client.ts +++ b/packages/analytics/client/src/analytics_client/analytics_client.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import type { Type } from 'io-ts'; +import type { Mixed } from 'io-ts'; import type { Observable } from 'rxjs'; import { BehaviorSubject, Subject, combineLatest, from, merge } from 'rxjs'; import { @@ -43,7 +43,7 @@ import { ContextService } from './context_service'; import { schemaToIoTs, validateSchema } from '../schema/validation'; interface EventDebugLogMeta extends LogMeta { - ebt_event: Event; + ebt_event: Event; } export class AnalyticsClient implements IAnalyticsClient { @@ -65,7 +65,7 @@ export class AnalyticsClient implements IAnalyticsClient { private readonly shipperRegistered$ = new Subject(); private readonly eventTypeRegistry = new Map< EventType, - EventTypeOpts & { validator?: Type> } + EventTypeOpts & { validator?: Mixed } >(); private readonly contextService: ContextService; private readonly context$ = new BehaviorSubject>({}); @@ -88,7 +88,7 @@ export class AnalyticsClient implements IAnalyticsClient { this.reportEnqueuedEventsWhenClientIsReady(); } - public reportEvent = >( + public reportEvent = ( eventType: EventType, eventData: EventTypeData ) => { @@ -119,14 +119,18 @@ export class AnalyticsClient implements IAnalyticsClient { // If the validator is registered (dev-mode only), perform the validation. if (eventTypeOpts.validator) { - validateSchema(`Event Type '${eventType}'`, eventTypeOpts.validator, eventData); + validateSchema( + `Event Type '${eventType}'`, + eventTypeOpts.validator, + eventData + ); } const event: Event = { timestamp, event_type: eventType, context: this.context$.value, - properties: eventData, + properties: eventData as unknown as Record, }; // debug-logging before checking the opt-in status to help during development diff --git a/packages/analytics/client/src/analytics_client/types.ts b/packages/analytics/client/src/analytics_client/types.ts index 88b60dc100e89..2af29d88b5ceb 100644 --- a/packages/analytics/client/src/analytics_client/types.ts +++ b/packages/analytics/client/src/analytics_client/types.ts @@ -170,7 +170,7 @@ export interface IAnalyticsClient { * @param eventType The event type registered via the `registerEventType` API. * @param eventData The properties matching the schema declared in the `registerEventType` API. */ - reportEvent: >( + reportEvent: ( eventType: EventType, eventData: EventTypeData ) => void; diff --git a/packages/analytics/client/src/events/types.ts b/packages/analytics/client/src/events/types.ts index 0c97bee3fdbb7..78b2f792e9e2b 100644 --- a/packages/analytics/client/src/events/types.ts +++ b/packages/analytics/client/src/events/types.ts @@ -108,7 +108,7 @@ export interface TelemetryCounter { /** * Definition of the full event structure */ -export interface Event { +export interface Event> { /** * The time the event was generated in ISO format. */ @@ -120,7 +120,7 @@ export interface Event { /** * The specific properties of the event type. */ - properties: Record; + properties: Properties; /** * The {@link EventContext} enriched during the processing pipeline. */ diff --git a/packages/analytics/shippers/fullstory/src/format_payload.ts b/packages/analytics/shippers/fullstory/src/format_payload.ts index c55ed2409da50..03873617af8fc 100644 --- a/packages/analytics/shippers/fullstory/src/format_payload.ts +++ b/packages/analytics/shippers/fullstory/src/format_payload.ts @@ -19,7 +19,7 @@ const FULLSTORY_RESERVED_PROPERTIES = [ 'pageName', ]; -export function formatPayload(context: Record): Record { +export function formatPayload(context: object): Record { // format context keys as required for env vars, see docs: https://help.fullstory.com/hc/en-us/articles/360020623234 return Object.fromEntries( Object.entries(context) diff --git a/packages/core/analytics/core-analytics-browser-internal/BUILD.bazel b/packages/core/analytics/core-analytics-browser-internal/BUILD.bazel index 2540ccabd517c..59f18b8f11d4a 100644 --- a/packages/core/analytics/core-analytics-browser-internal/BUILD.bazel +++ b/packages/core/analytics/core-analytics-browser-internal/BUILD.bazel @@ -30,6 +30,7 @@ RUNTIME_DEPS = [ "@npm//rxjs", "@npm//uuid", "//packages/analytics/client", + "//packages/kbn-ebt-tools", "//packages/core/base/core-base-browser-mocks", "//packages/core/injected-metadata/core-injected-metadata-browser-mocks", ] @@ -41,6 +42,7 @@ TYPES_DEPS = [ "@npm//rxjs", "//packages/kbn-logging:npm_module_types", "//packages/analytics/client:npm_module_types", + "//packages/kbn-ebt-tools:npm_module_types", "//packages/core/base/core-base-browser-internal:npm_module_types", "//packages/core/injected-metadata/core-injected-metadata-browser-internal:npm_module_types", "//packages/core/analytics/core-analytics-browser:npm_module_types", diff --git a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts index 8ae572ae34528..cdd5a27ee9500 100644 --- a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts +++ b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts @@ -23,15 +23,15 @@ describe('AnalyticsService', () => { await expect( firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[0][0].context$) ).resolves.toMatchInlineSnapshot(` - Object { - "branch": "branch", - "buildNum": 100, - "buildSha": "buildSha", - "isDev": true, - "isDistributable": false, - "version": "version", - } - `); + Object { + "branch": "branch", + "buildNum": 100, + "buildSha": "buildSha", + "isDev": true, + "isDistributable": false, + "version": "version", + } + `); await expect( firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[1][0].context$) ).resolves.toEqual({ session_id: expect.any(String) }); @@ -44,6 +44,155 @@ describe('AnalyticsService', () => { }); }); + test('should register the `metrics` and `clicks` event types on creation', () => { + expect(analyticsClientMock.registerEventType).toHaveBeenCalledTimes(2); + expect(analyticsClientMock.registerEventType.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "eventType": "metric", + "schema": Object { + "duration": Object { + "_meta": Object { + "description": "The main event duration in ms", + "optional": true, + }, + "type": "integer", + }, + "eventName": Object { + "_meta": Object { + "description": "Type of the event", + }, + "type": "keyword", + }, + "jsHeapSizeLimit": Object { + "_meta": Object { + "description": "performance.memory.jsHeapSizeLimit", + "optional": true, + }, + "type": "long", + }, + "key1": Object { + "_meta": Object { + "description": "Performance metric label 1", + "optional": true, + }, + "type": "keyword", + }, + "key2": Object { + "_meta": Object { + "description": "Performance metric label 2", + "optional": true, + }, + "type": "keyword", + }, + "key3": Object { + "_meta": Object { + "description": "Performance metric label 3", + "optional": true, + }, + "type": "keyword", + }, + "key4": Object { + "_meta": Object { + "description": "Performance metric label 4", + "optional": true, + }, + "type": "keyword", + }, + "key5": Object { + "_meta": Object { + "description": "Performance metric label 5", + "optional": true, + }, + "type": "keyword", + }, + "meta": Object { + "_meta": Object { + "description": "Meta data that is searchable but not aggregatable", + "optional": true, + }, + "type": "pass_through", + }, + "status": Object { + "_meta": Object { + "description": "A status", + "optional": true, + }, + "type": "keyword", + }, + "totalJSHeapSize": Object { + "_meta": Object { + "description": "performance.memory.totalJSHeapSize", + "optional": true, + }, + "type": "long", + }, + "usedJSHeapSize": Object { + "_meta": Object { + "description": "performance.memory.usedJSHeapSize", + "optional": true, + }, + "type": "long", + }, + "value1": Object { + "_meta": Object { + "description": "Performance metric value 1", + "optional": true, + }, + "type": "long", + }, + "value2": Object { + "_meta": Object { + "description": "Performance metric value 2", + "optional": true, + }, + "type": "long", + }, + "value3": Object { + "_meta": Object { + "description": "Performance metric value 3", + "optional": true, + }, + "type": "long", + }, + "value4": Object { + "_meta": Object { + "description": "Performance metric value 4", + "optional": true, + }, + "type": "long", + }, + "value5": Object { + "_meta": Object { + "description": "Performance metric value 5", + "optional": true, + }, + "type": "long", + }, + }, + }, + ] + `); + expect(analyticsClientMock.registerEventType.mock.calls[1]).toMatchInlineSnapshot(` + Array [ + Object { + "eventType": "click", + "schema": Object { + "target": Object { + "items": Object { + "_meta": Object { + "description": "The attributes of the clicked element and all its parents in the form \`{attr.name}={attr.value}\`. It allows finding the clicked elements by looking up its attributes like \\"data-test-subj=my-button\\".", + }, + "type": "keyword", + }, + "type": "array", + }, + }, + }, + ] + `); + }); + test('setup should expose all the register APIs, reportEvent and opt-in', () => { const injectedMetadata = injectedMetadataServiceMock.createSetupContract(); expect(analyticsService.setup({ injectedMetadata })).toStrictEqual({ @@ -76,12 +225,12 @@ describe('AnalyticsService', () => { await expect( firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[3][0].context$) ).resolves.toMatchInlineSnapshot(` - Object { - "cluster_name": "cluster_name", - "cluster_uuid": "cluster_uuid", - "cluster_version": "version", - } - `); + Object { + "cluster_name": "cluster_name", + "cluster_uuid": "cluster_uuid", + "cluster_version": "version", + } + `); }); test('setup should expose only the APIs report and opt-in', () => { diff --git a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts index 580fbac92aa5d..84eb75df04098 100644 --- a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts +++ b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts @@ -9,6 +9,7 @@ import { of } from 'rxjs'; import type { AnalyticsClient } from '@kbn/analytics-client'; import { createAnalytics } from '@kbn/analytics-client'; +import { registerMetricEventType } from '@kbn/ebt-tools'; import type { CoreContext } from '@kbn/core-base-browser-internal'; import type { InternalInjectedMetadataSetup } from '@kbn/core-injected-metadata-browser-internal'; import type { AnalyticsServiceSetup, AnalyticsServiceStart } from '@kbn/core-analytics-browser'; @@ -34,6 +35,8 @@ export class AnalyticsService { }); this.registerBuildInfoAnalyticsContext(core); + // Register special `metrics` type + registerMetricEventType(this.analyticsClient); // We may eventually move the following to the client's package since they are not Kibana-specific // and can benefit other consumers of the client. diff --git a/packages/core/analytics/core-analytics-server-internal/BUILD.bazel b/packages/core/analytics/core-analytics-server-internal/BUILD.bazel index b7ba4ed35a5a3..0ad590f1ee505 100644 --- a/packages/core/analytics/core-analytics-server-internal/BUILD.bazel +++ b/packages/core/analytics/core-analytics-server-internal/BUILD.bazel @@ -28,6 +28,7 @@ NPM_MODULE_EXTRA_FILES = [ RUNTIME_DEPS = [ "@npm//rxjs", "//packages/analytics/client", + "//packages/kbn-ebt-tools", ] TYPES_DEPS = [ @@ -35,6 +36,7 @@ TYPES_DEPS = [ "@npm//@types/jest", "@npm//rxjs", "//packages/analytics/client:npm_module_types", + "//packages/kbn-ebt-tools:npm_module_types", "//packages/core/base/core-base-server-internal:npm_module_types", "//packages/core/analytics/core-analytics-server:npm_module_types", ] diff --git a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.mocks.ts b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.mocks.ts new file mode 100644 index 0000000000000..3d98cf4392926 --- /dev/null +++ b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.mocks.ts @@ -0,0 +1,25 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { AnalyticsClient } from '@kbn/analytics-client'; +import { Subject } from 'rxjs'; + +export const analyticsClientMock: jest.Mocked = { + optIn: jest.fn(), + reportEvent: jest.fn(), + registerEventType: jest.fn(), + registerContextProvider: jest.fn(), + removeContextProvider: jest.fn(), + registerShipper: jest.fn(), + telemetryCounter$: new Subject(), + shutdown: jest.fn(), +}; + +jest.doMock('@kbn/analytics-client', () => ({ + createAnalytics: () => analyticsClientMock, +})); diff --git a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts new file mode 100644 index 0000000000000..74d1b6e4119ee --- /dev/null +++ b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts @@ -0,0 +1,187 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { firstValueFrom, Observable } from 'rxjs'; +import { mockCoreContext } from '@kbn/core-base-server-mocks'; +import { analyticsClientMock } from './analytics_service.test.mocks'; +import { AnalyticsService } from './analytics_service'; + +describe('AnalyticsService', () => { + let analyticsService: AnalyticsService; + beforeEach(() => { + jest.clearAllMocks(); + analyticsService = new AnalyticsService(mockCoreContext.create()); + }); + + test('should register the context provider `build info` on creation', async () => { + expect(analyticsClientMock.registerContextProvider).toHaveBeenCalledTimes(1); + await expect( + firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[0][0].context$) + ).resolves.toMatchInlineSnapshot(` + Object { + "branch": "main", + "buildNum": 9007199254740991, + "buildSha": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "isDev": true, + "isDistributable": false, + "version": "8.4.0", + } + `); + }); + + test('should register the `metrics` event type on creation', () => { + expect(analyticsClientMock.registerEventType).toHaveBeenCalledTimes(1); + expect(analyticsClientMock.registerEventType.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "eventType": "metric", + "schema": Object { + "duration": Object { + "_meta": Object { + "description": "The main event duration in ms", + "optional": true, + }, + "type": "integer", + }, + "eventName": Object { + "_meta": Object { + "description": "Type of the event", + }, + "type": "keyword", + }, + "jsHeapSizeLimit": Object { + "_meta": Object { + "description": "performance.memory.jsHeapSizeLimit", + "optional": true, + }, + "type": "long", + }, + "key1": Object { + "_meta": Object { + "description": "Performance metric label 1", + "optional": true, + }, + "type": "keyword", + }, + "key2": Object { + "_meta": Object { + "description": "Performance metric label 2", + "optional": true, + }, + "type": "keyword", + }, + "key3": Object { + "_meta": Object { + "description": "Performance metric label 3", + "optional": true, + }, + "type": "keyword", + }, + "key4": Object { + "_meta": Object { + "description": "Performance metric label 4", + "optional": true, + }, + "type": "keyword", + }, + "key5": Object { + "_meta": Object { + "description": "Performance metric label 5", + "optional": true, + }, + "type": "keyword", + }, + "meta": Object { + "_meta": Object { + "description": "Meta data that is searchable but not aggregatable", + "optional": true, + }, + "type": "pass_through", + }, + "status": Object { + "_meta": Object { + "description": "A status", + "optional": true, + }, + "type": "keyword", + }, + "totalJSHeapSize": Object { + "_meta": Object { + "description": "performance.memory.totalJSHeapSize", + "optional": true, + }, + "type": "long", + }, + "usedJSHeapSize": Object { + "_meta": Object { + "description": "performance.memory.usedJSHeapSize", + "optional": true, + }, + "type": "long", + }, + "value1": Object { + "_meta": Object { + "description": "Performance metric value 1", + "optional": true, + }, + "type": "long", + }, + "value2": Object { + "_meta": Object { + "description": "Performance metric value 2", + "optional": true, + }, + "type": "long", + }, + "value3": Object { + "_meta": Object { + "description": "Performance metric value 3", + "optional": true, + }, + "type": "long", + }, + "value4": Object { + "_meta": Object { + "description": "Performance metric value 4", + "optional": true, + }, + "type": "long", + }, + "value5": Object { + "_meta": Object { + "description": "Performance metric value 5", + "optional": true, + }, + "type": "long", + }, + }, + }, + ] + `); + }); + + test('setup should expose all the register APIs, reportEvent and opt-in', () => { + expect(analyticsService.setup()).toStrictEqual({ + registerShipper: expect.any(Function), + registerContextProvider: expect.any(Function), + removeContextProvider: expect.any(Function), + registerEventType: expect.any(Function), + reportEvent: expect.any(Function), + optIn: expect.any(Function), + telemetryCounter$: expect.any(Observable), + }); + }); + + test('setup should expose only the APIs report and opt-in', () => { + expect(analyticsService.start()).toStrictEqual({ + reportEvent: expect.any(Function), + optIn: expect.any(Function), + telemetryCounter$: expect.any(Observable), + }); + }); +}); diff --git a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts index 0fa96ebe0ae51..7aaebe2235955 100644 --- a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts +++ b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts @@ -9,6 +9,7 @@ import { of } from 'rxjs'; import type { AnalyticsClient } from '@kbn/analytics-client'; import { createAnalytics } from '@kbn/analytics-client'; +import { registerMetricEventType } from '@kbn/ebt-tools'; import type { CoreContext } from '@kbn/core-base-server-internal'; import type { AnalyticsServiceSetup, @@ -29,6 +30,8 @@ export class AnalyticsService { }); this.registerBuildInfoAnalyticsContext(core); + // Register special `metrics` type + registerMetricEventType(this.analyticsClient); } public preboot(): AnalyticsServicePreboot { diff --git a/packages/kbn-ebt-tools/BUILD.bazel b/packages/kbn-ebt-tools/BUILD.bazel index 3b4e37ca356ff..e4c4209361906 100644 --- a/packages/kbn-ebt-tools/BUILD.bazel +++ b/packages/kbn-ebt-tools/BUILD.bazel @@ -24,16 +24,10 @@ NPM_MODULE_EXTRA_FILES = [ "README.md" ] -RUNTIME_DEPS = [ - "//packages/analytics/client", - "@npm//load-json-file", - "@npm//tslib", -] +RUNTIME_DEPS = [] TYPES_DEPS = [ "//packages/analytics/client:npm_module_types", - "@npm//load-json-file", - "@npm//tslib", "@npm//@types/jest", "@npm//@types/node", ] diff --git a/packages/kbn-ebt-tools/src/metric_events/helpers.test.ts b/packages/kbn-ebt-tools/src/metric_events/helpers.test.ts new file mode 100644 index 0000000000000..376e5d926c252 --- /dev/null +++ b/packages/kbn-ebt-tools/src/metric_events/helpers.test.ts @@ -0,0 +1,97 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { createAnalytics, type AnalyticsClient } from '@kbn/analytics-client'; +import { loggerMock } from '@kbn/logging-mocks'; +import { registerMetricEventType, reportMetricEvent } from './helpers'; +import { METRIC_EVENT_SCHEMA } from './schema'; + +describe('metric event helpers', () => { + let analyticsClient: AnalyticsClient; + + describe('registerMetricEventType', () => { + beforeEach(() => { + analyticsClient = createAnalytics({ + isDev: true, // Explicitly setting `true` to ensure we have event validation to make sure the events sent pass our validation. + sendTo: 'staging', + logger: loggerMock.create(), + }); + }); + + test('registers the `metrics` eventType to the analytics client', () => { + const registerEventTypeSpy = jest.spyOn(analyticsClient, 'registerEventType'); + + expect(() => registerMetricEventType(analyticsClient)).not.toThrow(); + + expect(registerEventTypeSpy).toHaveBeenCalledWith({ + eventType: 'metric', + schema: METRIC_EVENT_SCHEMA, + }); + }); + }); + + describe('reportMetricEvent', () => { + beforeEach(() => { + analyticsClient = createAnalytics({ + isDev: true, // Explicitly setting `true` to ensure we have event validation to make sure the events sent pass our validation. + sendTo: 'staging', + logger: loggerMock.create(), + }); + registerMetricEventType(analyticsClient); + }); + + test('reports the minimum allowed event', () => { + reportMetricEvent(analyticsClient, { eventName: 'test-event' }); + }); + + test('reports all the allowed fields in the event', () => { + reportMetricEvent(analyticsClient, { + eventName: 'test-event', + meta: { my: { custom: { fields: 'here' } }, another_field: true }, + status: 'something', + duration: 10, + key1: 'something', + value1: 10, + key2: 'something', + value2: 10, + key3: 'something', + value3: 10, + key4: 'something', + value4: 10, + key5: 'something', + value5: 10, + }); + }); + + test('should fail if eventName is missing', () => { + expect(() => + reportMetricEvent( + analyticsClient, + // @ts-expect-error + {} + ) + ).toThrowErrorMatchingInlineSnapshot(` + "Failed to validate payload coming from \\"Event Type 'metric'\\": + - [eventName]: {\\"expected\\":\\"string\\",\\"actual\\":\\"undefined\\",\\"value\\":\\"undefined\\"}" + `); + }); + + test('should fail if any additional unknown keys are added', () => { + expect(() => + reportMetricEvent(analyticsClient, { + eventName: 'test-event', + // @ts-expect-error + an_unknown_field: 'blah', + }) + ).toThrowErrorMatchingInlineSnapshot(` + "Failed to validate payload coming from \\"Event Type 'metric'\\": + - []: excess key 'an_unknown_field' found" + `); + }); + }); +}); diff --git a/packages/kbn-ebt-tools/src/metric_events/helpers.ts b/packages/kbn-ebt-tools/src/metric_events/helpers.ts index ba30d10633261..d385abb676cd8 100644 --- a/packages/kbn-ebt-tools/src/metric_events/helpers.ts +++ b/packages/kbn-ebt-tools/src/metric_events/helpers.ts @@ -7,17 +7,30 @@ */ import type { AnalyticsClient } from '@kbn/analytics-client'; -import { MetricEvent, METRIC_EVENT_SCHEMA } from './schema'; +import { type MetricEvent, METRIC_EVENT_SCHEMA } from './schema'; const METRIC_EVENT_TYPE = 'metric'; -export function registerMetricEvent(analytics: AnalyticsClient) { - analytics.registerEventType({ +/** + * Register the `metrics` event type + * @param analytics The {@link AnalyticsClient} during the setup phase (it has the method `registerEventType`) + * @private To be called only by core's Analytics Service + */ +export function registerMetricEventType(analytics: Pick) { + analytics.registerEventType({ eventType: METRIC_EVENT_TYPE, schema: METRIC_EVENT_SCHEMA, }); } -export function reportMetricEvent(analytics: AnalyticsClient, eventData: MetricEvent) { +/** + * Report a `metrics` event type. + * @param analytics The {@link AnalyticsClient} to report the events. + * @param eventData The data to send, conforming the structure of a {@link MetricEvent}. + */ +export function reportMetricEvent( + analytics: Pick, + eventData: MetricEvent +) { analytics.reportEvent(METRIC_EVENT_TYPE, eventData); } diff --git a/packages/kbn-ebt-tools/src/metric_events/index.ts b/packages/kbn-ebt-tools/src/metric_events/index.ts index 5a23ca6627c6d..1b9e5c762d7f4 100644 --- a/packages/kbn-ebt-tools/src/metric_events/index.ts +++ b/packages/kbn-ebt-tools/src/metric_events/index.ts @@ -6,4 +6,4 @@ * Side Public License, v 1. */ export type { MetricEvent } from './schema'; -export { registerMetricEvent, reportMetricEvent } from './helpers'; +export { registerMetricEventType, reportMetricEvent } from './helpers'; diff --git a/packages/kbn-ebt-tools/src/metric_events/schema.ts b/packages/kbn-ebt-tools/src/metric_events/schema.ts index 121317dc2464b..3d572963b07db 100644 --- a/packages/kbn-ebt-tools/src/metric_events/schema.ts +++ b/packages/kbn-ebt-tools/src/metric_events/schema.ts @@ -6,31 +6,100 @@ * Side Public License, v 1. */ -export interface MetricEvent extends Record { +import type { RootSchema } from '@kbn/analytics-client'; + +/** + * Structure of the `metric` event + */ +export interface MetricEvent { + /** + * The name of the action that is tracked in the metrics. + */ eventName: string; - meta?: Record; + /** + * Searchable but not aggregateable metadata relevant to the tracked action. + */ + meta?: Record; - // Standardized fields + /** + * @group Standardized fields + * The time (in milliseconds) it took to run the entire action. + */ duration?: number; + /** + * @group Standardized fields + * A status relevant to the action (i.e.: `failed`, `succeeded`). + */ status?: string; + /** + * @group Standardized fields + * performance.memory.jsHeapSizeLimit + */ jsHeapSizeLimit?: number; + /** + * @group Standardized fields + * performance.memory.totalJSHeapSize + */ totalJSHeapSize?: number; + /** + * @group Standardized fields + * performance.memory.usedJSHeapSize + */ usedJSHeapSize?: number; - // Free fields - will be mapped in the index; + /** + * @group Free fields for custom metrics (searchable and aggregateable) + * Description label for the metric 1 + */ key1?: string; + /** + * @group Free fields for custom metrics (searchable and aggregateable) + * Value for the metric 1 + */ value1?: number; + /** + * @group Free fields for custom metrics (searchable and aggregateable) + * Description label for the metric 2 + */ key2?: string; + /** + * @group Free fields for custom metrics (searchable and aggregateable) + * Value for the metric 2 + */ value2?: number; + /** + * @group Free fields for custom metrics (searchable and aggregateable) + * Description label for the metric 3 + */ key3?: string; + /** + * @group Free fields for custom metrics (searchable and aggregateable) + * Value for the metric 3 + */ value3?: number; + /** + * @group Free fields for custom metrics (searchable and aggregateable) + * Description label for the metric 4 + */ key4?: string; + /** + * @group Free fields for custom metrics (searchable and aggregateable) + * Value for the metric 4 + */ value4?: number; + /** + * @group Free fields for custom metrics (searchable and aggregateable) + * Description label for the metric 5 + */ key5?: string; + /** + * @group Free fields for custom metrics (searchable and aggregateable) + * Value for the metric 5 + */ value5?: number; } -export const METRIC_EVENT_SCHEMA: Record = { +export const METRIC_EVENT_SCHEMA: RootSchema = { eventName: { type: 'keyword', _meta: { description: 'Type of the event' }, @@ -61,42 +130,42 @@ export const METRIC_EVENT_SCHEMA: Record = { }, key1: { type: 'keyword', - _meta: { description: 'Performance metric label', optional: true }, + _meta: { description: 'Performance metric label 1', optional: true }, }, value1: { type: 'long', - _meta: { description: 'Performance metric value', optional: true }, + _meta: { description: 'Performance metric value 1', optional: true }, }, key2: { type: 'keyword', - _meta: { description: 'Performance metric label', optional: true }, + _meta: { description: 'Performance metric label 2', optional: true }, }, value2: { type: 'long', - _meta: { description: 'Performance metric value', optional: true }, + _meta: { description: 'Performance metric value 2', optional: true }, }, key3: { type: 'keyword', - _meta: { description: 'Performance metric label', optional: true }, + _meta: { description: 'Performance metric label 3', optional: true }, }, value3: { type: 'long', - _meta: { description: 'Performance metric value', optional: true }, + _meta: { description: 'Performance metric value 3', optional: true }, }, key4: { type: 'keyword', - _meta: { description: 'Performance metric label', optional: true }, + _meta: { description: 'Performance metric label 4', optional: true }, }, value4: { type: 'long', - _meta: { description: 'Performance metric value', optional: true }, + _meta: { description: 'Performance metric value 4', optional: true }, }, key5: { type: 'keyword', - _meta: { description: 'Performance metric label', optional: true }, + _meta: { description: 'Performance metric label 5', optional: true }, }, value5: { type: 'long', - _meta: { description: 'Performance metric value', optional: true }, + _meta: { description: 'Performance metric value 5', optional: true }, }, }; diff --git a/src/core/public/core_system.test.mocks.ts b/src/core/public/core_system.test.mocks.ts index b96d81200e6e0..99f525b1f8aba 100644 --- a/src/core/public/core_system.test.mocks.ts +++ b/src/core/public/core_system.test.mocks.ts @@ -31,6 +31,11 @@ jest.doMock('@kbn/core-analytics-browser-internal', () => ({ AnalyticsService: AnalyticsServiceConstructor, })); +export const fetchOptionalMemoryInfoMock = jest.fn(); +jest.doMock('./fetch_optional_memory_info', () => ({ + fetchOptionalMemoryInfo: fetchOptionalMemoryInfoMock, +})); + export const MockInjectedMetadataService = injectedMetadataServiceMock.create(); export const InjectedMetadataServiceConstructor = jest .fn() diff --git a/src/core/public/core_system.test.ts b/src/core/public/core_system.test.ts index 7e6d1a30c042e..0cafa8ed6bd39 100644 --- a/src/core/public/core_system.test.ts +++ b/src/core/public/core_system.test.ts @@ -37,6 +37,7 @@ import { AnalyticsServiceConstructor, MockAnalyticsService, analyticsServiceStartMock, + fetchOptionalMemoryInfoMock, } from './core_system.test.mocks'; import { CoreSystem } from './core_system'; @@ -274,8 +275,8 @@ describe('#start()', () => { it('reports the deprecated event Loaded Kibana', async () => { await startCore(); - expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledTimes(1); - expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledWith('Loaded Kibana', { + expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledTimes(2); + expect(analyticsServiceStartMock.reportEvent).toHaveBeenNthCalledWith(1, 'Loaded Kibana', { kibana_version: '1.2.3', protocol: 'http:', }); @@ -283,12 +284,15 @@ describe('#start()', () => { expect(window.performance.clearMarks).toHaveBeenCalledTimes(1); }); - it('reports the event kibana-loaded and clears marks', async () => { + it('reports the metric event kibana-loaded and clears marks', async () => { await startCore(); - expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledTimes(1); - expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledWith(KIBANA_LOADED_EVENT, { - kibana_version: '1.2.3', - protocol: 'http:', + expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledTimes(2); + expect(analyticsServiceStartMock.reportEvent).toHaveBeenNthCalledWith(2, 'metric', { + eventName: KIBANA_LOADED_EVENT, + meta: { + kibana_version: '1.2.3', + protocol: 'http:', + }, key1: LOAD_START, key2: LOAD_BOOTSTRAP_START, key3: LOAD_CORE_CREATED, @@ -306,22 +310,34 @@ describe('#start()', () => { }); it('reports the event kibana-loaded (with memory)', async () => { + const performanceMemory = { + usedJSHeapSize: 1, + jsHeapSizeLimit: 3, + totalJSHeapSize: 4, + }; + fetchOptionalMemoryInfoMock.mockReturnValue(performanceMemory); + await startCore(); - expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledTimes(1); - expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledWith(KIBANA_LOADED_EVENT, { - kibana_version: '1.2.3', - duration: 666, + + expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledTimes(2); + expect(analyticsServiceStartMock.reportEvent).toHaveBeenNthCalledWith(2, 'metric', { + eventName: KIBANA_LOADED_EVENT, + meta: { + kibana_version: '1.2.3', + protocol: 'http:', + }, key1: LOAD_START, key2: LOAD_BOOTSTRAP_START, key3: LOAD_CORE_CREATED, key4: LOAD_SETUP_DONE, key5: LOAD_START_DONE, + ...performanceMemory, value1: 111, value2: 222, value3: 333, value4: 444, value5: 555, - protocol: 'http:', + duration: 666, }); }); diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 75a43832b5d38..34ad06766fabc 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -26,7 +26,8 @@ import { HttpService } from '@kbn/core-http-browser-internal'; import { UiSettingsService } from '@kbn/core-ui-settings-browser-internal'; import { DeprecationsService } from '@kbn/core-deprecations-browser-internal'; import { IntegrationsService } from '@kbn/core-integrations-browser-internal'; -import { registerMetricEvent, reportMetricEvent } from '@kbn/ebt-tools'; +import { reportMetricEvent } from '@kbn/ebt-tools'; +import { fetchOptionalMemoryInfo } from './fetch_optional_memory_info'; import { CoreSetup, CoreStart } from '.'; import { ChromeService } from './chrome'; import { NotificationsService } from './notifications'; @@ -155,7 +156,7 @@ export class CoreSystem { private reportKibanaLoadedEvent(analytics: AnalyticsServiceStart) { /** - * @deprecated here for backwards compatibility in Fullstory + * @deprecated here for backwards compatibility in FullStory **/ analytics.reportEvent('Loaded Kibana', { kibana_version: this.coreContext.env.packageInfo.version, @@ -170,8 +171,7 @@ export class CoreSystem { protocol: window.location.protocol, }, duration: timing[LOAD_FIRST_NAV], - // @ts-expect-error 2339 - ...performance.memory, + ...fetchOptionalMemoryInfo(), key1: LOAD_START, value1: timing[LOAD_START], key2: LOAD_BOOTSTRAP_START, @@ -204,7 +204,6 @@ export class CoreSystem { const analytics = this.analytics.setup({ injectedMetadata }); this.registerLoadedKibanaEventType(analytics); - registerMetricEvent(analytics); const executionContext = this.executionContext.setup({ analytics }); const http = this.http.setup({ diff --git a/src/core/public/fetch_optional_memory_info.test.ts b/src/core/public/fetch_optional_memory_info.test.ts new file mode 100644 index 0000000000000..4eca4cf0d11de --- /dev/null +++ b/src/core/public/fetch_optional_memory_info.test.ts @@ -0,0 +1,35 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { fetchOptionalMemoryInfo } from './fetch_optional_memory_info'; + +describe('fetchOptionalMemoryInfo', () => { + test('should return undefined if no memory info is available', () => { + expect(fetchOptionalMemoryInfo()).toBeUndefined(); + }); + + test('should return the memory info when available', () => { + // @ts-expect-error 2339 + window.performance.memory = { + get jsHeapSizeLimit() { + return 3; + }, + get totalJSHeapSize() { + return 2; + }, + get usedJSHeapSize() { + return 1; + }, + }; + expect(fetchOptionalMemoryInfo()).toEqual({ + jsHeapSizeLimit: 3, + totalJSHeapSize: 2, + usedJSHeapSize: 1, + }); + }); +}); diff --git a/src/core/public/fetch_optional_memory_info.ts b/src/core/public/fetch_optional_memory_info.ts new file mode 100644 index 0000000000000..957388d55453d --- /dev/null +++ b/src/core/public/fetch_optional_memory_info.ts @@ -0,0 +1,42 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** + * `Performance.memory` output. + * https://developer.mozilla.org/en-US/docs/Web/API/Performance/memory + */ +export interface BrowserPerformanceMemoryInfo { + /** + * The maximum size of the heap, in bytes, that is available to the context. + */ + jsHeapSizeLimit: number; + /** + * The total allocated heap size, in bytes. + */ + totalJSHeapSize: number; + /** + * The currently active segment of JS heap, in bytes. + */ + usedJSHeapSize: number; +} + +/** + * Get performance information from the browser (non-standard property). + * @remarks Only available in Google Chrome and MS Edge for now. + */ +export function fetchOptionalMemoryInfo(): BrowserPerformanceMemoryInfo | undefined { + // @ts-expect-error 2339 + const memory = window.performance.memory; + if (memory) { + return { + jsHeapSizeLimit: memory.jsHeapSizeLimit, + totalJSHeapSize: memory.totalJSHeapSize, + usedJSHeapSize: memory.usedJSHeapSize, + }; + } +} diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 1f6cb6a5272cf..1549e42f3d79c 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -23,7 +23,8 @@ import { } from '@kbn/core-config-server-internal'; import { NodeService, nodeConfig } from '@kbn/core-node-server-internal'; import { AnalyticsService } from '@kbn/core-analytics-server-internal'; -import { registerMetricEvent, reportMetricEvent } from '@kbn/ebt-tools'; +import type { AnalyticsServiceSetup, AnalyticsServiceStart } from '@kbn/core-analytics-server'; +import { reportMetricEvent } from '@kbn/ebt-tools'; import { EnvironmentService, pidConfig } from '@kbn/core-environment-server-internal'; import { ExecutionContextService, @@ -235,7 +236,7 @@ export class Server { const analyticsSetup = this.analytics.setup(); - registerMetricEvent(analyticsSetup); + this.registerKibanaStartedEventType(analyticsSetup); const environmentSetup = this.environment.setup(); @@ -399,25 +400,7 @@ export class Server { startTransaction?.end(); this.uptimePerStep.start = { start: startStartUptime, end: process.uptime() }; - - const ups = this.uptimePerStep; - - reportMetricEvent(this.coreStart.analytics, { - eventName: KIBANA_STARTED_EVENT, - duration: ups.start!.end - ups.constructor!.start, - key1: 'constructor-time', - value1: ups.constructor!.end - ups.constructor!.start, - key2: 'preboot-time', - value2: ups.preboot!.end - ups.preboot!.start, - key3: 'setup-time', - value3: ups.setup!.end - ups.setup!.start, - key4: 'start-time', - value4: ups.start!.end - ups.start!.start, - // backwards compatibility - meta: { - uptime_per_step: this.uptimePerStep, - }, - }); + this.reportKibanaStartedEvents(analyticsStart); return this.coreStart; } @@ -478,4 +461,125 @@ export class Server { this.configService.setSchema(descriptor.path, descriptor.schema); } } + + /** + * Register the legacy KIBANA_STARTED_EVENT. + * @param analyticsSetup The {@link AnalyticsServiceSetup} + * @private + */ + private registerKibanaStartedEventType(analyticsSetup: AnalyticsServiceSetup) { + analyticsSetup.registerEventType<{ uptime_per_step: UptimeSteps }>({ + eventType: KIBANA_STARTED_EVENT, + schema: { + uptime_per_step: { + properties: { + constructor: { + properties: { + start: { + type: 'float', + _meta: { + description: + 'Number of seconds the Node.js process has been running until the constructor was called', + }, + }, + end: { + type: 'float', + _meta: { + description: + 'Number of seconds the Node.js process has been running until the constructor finished', + }, + }, + }, + }, + preboot: { + properties: { + start: { + type: 'float', + _meta: { + description: + 'Number of seconds the Node.js process has been running until `preboot` was called', + }, + }, + end: { + type: 'float', + _meta: { + description: + 'Number of seconds the Node.js process has been running until `preboot` finished', + }, + }, + }, + }, + setup: { + properties: { + start: { + type: 'float', + _meta: { + description: + 'Number of seconds the Node.js process has been running until `setup` was called', + }, + }, + end: { + type: 'float', + _meta: { + description: + 'Number of seconds the Node.js process has been running until `setup` finished', + }, + }, + }, + }, + start: { + properties: { + start: { + type: 'float', + _meta: { + description: + 'Number of seconds the Node.js process has been running until `start` was called', + }, + }, + end: { + type: 'float', + _meta: { + description: + 'Number of seconds the Node.js process has been running until `start` finished', + }, + }, + }, + }, + }, + _meta: { + description: + 'Number of seconds the Node.js process has been running until each phase of the server execution is called and finished.', + }, + }, + }, + }); + } + + /** + * Reports the new and legacy KIBANA_STARTED_EVENT. + * @param analyticsStart The {@link AnalyticsServiceStart}. + * @private + */ + private reportKibanaStartedEvents(analyticsStart: AnalyticsServiceStart) { + // Report the legacy KIBANA_STARTED_EVENT. + analyticsStart.reportEvent(KIBANA_STARTED_EVENT, { uptime_per_step: this.uptimePerStep }); + + const ups = this.uptimePerStep; + + // Report the metric-shaped KIBANA_STARTED_EVENT. + reportMetricEvent(analyticsStart, { + eventName: KIBANA_STARTED_EVENT, + duration: ups.start!.end - ups.constructor!.start, + key1: 'time-to-constructor', + value1: ups.constructor?.start, + key2: 'constructor-time', + value2: ups.constructor!.end - ups.constructor!.start, + key3: 'preboot-time', + value3: ups.preboot!.end - ups.preboot!.start, + key4: 'setup-time', + value4: ups.setup!.end - ups.setup!.start, + key5: 'start-time', + value5: ups.start!.end - ups.start!.start, + }); + } } diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx index 57325222dc8bf..c77a4b7d4769c 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx @@ -165,15 +165,17 @@ export class DashboardContainer extends Container { - const { eventTypes = [], withTimeoutMs, fromTimestamp } = options; + const { eventTypes = [], withTimeoutMs, fromTimestamp, filters } = options; const filteredEvents$ = events$.pipe( filter((event) => { @@ -39,6 +40,28 @@ export async function fetchEvents( return new Date(event.timestamp).getTime() - new Date(fromTimestamp).getTime() > 0; } return true; + }), + filter((event) => { + if (filters) { + return Object.entries(filters).every(([key, comparison]) => { + const value = get(event, key); + return Object.entries(comparison).every(([operation, valueToCompare]) => { + switch (operation) { + case 'eq': + return value === valueToCompare; + case 'gte': + return value >= (valueToCompare as typeof value); + case 'gt': + return value > (valueToCompare as typeof value); + case 'lte': + return value <= (valueToCompare as typeof value); + case 'lt': + return value < (valueToCompare as typeof value); + } + }); + }); + } + return true; }) ); diff --git a/test/analytics/fixtures/plugins/analytics_ftr_helpers/common/types.ts b/test/analytics/fixtures/plugins/analytics_ftr_helpers/common/types.ts index 3f66cde1fa3ae..97e1faff823a4 100644 --- a/test/analytics/fixtures/plugins/analytics_ftr_helpers/common/types.ts +++ b/test/analytics/fixtures/plugins/analytics_ftr_helpers/common/types.ts @@ -8,6 +8,10 @@ import type { Event, EventType } from '@kbn/analytics-client'; +export type FiltersOptions = { + [key in 'eq' | 'gte' | 'gt' | 'lte' | 'lt']?: unknown; +}; + export interface GetEventsOptions { /** * eventTypes (optional) array of event types to return @@ -24,6 +28,18 @@ export interface GetEventsOptions { * @remarks Useful when we need to retrieve the events after a specific action, and we don't care about anything prior to that. */ fromTimestamp?: string; + /** + * List of internal keys to validate in the event with the validation comparison. + * @example + * { + * filters: { + * 'properties.my_key': { + * eq: 'my expected value', + * }, + * }, + * } + */ + filters?: Record; } export interface EBTHelpersContract { @@ -37,7 +53,10 @@ export interface EBTHelpersContract { * @param takeNumberOfEvents - number of events to return * @param options (optional) list of options to filter events or for advanced usage of the API {@link GetEventsOptions}. */ - getEvents: (takeNumberOfEvents: number, options?: GetEventsOptions) => Promise; + getEvents: ( + takeNumberOfEvents: number, + options?: GetEventsOptions + ) => Promise>>>; /** * Count the number of events that match the filters. * @param options list of options to filter the events {@link GetEventsOptions}. `withTimeoutMs` is required in this API. diff --git a/test/analytics/fixtures/plugins/analytics_ftr_helpers/public/plugin.test.ts b/test/analytics/fixtures/plugins/analytics_ftr_helpers/public/plugin.test.ts index c5cb6d4df1dd3..b3f86172b751b 100644 --- a/test/analytics/fixtures/plugins/analytics_ftr_helpers/public/plugin.test.ts +++ b/test/analytics/fixtures/plugins/analytics_ftr_helpers/public/plugin.test.ts @@ -127,5 +127,32 @@ describe('AnalyticsFTRHelpers', () => { }) ).resolves.toEqual([{ ...event, timestamp: '2022-06-10T00:00:00.000Z' }]); }); + + test('should filter by `filters` when provided', async () => { + // 3 enqueued events + const events = [ + { ...event, timestamp: '2022-01-10T00:00:00.000Z' }, + { ...event, timestamp: '2022-03-10T00:00:00.000Z', properties: { my_property: 20 } }, + { ...event, timestamp: '2022-06-10T00:00:00.000Z' }, + ]; + events.forEach((ev) => events$.next(ev)); + + await expect( + window.__analytics_ftr_helpers__.getEvents(1, { + eventTypes: [event.event_type], + filters: { + 'properties.my_property': { + eq: 20, + gte: 20, + lte: 20, + gt: 10, + lt: 30, + }, + }, + }) + ).resolves.toEqual([ + { ...event, timestamp: '2022-03-10T00:00:00.000Z', properties: { my_property: 20 } }, + ]); + }); }); }); diff --git a/test/analytics/fixtures/plugins/analytics_ftr_helpers/server/plugin.ts b/test/analytics/fixtures/plugins/analytics_ftr_helpers/server/plugin.ts index 88cacd2bfd36d..2e5d93345b07f 100644 --- a/test/analytics/fixtures/plugins/analytics_ftr_helpers/server/plugin.ts +++ b/test/analytics/fixtures/plugins/analytics_ftr_helpers/server/plugin.ts @@ -48,6 +48,21 @@ export class AnalyticsFTRHelpers implements Plugin { eventTypes: schema.arrayOf(schema.string()), withTimeoutMs: schema.maybe(schema.number()), fromTimestamp: schema.maybe(schema.string()), + filters: schema.maybe( + schema.recordOf( + schema.string(), + schema.recordOf( + schema.oneOf([ + schema.literal('eq'), + schema.literal('gte'), + schema.literal('gt'), + schema.literal('lte'), + schema.literal('lt'), + ]), + schema.any() + ) + ) + ), }), }, }, diff --git a/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts b/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts index 4fda618fffb07..3d0b018156ce7 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/core_context_providers.ts @@ -8,7 +8,6 @@ import expect from '@kbn/expect'; import { Event } from '@kbn/core/public'; -import { KIBANA_LOADED_EVENT } from '@kbn/core/public/events'; import { FtrProviderContext } from '../../../services'; export default function ({ getService, getPageObjects }: FtrProviderContext) { @@ -17,10 +16,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const { common } = getPageObjects(['common']); describe('Core Context Providers', () => { - let event: Event; + let event: Event>; before(async () => { await common.navigateToApp('home'); - [event] = await ebtUIHelper.getEvents(1, { eventTypes: [KIBANA_LOADED_EVENT] }); // Get the loaded Kibana event + [event] = await ebtUIHelper.getEvents(1, { eventTypes: ['Loaded Kibana'] }); // Get the loaded Kibana event }); it('should have the properties provided by the "cluster info" context provider', () => { diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts index 9b243f7c2e865..88143016324d0 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts @@ -8,9 +8,10 @@ import { GetEventsOptions } from '@kbn/analytics-ftr-helpers-plugin/common/types'; import expect from '@kbn/expect'; -import { DASHBOARD_LOADED_EVENT } from '@kbn/dashboard-plugin/public/events'; import { FtrProviderContext } from '../../../services'; +const DASHBOARD_LOADED_EVENT = 'dashboard_loaded'; + export default function ({ getService, getPageObjects }: FtrProviderContext) { const ebtUIHelper = getService('kibana_ebt_ui'); const PageObjects = getPageObjects([ @@ -30,9 +31,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const getEvents = async (count: number, options?: GetEventsOptions) => ebtUIHelper.getEvents(count, { - eventTypes: [DASHBOARD_LOADED_EVENT], + eventTypes: ['metric'], fromTimestamp, withTimeoutMs: 1000, + filters: { 'properties.eventName': { eq: DASHBOARD_LOADED_EVENT } }, ...options, }); @@ -40,13 +42,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const events = await getEvents(Number.MAX_SAFE_INTEGER, options); expect(events.length).to.be(1); const event = events[0]; - expect(event.event_type).to.eql(DASHBOARD_LOADED_EVENT); + expect(event.event_type).to.eql('metric'); + expect(event.properties.eventName).to.eql(DASHBOARD_LOADED_EVENT); expect(event.context.applicationId).to.be('dashboards'); expect(event.context.page).to.be('app'); expect(event.context.pageName).to.be('application:dashboards:app'); expect(event.properties.status).to.be('done'); - expect(event.properties.timeToData).to.be.a('number'); - expect(event.properties.timeToDone).to.be.a('number'); + expect(event.properties.duration).to.be.a('number'); + expect(event.properties.key1).to.eql('time_to_data'); + expect(event.properties.value1).to.be.a('number'); + expect(event.properties.key2).to.eql('num_of_panels'); + expect(event.properties.value2).to.be.a('number'); // update fromTimestamp fromTimestamp = event.timestamp; @@ -82,7 +88,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.common.navigateToApp('dashboards'); }); - it('doesnt emit on empty dashboard', async () => { + it("doesn't emit on empty dashboard", async () => { await PageObjects.dashboard.clickNewDashboard(); await checkDoesNotEmit(); }); @@ -110,7 +116,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await checkEmitsOnce(); }); - it('doesnt emit when removing saved search panel', async () => { + it("doesn't emit when removing saved search panel", async () => { await dashboardPanelActions.removePanelByTitle(SAVED_SEARCH_PANEL_TITLE); await checkDoesNotEmit(); }); @@ -128,7 +134,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await checkEmitsOnce(); }); - it('doesnt emit when removing vis panel', async () => { + it("doesn't emit when removing vis panel", async () => { await dashboardPanelActions.removePanelByTitle(VIS_PANEL_TITLE); await checkDoesNotEmit(); }); @@ -152,7 +158,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await checkEmitsOnce(); }); - it('doesnt emit when removing markup panel', async () => { + it("doesn't emit when removing markup panel", async () => { await dashboardPanelActions.removePanelByTitle(MARKDOWN_PANEL_TITLE); await checkDoesNotEmit(); }); @@ -172,7 +178,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await checkEmitsOnce(); }); - it('doesnt emit when removing map panel', async () => { + it("doesn't emit when removing map panel", async () => { await dashboardPanelActions.removePanelByTitle(MAP_PANEL_TITLE); await checkDoesNotEmit(); }); diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts index f3f7f980115aa..0c7f39d3617b0 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts @@ -6,41 +6,38 @@ * Side Public License, v 1. */ -import { Event } from '@kbn/analytics-client'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../services'; -const KIBANA_LOADED_EVENT = 'kibana_loaded'; - export default function ({ getService, getPageObjects }: FtrProviderContext) { const ebtUIHelper = getService('kibana_ebt_ui'); const { common } = getPageObjects(['common']); + const browser = getService('browser'); describe('Loaded Kibana', () => { beforeEach(async () => { await common.navigateToApp('home'); }); - it('should emit the legacy "Loaded Kibana" and new kibana-loaded events', async () => { - const events = await ebtUIHelper.getEvents(2, { - eventTypes: [KIBANA_LOADED_EVENT, 'Loaded Kibana'], - }); + it('should emit the legacy "Loaded Kibana"', async () => { + const [event] = await ebtUIHelper.getEvents(1, { eventTypes: ['Loaded Kibana'] }); - const legacyEvent = events.find( - (e) => e.event_type !== KIBANA_LOADED_EVENT - ) as unknown as Event; - const event = events.find((e) => e.event_type === KIBANA_LOADED_EVENT) as unknown as Event; + expect(event.event_type).to.eql('Loaded Kibana'); + expect(event.properties).to.have.property('kibana_version'); + expect(event.properties.kibana_version).to.be.a('string'); + expect(event.properties).to.have.property('protocol'); + expect(event.properties.protocol).to.be.a('string'); + }); - // Legacy event - expect(legacyEvent.event_type).to.eql('Loaded Kibana'); - expect(legacyEvent.properties).to.have.property('kibana_version'); - expect(legacyEvent.properties.kibana_version).to.be.a('string'); - expect(legacyEvent.properties).to.have.property('protocol'); - expect(legacyEvent.properties.protocol).to.be.a('string'); + it('should emit the new kibana-loaded events', async () => { + const [event] = await ebtUIHelper.getEvents(1, { + eventTypes: ['metric'], + filters: { 'properties.eventName': { eq: 'kibana_loaded' } }, + }); // New event expect(event.event_type).to.eql('metric'); - expect(event.properties.eventName).to.eql(KIBANA_LOADED_EVENT); + expect(event.properties.eventName).to.eql('kibana_loaded'); // meta expect(event.properties).to.have.property('meta'); @@ -64,6 +61,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(event.properties.value3).to.be.a('number'); expect(event.properties.value4).to.be.a('number'); expect(event.properties.value5).to.be.a('number'); + + if (browser.isChromium) { + // Kibana Loaded memory + expect(event.properties).to.have.property('jsHeapSizeLimit'); + expect(event.properties.jsHeapSizeLimit).to.be.a('number'); + expect(event.properties).to.have.property('totalJSHeapSize'); + expect(event.properties.totalJSHeapSize).to.be.a('number'); + expect(event.properties).to.have.property('usedJSHeapSize'); + expect(event.properties.usedJSHeapSize).to.be.a('number'); + } }); }); } diff --git a/test/analytics/tests/instrumented_events/from_the_server/core_context_providers.ts b/test/analytics/tests/instrumented_events/from_the_server/core_context_providers.ts index 9a694c38b8b40..cf781bed5ad0e 100644 --- a/test/analytics/tests/instrumented_events/from_the_server/core_context_providers.ts +++ b/test/analytics/tests/instrumented_events/from_the_server/core_context_providers.ts @@ -15,7 +15,7 @@ export default function ({ getService }: FtrProviderContext) { const ebtServerHelper = getService('kibana_ebt_server'); describe('Core Context Providers', () => { - let event: Event; + let event: Event>; before(async () => { let i = 2; do { diff --git a/test/analytics/tests/instrumented_events/from_the_server/core_overall_status_changed.ts b/test/analytics/tests/instrumented_events/from_the_server/core_overall_status_changed.ts index 07c03465f6c27..8f904c4c8844c 100644 --- a/test/analytics/tests/instrumented_events/from_the_server/core_overall_status_changed.ts +++ b/test/analytics/tests/instrumented_events/from_the_server/core_overall_status_changed.ts @@ -14,8 +14,8 @@ export default function ({ getService }: FtrProviderContext) { const ebtServerHelper = getService('kibana_ebt_server'); describe('core-overall_status_changed', () => { - let initialEvent: Event; - let secondEvent: Event; + let initialEvent: Event>; + let secondEvent: Event>; before(async () => { [initialEvent, secondEvent] = await ebtServerHelper.getEvents(2, { diff --git a/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts b/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts index 9d806e589f459..533ee32995438 100644 --- a/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts +++ b/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts @@ -13,10 +13,9 @@ export default function ({ getService }: FtrProviderContext) { const ebtServerHelper = getService('kibana_ebt_server'); describe('kibana_started', () => { - it('should emit the "kibana_started" event', async () => { + it('should emit the legacy "kibana_started" event', async () => { const [event] = await ebtServerHelper.getEvents(1, { eventTypes: ['kibana_started'] }); - expect(event.event_type).to.eql('metric'); - expect(event.properties.event_name).to.eql('kibana_started'); + expect(event.event_type).to.eql('kibana_started'); const uptimePerStep = event.properties.uptime_per_step as Record< 'constructor' | 'preboot' | 'setup' | 'start', Record<'start' | 'end', number> @@ -30,5 +29,25 @@ export default function ({ getService }: FtrProviderContext) { expect(uptimePerStep.start.start).to.be.a('number'); expect(uptimePerStep.start.end).to.be.a('number'); }); + + it('should emit the "kibana_started" metric event', async () => { + const [event] = await ebtServerHelper.getEvents(1, { + eventTypes: ['metric'], + filters: { 'properties.eventName': { eq: 'kibana_started' } }, + }); + expect(event.event_type).to.eql('metric'); + expect(event.properties.eventName).to.eql('kibana_started'); + expect(event.properties.duration).to.be.a('number'); + expect(event.properties.key1).to.eql('time-to-constructor'); + expect(event.properties.value1).to.be.a('number'); + expect(event.properties.key2).to.eql('constructor-time'); + expect(event.properties.value2).to.be.a('number'); + expect(event.properties.key3).to.eql('preboot-time'); + expect(event.properties.value3).to.be.a('number'); + expect(event.properties.key4).to.eql('setup-time'); + expect(event.properties.value4).to.be.a('number'); + expect(event.properties.key5).to.eql('start-time'); + expect(event.properties.value5).to.be.a('number'); + }); }); } From 06a8f38fc9a9f996b29f9b0fdfc8a06435ad1283 Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 20 Jul 2022 16:25:53 +0300 Subject: [PATCH 30/45] Convert KIBANA_STARTED_EVENT times to ms --- src/core/server/server.ts | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 1549e42f3d79c..6ad4717e57344 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -566,20 +566,21 @@ export class Server { const ups = this.uptimePerStep; + const toMs = (sec: number) => Math.round(sec * 100); // Report the metric-shaped KIBANA_STARTED_EVENT. reportMetricEvent(analyticsStart, { eventName: KIBANA_STARTED_EVENT, - duration: ups.start!.end - ups.constructor!.start, - key1: 'time-to-constructor', - value1: ups.constructor?.start, - key2: 'constructor-time', - value2: ups.constructor!.end - ups.constructor!.start, - key3: 'preboot-time', - value3: ups.preboot!.end - ups.preboot!.start, - key4: 'setup-time', - value4: ups.setup!.end - ups.setup!.start, - key5: 'start-time', - value5: ups.start!.end - ups.start!.start, + duration: toMs(ups.start!.end - ups.constructor!.start), + key1: 'time_to_constructor', + value1: toMs(ups.constructor!.start), + key2: 'constructor_time', + value2: toMs(ups.constructor!.end - ups.constructor!.start), + key3: 'preboot_time', + value3: toMs(ups.preboot!.end - ups.preboot!.start), + key4: 'setup_time', + value4: toMs(ups.setup!.end - ups.setup!.start), + key5: 'start_time', + value5: toMs(ups.start!.end - ups.start!.start), }); } } From adcce9052d50df209683bb9806dbe1256399817f Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 20 Jul 2022 20:25:43 +0300 Subject: [PATCH 31/45] test --- .../from_the_server/kibana_started.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts b/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts index 533ee32995438..bcb477708b3d0 100644 --- a/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts +++ b/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts @@ -38,15 +38,15 @@ export default function ({ getService }: FtrProviderContext) { expect(event.event_type).to.eql('metric'); expect(event.properties.eventName).to.eql('kibana_started'); expect(event.properties.duration).to.be.a('number'); - expect(event.properties.key1).to.eql('time-to-constructor'); + expect(event.properties.key1).to.eql('time_to_constructor'); expect(event.properties.value1).to.be.a('number'); - expect(event.properties.key2).to.eql('constructor-time'); + expect(event.properties.key2).to.eql('constructor_time'); expect(event.properties.value2).to.be.a('number'); - expect(event.properties.key3).to.eql('preboot-time'); + expect(event.properties.key3).to.eql('preboot_time'); expect(event.properties.value3).to.be.a('number'); - expect(event.properties.key4).to.eql('setup-time'); + expect(event.properties.key4).to.eql('setup_time'); expect(event.properties.value4).to.be.a('number'); - expect(event.properties.key5).to.eql('start-time'); + expect(event.properties.key5).to.eql('starttime'); expect(event.properties.value5).to.be.a('number'); }); }); From 43d2f84e8ff10f72e0e4894032560f4ed01a33b0 Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 21 Jul 2022 12:51:27 +0300 Subject: [PATCH 32/45] test --- .../tests/instrumented_events/from_the_server/kibana_started.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts b/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts index bcb477708b3d0..c06e13ee476ee 100644 --- a/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts +++ b/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts @@ -46,7 +46,7 @@ export default function ({ getService }: FtrProviderContext) { expect(event.properties.value3).to.be.a('number'); expect(event.properties.key4).to.eql('setup_time'); expect(event.properties.value4).to.be.a('number'); - expect(event.properties.key5).to.eql('starttime'); + expect(event.properties.key5).to.eql('start_time'); expect(event.properties.value5).to.be.a('number'); }); }); From ffc7e6aa878b5fd646f56a3481fc68224da96b4c Mon Sep 17 00:00:00 2001 From: suchcodemuchwow Date: Thu, 28 Jul 2022 15:49:08 +0200 Subject: [PATCH 33/45] fix sec -> ms conversion --- src/core/server/server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 6f1abccd454fd..16033f739574e 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -568,7 +568,7 @@ export class Server { const ups = this.uptimePerStep; - const toMs = (sec: number) => Math.round(sec * 100); + const toMs = (sec: number) => Math.round(sec * 1000); // Report the metric-shaped KIBANA_STARTED_EVENT. reportMetricEvent(analyticsStart, { eventName: KIBANA_STARTED_EVENT, From 38dac93d965db6ac0ebd0a96880c68151c40c074 Mon Sep 17 00:00:00 2001 From: suchcodemuchwow Date: Thu, 28 Jul 2022 16:40:07 +0200 Subject: [PATCH 34/45] rename metric->performance_metric * makes duration field required * renames metric events to performance_metric_events * updates usages of reporter functions * removing .resolves to fix whitespace diff between snapshot updates * updates snapshots --- .../src/analytics_service.test.ts | 38 +++++++++---------- .../src/analytics_service.ts | 6 +-- .../src/analytics_service.test.ts | 4 +- .../src/analytics_service.ts | 4 +- .../src/metric_events/helpers.test.ts | 30 ++++++++------- .../src/metric_events/helpers.ts | 12 +++--- .../kbn-ebt-tools/src/metric_events/index.ts | 5 ++- .../kbn-ebt-tools/src/metric_events/schema.ts | 4 +- src/core/public/core_system.test.ts | 4 +- src/core/public/core_system.ts | 4 +- src/core/server/server.ts | 4 +- .../embeddable/dashboard_container.tsx | 4 +- .../from_the_browser/loaded_dashboard.ts | 4 +- .../from_the_browser/loaded_kibana.ts | 4 +- .../from_the_server/kibana_started.ts | 4 +- 15 files changed, 69 insertions(+), 62 deletions(-) diff --git a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts index cdd5a27ee9500..cd70b72420ec2 100644 --- a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts +++ b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts @@ -21,23 +21,23 @@ describe('AnalyticsService', () => { test('should register some context providers on creation', async () => { expect(analyticsClientMock.registerContextProvider).toHaveBeenCalledTimes(3); await expect( - firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[0][0].context$) - ).resolves.toMatchInlineSnapshot(` - Object { - "branch": "branch", - "buildNum": 100, - "buildSha": "buildSha", - "isDev": true, - "isDistributable": false, - "version": "version", - } - `); + await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[0][0].context$) + ).toMatchInlineSnapshot(` + Object { + "branch": "branch", + "buildNum": 100, + "buildSha": "buildSha", + "isDev": true, + "isDistributable": false, + "version": "version", + } + `); await expect( - firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[1][0].context$) - ).resolves.toEqual({ session_id: expect.any(String) }); + await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[1][0].context$) + ).toEqual({ session_id: expect.any(String) }); await expect( - firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[2][0].context$) - ).resolves.toEqual({ + await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[2][0].context$) + ).toEqual({ preferred_language: 'en-US', preferred_languages: ['en-US', 'en'], user_agent: expect.any(String), @@ -210,8 +210,8 @@ describe('AnalyticsService', () => { const injectedMetadata = injectedMetadataServiceMock.createSetupContract(); analyticsService.setup({ injectedMetadata }); await expect( - firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[3][0].context$) - ).resolves.toMatchInlineSnapshot(`undefined`); + await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[3][0].context$) + ).toMatchInlineSnapshot(`undefined`); }); test('setup should register the elasticsearch info context provider (with info)', async () => { @@ -223,8 +223,8 @@ describe('AnalyticsService', () => { }); analyticsService.setup({ injectedMetadata }); await expect( - firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[3][0].context$) - ).resolves.toMatchInlineSnapshot(` + await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[3][0].context$) + ).toMatchInlineSnapshot(` Object { "cluster_name": "cluster_name", "cluster_uuid": "cluster_uuid", diff --git a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts index 84eb75df04098..9cad35d22134d 100644 --- a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts +++ b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts @@ -9,7 +9,7 @@ import { of } from 'rxjs'; import type { AnalyticsClient } from '@kbn/analytics-client'; import { createAnalytics } from '@kbn/analytics-client'; -import { registerMetricEventType } from '@kbn/ebt-tools'; +import { registerPerformanceMetricEventType } from '@kbn/ebt-tools'; import type { CoreContext } from '@kbn/core-base-browser-internal'; import type { InternalInjectedMetadataSetup } from '@kbn/core-injected-metadata-browser-internal'; import type { AnalyticsServiceSetup, AnalyticsServiceStart } from '@kbn/core-analytics-browser'; @@ -35,8 +35,8 @@ export class AnalyticsService { }); this.registerBuildInfoAnalyticsContext(core); - // Register special `metrics` type - registerMetricEventType(this.analyticsClient); + // Register special `performance_metrics` type + registerPerformanceMetricEventType(this.analyticsClient); // We may eventually move the following to the client's package since they are not Kibana-specific // and can benefit other consumers of the client. diff --git a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts index 74d1b6e4119ee..73fcc28cc1e54 100644 --- a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts +++ b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts @@ -21,8 +21,8 @@ describe('AnalyticsService', () => { test('should register the context provider `build info` on creation', async () => { expect(analyticsClientMock.registerContextProvider).toHaveBeenCalledTimes(1); await expect( - firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[0][0].context$) - ).resolves.toMatchInlineSnapshot(` + await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[0][0].context$) + ).toMatchInlineSnapshot(` Object { "branch": "main", "buildNum": 9007199254740991, diff --git a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts index 7aaebe2235955..aac8048f166db 100644 --- a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts +++ b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts @@ -9,7 +9,7 @@ import { of } from 'rxjs'; import type { AnalyticsClient } from '@kbn/analytics-client'; import { createAnalytics } from '@kbn/analytics-client'; -import { registerMetricEventType } from '@kbn/ebt-tools'; +import { registerPerformanceMetricEventType } from '@kbn/ebt-tools'; import type { CoreContext } from '@kbn/core-base-server-internal'; import type { AnalyticsServiceSetup, @@ -31,7 +31,7 @@ export class AnalyticsService { this.registerBuildInfoAnalyticsContext(core); // Register special `metrics` type - registerMetricEventType(this.analyticsClient); + registerPerformanceMetricEventType(this.analyticsClient); } public preboot(): AnalyticsServicePreboot { diff --git a/packages/kbn-ebt-tools/src/metric_events/helpers.test.ts b/packages/kbn-ebt-tools/src/metric_events/helpers.test.ts index 376e5d926c252..324a050ca802a 100644 --- a/packages/kbn-ebt-tools/src/metric_events/helpers.test.ts +++ b/packages/kbn-ebt-tools/src/metric_events/helpers.test.ts @@ -8,13 +8,13 @@ import { createAnalytics, type AnalyticsClient } from '@kbn/analytics-client'; import { loggerMock } from '@kbn/logging-mocks'; -import { registerMetricEventType, reportMetricEvent } from './helpers'; +import { registerPerformanceMetricEventType, reportPerformanceMetricEvent } from './helpers'; import { METRIC_EVENT_SCHEMA } from './schema'; describe('metric event helpers', () => { let analyticsClient: AnalyticsClient; - describe('registerMetricEventType', () => { + describe('registerPerformanceMetricEventType', () => { beforeEach(() => { analyticsClient = createAnalytics({ isDev: true, // Explicitly setting `true` to ensure we have event validation to make sure the events sent pass our validation. @@ -23,34 +23,34 @@ describe('metric event helpers', () => { }); }); - test('registers the `metrics` eventType to the analytics client', () => { + test('registers the `performance_metric` eventType to the analytics client', () => { const registerEventTypeSpy = jest.spyOn(analyticsClient, 'registerEventType'); - expect(() => registerMetricEventType(analyticsClient)).not.toThrow(); + expect(() => registerPerformanceMetricEventType(analyticsClient)).not.toThrow(); expect(registerEventTypeSpy).toHaveBeenCalledWith({ - eventType: 'metric', + eventType: 'performance_metric', schema: METRIC_EVENT_SCHEMA, }); }); }); - describe('reportMetricEvent', () => { + describe('reportPerformanceMetricEvent', () => { beforeEach(() => { analyticsClient = createAnalytics({ isDev: true, // Explicitly setting `true` to ensure we have event validation to make sure the events sent pass our validation. sendTo: 'staging', logger: loggerMock.create(), }); - registerMetricEventType(analyticsClient); + registerPerformanceMetricEventType(analyticsClient); }); test('reports the minimum allowed event', () => { - reportMetricEvent(analyticsClient, { eventName: 'test-event' }); + reportPerformanceMetricEvent(analyticsClient, { eventName: 'test-event', duration: 1000 }); }); test('reports all the allowed fields in the event', () => { - reportMetricEvent(analyticsClient, { + reportPerformanceMetricEvent(analyticsClient, { eventName: 'test-event', meta: { my: { custom: { fields: 'here' } }, another_field: true }, status: 'something', @@ -70,26 +70,28 @@ describe('metric event helpers', () => { test('should fail if eventName is missing', () => { expect(() => - reportMetricEvent( + reportPerformanceMetricEvent( analyticsClient, // @ts-expect-error {} ) ).toThrowErrorMatchingInlineSnapshot(` - "Failed to validate payload coming from \\"Event Type 'metric'\\": - - [eventName]: {\\"expected\\":\\"string\\",\\"actual\\":\\"undefined\\",\\"value\\":\\"undefined\\"}" + "Failed to validate payload coming from \\"Event Type 'performance_metric'\\": + - [eventName]: {\\"expected\\":\\"string\\",\\"actual\\":\\"undefined\\",\\"value\\":\\"undefined\\"} + - [duration]: {\\"expected\\":\\"number\\",\\"actual\\":\\"undefined\\",\\"value\\":\\"undefined\\"}" `); }); test('should fail if any additional unknown keys are added', () => { expect(() => - reportMetricEvent(analyticsClient, { + reportPerformanceMetricEvent(analyticsClient, { eventName: 'test-event', + duration: 1000, // @ts-expect-error an_unknown_field: 'blah', }) ).toThrowErrorMatchingInlineSnapshot(` - "Failed to validate payload coming from \\"Event Type 'metric'\\": + "Failed to validate payload coming from \\"Event Type 'performance_metric'\\": - []: excess key 'an_unknown_field' found" `); }); diff --git a/packages/kbn-ebt-tools/src/metric_events/helpers.ts b/packages/kbn-ebt-tools/src/metric_events/helpers.ts index d385abb676cd8..f332402b60cb8 100644 --- a/packages/kbn-ebt-tools/src/metric_events/helpers.ts +++ b/packages/kbn-ebt-tools/src/metric_events/helpers.ts @@ -9,16 +9,18 @@ import type { AnalyticsClient } from '@kbn/analytics-client'; import { type MetricEvent, METRIC_EVENT_SCHEMA } from './schema'; -const METRIC_EVENT_TYPE = 'metric'; +const PERFORMANCE_METRIC_EVENT_TYPE = 'performance_metric'; /** * Register the `metrics` event type * @param analytics The {@link AnalyticsClient} during the setup phase (it has the method `registerEventType`) * @private To be called only by core's Analytics Service */ -export function registerMetricEventType(analytics: Pick) { +export function registerPerformanceMetricEventType( + analytics: Pick +) { analytics.registerEventType({ - eventType: METRIC_EVENT_TYPE, + eventType: PERFORMANCE_METRIC_EVENT_TYPE, schema: METRIC_EVENT_SCHEMA, }); } @@ -28,9 +30,9 @@ export function registerMetricEventType(analytics: Pick, eventData: MetricEvent ) { - analytics.reportEvent(METRIC_EVENT_TYPE, eventData); + analytics.reportEvent(PERFORMANCE_METRIC_EVENT_TYPE, eventData); } diff --git a/packages/kbn-ebt-tools/src/metric_events/index.ts b/packages/kbn-ebt-tools/src/metric_events/index.ts index 1b9e5c762d7f4..95bbfeb2dad19 100644 --- a/packages/kbn-ebt-tools/src/metric_events/index.ts +++ b/packages/kbn-ebt-tools/src/metric_events/index.ts @@ -6,4 +6,7 @@ * Side Public License, v 1. */ export type { MetricEvent } from './schema'; -export { registerMetricEventType, reportMetricEvent } from './helpers'; +export { + registerPerformanceMetricEventType as registerPerformanceMetricEventType, + reportPerformanceMetricEvent, +} from './helpers'; diff --git a/packages/kbn-ebt-tools/src/metric_events/schema.ts b/packages/kbn-ebt-tools/src/metric_events/schema.ts index 3d572963b07db..142cc6929e45b 100644 --- a/packages/kbn-ebt-tools/src/metric_events/schema.ts +++ b/packages/kbn-ebt-tools/src/metric_events/schema.ts @@ -25,7 +25,7 @@ export interface MetricEvent { * @group Standardized fields * The time (in milliseconds) it took to run the entire action. */ - duration?: number; + duration: number; /** * @group Standardized fields * A status relevant to the action (i.e.: `failed`, `succeeded`). @@ -110,7 +110,7 @@ export const METRIC_EVENT_SCHEMA: RootSchema = { }, duration: { type: 'integer', - _meta: { description: 'The main event duration in ms', optional: true }, + _meta: { description: 'The main event duration in ms' }, }, status: { type: 'keyword', diff --git a/src/core/public/core_system.test.ts b/src/core/public/core_system.test.ts index 0cafa8ed6bd39..32b51f9ec0182 100644 --- a/src/core/public/core_system.test.ts +++ b/src/core/public/core_system.test.ts @@ -287,7 +287,7 @@ describe('#start()', () => { it('reports the metric event kibana-loaded and clears marks', async () => { await startCore(); expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledTimes(2); - expect(analyticsServiceStartMock.reportEvent).toHaveBeenNthCalledWith(2, 'metric', { + expect(analyticsServiceStartMock.reportEvent).toHaveBeenNthCalledWith(2, 'performance_metric', { eventName: KIBANA_LOADED_EVENT, meta: { kibana_version: '1.2.3', @@ -320,7 +320,7 @@ describe('#start()', () => { await startCore(); expect(analyticsServiceStartMock.reportEvent).toHaveBeenCalledTimes(2); - expect(analyticsServiceStartMock.reportEvent).toHaveBeenNthCalledWith(2, 'metric', { + expect(analyticsServiceStartMock.reportEvent).toHaveBeenNthCalledWith(2, 'performance_metric', { eventName: KIBANA_LOADED_EVENT, meta: { kibana_version: '1.2.3', diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 34ad06766fabc..2baa95ba844f2 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -26,7 +26,7 @@ import { HttpService } from '@kbn/core-http-browser-internal'; import { UiSettingsService } from '@kbn/core-ui-settings-browser-internal'; import { DeprecationsService } from '@kbn/core-deprecations-browser-internal'; import { IntegrationsService } from '@kbn/core-integrations-browser-internal'; -import { reportMetricEvent } from '@kbn/ebt-tools'; +import { reportPerformanceMetricEvent } from '@kbn/ebt-tools'; import { fetchOptionalMemoryInfo } from './fetch_optional_memory_info'; import { CoreSetup, CoreStart } from '.'; import { ChromeService } from './chrome'; @@ -164,7 +164,7 @@ export class CoreSystem { }); const timing = this.getLoadMarksInfo(); - reportMetricEvent(analytics, { + reportPerformanceMetricEvent(analytics, { eventName: KIBANA_LOADED_EVENT, meta: { kibana_version: this.coreContext.env.packageInfo.version, diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 16033f739574e..a7f40ed916b0e 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -24,7 +24,7 @@ import { import { NodeService, nodeConfig } from '@kbn/core-node-server-internal'; import { AnalyticsService } from '@kbn/core-analytics-server-internal'; import type { AnalyticsServiceSetup, AnalyticsServiceStart } from '@kbn/core-analytics-server'; -import { reportMetricEvent } from '@kbn/ebt-tools'; +import { reportPerformanceMetricEvent } from '@kbn/ebt-tools'; import { EnvironmentService, pidConfig } from '@kbn/core-environment-server-internal'; import { ExecutionContextService, @@ -570,7 +570,7 @@ export class Server { const toMs = (sec: number) => Math.round(sec * 1000); // Report the metric-shaped KIBANA_STARTED_EVENT. - reportMetricEvent(analyticsStart, { + reportPerformanceMetricEvent(analyticsStart, { eventName: KIBANA_STARTED_EVENT, duration: toMs(ups.start!.end - ups.constructor!.start), key1: 'time_to_constructor', diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx index c77a4b7d4769c..527c90b3b48df 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx @@ -12,7 +12,7 @@ import { I18nProvider } from '@kbn/i18n-react'; import uuid from 'uuid'; import { CoreStart, IUiSettingsClient, KibanaExecutionContext } from '@kbn/core/public'; import { Start as InspectorStartContract } from '@kbn/inspector-plugin/public'; -import { reportMetricEvent } from '@kbn/ebt-tools'; +import { reportPerformanceMetricEvent } from '@kbn/ebt-tools'; import { ControlGroupContainer } from '@kbn/controls-plugin/public'; import { Filter, TimeRange } from '@kbn/es-query'; @@ -166,7 +166,7 @@ export class DashboardContainer extends Container ebtUIHelper.getEvents(count, { - eventTypes: ['metric'], + eventTypes: ['performance_metric'], fromTimestamp, withTimeoutMs: 1000, filters: { 'properties.eventName': { eq: DASHBOARD_LOADED_EVENT } }, @@ -42,7 +42,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const events = await getEvents(Number.MAX_SAFE_INTEGER, options); expect(events.length).to.be(1); const event = events[0]; - expect(event.event_type).to.eql('metric'); + expect(event.event_type).to.eql('performance_metric'); expect(event.properties.eventName).to.eql(DASHBOARD_LOADED_EVENT); expect(event.context.applicationId).to.be('dashboards'); expect(event.context.page).to.be('app'); diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts index 0c7f39d3617b0..c336dc5edafd9 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts @@ -31,12 +31,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should emit the new kibana-loaded events', async () => { const [event] = await ebtUIHelper.getEvents(1, { - eventTypes: ['metric'], + eventTypes: ['performance_metric'], filters: { 'properties.eventName': { eq: 'kibana_loaded' } }, }); // New event - expect(event.event_type).to.eql('metric'); + expect(event.event_type).to.eql('performance_metric'); expect(event.properties.eventName).to.eql('kibana_loaded'); // meta diff --git a/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts b/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts index c06e13ee476ee..d1b59ce9d4e9c 100644 --- a/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts +++ b/test/analytics/tests/instrumented_events/from_the_server/kibana_started.ts @@ -32,10 +32,10 @@ export default function ({ getService }: FtrProviderContext) { it('should emit the "kibana_started" metric event', async () => { const [event] = await ebtServerHelper.getEvents(1, { - eventTypes: ['metric'], + eventTypes: ['performance_metric'], filters: { 'properties.eventName': { eq: 'kibana_started' } }, }); - expect(event.event_type).to.eql('metric'); + expect(event.event_type).to.eql('performance_metric'); expect(event.properties.eventName).to.eql('kibana_started'); expect(event.properties.duration).to.be.a('number'); expect(event.properties.key1).to.eql('time_to_constructor'); From 51aa34bd863072238a9520defc6f308d8fcd5297 Mon Sep 17 00:00:00 2001 From: suchcodemuchwow Date: Fri, 29 Jul 2022 11:24:41 +0200 Subject: [PATCH 35/45] update snapshots --- .../src/analytics_service.test.ts | 3 +-- .../src/analytics_service.test.ts | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts index cd70b72420ec2..86073aa05d52f 100644 --- a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts +++ b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts @@ -49,12 +49,11 @@ describe('AnalyticsService', () => { expect(analyticsClientMock.registerEventType.mock.calls[0]).toMatchInlineSnapshot(` Array [ Object { - "eventType": "metric", + "eventType": "performance_metric", "schema": Object { "duration": Object { "_meta": Object { "description": "The main event duration in ms", - "optional": true, }, "type": "integer", }, diff --git a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts index 73fcc28cc1e54..bc132cccb6c12 100644 --- a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts +++ b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts @@ -29,7 +29,7 @@ describe('AnalyticsService', () => { "buildSha": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "isDev": true, "isDistributable": false, - "version": "8.4.0", + "version": "8.5.0", } `); }); @@ -39,12 +39,11 @@ describe('AnalyticsService', () => { expect(analyticsClientMock.registerEventType.mock.calls[0]).toMatchInlineSnapshot(` Array [ Object { - "eventType": "metric", + "eventType": "performance_metric", "schema": Object { "duration": Object { "_meta": Object { "description": "The main event duration in ms", - "optional": true, }, "type": "integer", }, From bcfd341c6e3edb710ed1519e5195c3ac346d80db Mon Sep 17 00:00:00 2001 From: suchcodemuchwow Date: Fri, 29 Jul 2022 14:49:33 +0200 Subject: [PATCH 36/45] remove memory related fields from standardized fields --- .../src/analytics_service.test.ts | 28 --------------- .../src/analytics_service.test.ts | 28 --------------- .../src/metric_events/helpers.test.ts | 3 +- .../kbn-ebt-tools/src/metric_events/schema.ts | 36 ------------------- src/core/public/core_system.test.ts | 2 +- src/core/public/core_system.ts | 2 +- .../from_the_browser/loaded_kibana.ts | 12 +++---- 7 files changed, 9 insertions(+), 102 deletions(-) diff --git a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts index 86073aa05d52f..fdc6f0dcccd61 100644 --- a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts +++ b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts @@ -63,13 +63,6 @@ describe('AnalyticsService', () => { }, "type": "keyword", }, - "jsHeapSizeLimit": Object { - "_meta": Object { - "description": "performance.memory.jsHeapSizeLimit", - "optional": true, - }, - "type": "long", - }, "key1": Object { "_meta": Object { "description": "Performance metric label 1", @@ -112,27 +105,6 @@ describe('AnalyticsService', () => { }, "type": "pass_through", }, - "status": Object { - "_meta": Object { - "description": "A status", - "optional": true, - }, - "type": "keyword", - }, - "totalJSHeapSize": Object { - "_meta": Object { - "description": "performance.memory.totalJSHeapSize", - "optional": true, - }, - "type": "long", - }, - "usedJSHeapSize": Object { - "_meta": Object { - "description": "performance.memory.usedJSHeapSize", - "optional": true, - }, - "type": "long", - }, "value1": Object { "_meta": Object { "description": "Performance metric value 1", diff --git a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts index bc132cccb6c12..80dd29fba7ea4 100644 --- a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts +++ b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts @@ -53,13 +53,6 @@ describe('AnalyticsService', () => { }, "type": "keyword", }, - "jsHeapSizeLimit": Object { - "_meta": Object { - "description": "performance.memory.jsHeapSizeLimit", - "optional": true, - }, - "type": "long", - }, "key1": Object { "_meta": Object { "description": "Performance metric label 1", @@ -102,27 +95,6 @@ describe('AnalyticsService', () => { }, "type": "pass_through", }, - "status": Object { - "_meta": Object { - "description": "A status", - "optional": true, - }, - "type": "keyword", - }, - "totalJSHeapSize": Object { - "_meta": Object { - "description": "performance.memory.totalJSHeapSize", - "optional": true, - }, - "type": "long", - }, - "usedJSHeapSize": Object { - "_meta": Object { - "description": "performance.memory.usedJSHeapSize", - "optional": true, - }, - "type": "long", - }, "value1": Object { "_meta": Object { "description": "Performance metric value 1", diff --git a/packages/kbn-ebt-tools/src/metric_events/helpers.test.ts b/packages/kbn-ebt-tools/src/metric_events/helpers.test.ts index 324a050ca802a..a1048849809ae 100644 --- a/packages/kbn-ebt-tools/src/metric_events/helpers.test.ts +++ b/packages/kbn-ebt-tools/src/metric_events/helpers.test.ts @@ -52,8 +52,7 @@ describe('metric event helpers', () => { test('reports all the allowed fields in the event', () => { reportPerformanceMetricEvent(analyticsClient, { eventName: 'test-event', - meta: { my: { custom: { fields: 'here' } }, another_field: true }, - status: 'something', + meta: { my: { custom: { fields: 'here' } }, another_field: true, status: 'something' }, duration: 10, key1: 'something', value1: 10, diff --git a/packages/kbn-ebt-tools/src/metric_events/schema.ts b/packages/kbn-ebt-tools/src/metric_events/schema.ts index 142cc6929e45b..14fd2d24c0845 100644 --- a/packages/kbn-ebt-tools/src/metric_events/schema.ts +++ b/packages/kbn-ebt-tools/src/metric_events/schema.ts @@ -26,26 +26,6 @@ export interface MetricEvent { * The time (in milliseconds) it took to run the entire action. */ duration: number; - /** - * @group Standardized fields - * A status relevant to the action (i.e.: `failed`, `succeeded`). - */ - status?: string; - /** - * @group Standardized fields - * performance.memory.jsHeapSizeLimit - */ - jsHeapSizeLimit?: number; - /** - * @group Standardized fields - * performance.memory.totalJSHeapSize - */ - totalJSHeapSize?: number; - /** - * @group Standardized fields - * performance.memory.usedJSHeapSize - */ - usedJSHeapSize?: number; /** * @group Free fields for custom metrics (searchable and aggregateable) @@ -112,22 +92,6 @@ export const METRIC_EVENT_SCHEMA: RootSchema = { type: 'integer', _meta: { description: 'The main event duration in ms' }, }, - status: { - type: 'keyword', - _meta: { description: 'A status', optional: true }, - }, - jsHeapSizeLimit: { - type: 'long', - _meta: { description: 'performance.memory.jsHeapSizeLimit', optional: true }, - }, - totalJSHeapSize: { - type: 'long', - _meta: { description: 'performance.memory.totalJSHeapSize', optional: true }, - }, - usedJSHeapSize: { - type: 'long', - _meta: { description: 'performance.memory.usedJSHeapSize', optional: true }, - }, key1: { type: 'keyword', _meta: { description: 'Performance metric label 1', optional: true }, diff --git a/src/core/public/core_system.test.ts b/src/core/public/core_system.test.ts index 32b51f9ec0182..f9f9f6e90afdd 100644 --- a/src/core/public/core_system.test.ts +++ b/src/core/public/core_system.test.ts @@ -325,13 +325,13 @@ describe('#start()', () => { meta: { kibana_version: '1.2.3', protocol: 'http:', + ...performanceMemory, }, key1: LOAD_START, key2: LOAD_BOOTSTRAP_START, key3: LOAD_CORE_CREATED, key4: LOAD_SETUP_DONE, key5: LOAD_START_DONE, - ...performanceMemory, value1: 111, value2: 222, value3: 333, diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 2baa95ba844f2..8e6c55008f00b 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -169,9 +169,9 @@ export class CoreSystem { meta: { kibana_version: this.coreContext.env.packageInfo.version, protocol: window.location.protocol, + ...fetchOptionalMemoryInfo(), }, duration: timing[LOAD_FIRST_NAV], - ...fetchOptionalMemoryInfo(), key1: LOAD_START, value1: timing[LOAD_START], key2: LOAD_BOOTSTRAP_START, diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts index c336dc5edafd9..ca4317cb1a9b4 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts @@ -64,12 +64,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { if (browser.isChromium) { // Kibana Loaded memory - expect(event.properties).to.have.property('jsHeapSizeLimit'); - expect(event.properties.jsHeapSizeLimit).to.be.a('number'); - expect(event.properties).to.have.property('totalJSHeapSize'); - expect(event.properties.totalJSHeapSize).to.be.a('number'); - expect(event.properties).to.have.property('usedJSHeapSize'); - expect(event.properties.usedJSHeapSize).to.be.a('number'); + expect(event.meta).to.have.property('jsHeapSizeLimit'); + expect(event.meta.jsHeapSizeLimit).to.be.a('string'); + expect(event.meta).to.have.property('totalJSHeapSize'); + expect(event.meta.totalJSHeapSize).to.be.a('string'); + expect(event.meta).to.have.property('usedJSHeapSize'); + expect(event.meta.usedJSHeapSize).to.be.a('string'); } }); }); From 7633faa78ff3fbe0ad35dc7222c0bd84cfe6a3da Mon Sep 17 00:00:00 2001 From: suchcodemuchwow Date: Fri, 29 Jul 2022 15:53:09 +0200 Subject: [PATCH 37/45] fix type errors --- .../application/embeddable/dashboard_container.tsx | 1 - .../from_the_browser/loaded_kibana.ts | 11 +---------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx index 527c90b3b48df..9f59e8637ba1c 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx @@ -169,7 +169,6 @@ export class DashboardContainer extends Container { beforeEach(async () => { @@ -62,15 +61,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(event.properties.value4).to.be.a('number'); expect(event.properties.value5).to.be.a('number'); - if (browser.isChromium) { - // Kibana Loaded memory - expect(event.meta).to.have.property('jsHeapSizeLimit'); - expect(event.meta.jsHeapSizeLimit).to.be.a('string'); - expect(event.meta).to.have.property('totalJSHeapSize'); - expect(event.meta.totalJSHeapSize).to.be.a('string'); - expect(event.meta).to.have.property('usedJSHeapSize'); - expect(event.meta.usedJSHeapSize).to.be.a('string'); - } + expect(event.properties.meta).to.be.a('unknown'); }); }); } From bfd59bcc9f2a70ff6c1ccf5656cc5e998cd8fa25 Mon Sep 17 00:00:00 2001 From: suchcodemuchwow Date: Mon, 1 Aug 2022 11:13:41 +0200 Subject: [PATCH 38/45] small fixes --- src/core/public/core_system.ts | 2 +- src/core/public/utils/index.ts | 2 +- .../from_the_browser/loaded_kibana.ts | 11 ++++++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index a9eac8cde22f5..e36b95f3c8a22 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -27,9 +27,9 @@ import { UiSettingsService } from '@kbn/core-ui-settings-browser-internal'; import { DeprecationsService } from '@kbn/core-deprecations-browser-internal'; import { IntegrationsService } from '@kbn/core-integrations-browser-internal'; import { reportPerformanceMetricEvent } from '@kbn/ebt-tools'; -import { fetchOptionalMemoryInfo } from './fetch_optional_memory_info'; import { OverlayService } from '@kbn/core-overlays-browser-internal'; import { KBN_LOAD_MARKS } from '@kbn/core-mount-utils-browser-internal'; +import { fetchOptionalMemoryInfo } from './fetch_optional_memory_info'; import { CoreSetup, CoreStart } from '.'; import { ChromeService } from './chrome'; import { NotificationsService } from './notifications'; diff --git a/src/core/public/utils/index.ts b/src/core/public/utils/index.ts index 5550b04526db9..5679153f73bac 100644 --- a/src/core/public/utils/index.ts +++ b/src/core/public/utils/index.ts @@ -10,4 +10,4 @@ export { MountWrapper, mountReactNode, KBN_LOAD_MARKS, -} from '@kbn/core-mount-utils-browser-internal'; \ No newline at end of file +} from '@kbn/core-mount-utils-browser-internal'; diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts index ba28ee2d73f80..19d8a4889bfa1 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts @@ -12,6 +12,7 @@ import { FtrProviderContext } from '../../../services'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const ebtUIHelper = getService('kibana_ebt_ui'); const { common } = getPageObjects(['common']); + const browser = getService('browser'); describe('Loaded Kibana', () => { beforeEach(async () => { @@ -61,7 +62,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(event.properties.value4).to.be.a('number'); expect(event.properties.value5).to.be.a('number'); - expect(event.properties.meta).to.be.a('unknown'); + if (browser.isChromium) { + // Kibana Loaded memory + expect(meta).to.have.property('jsHeapSizeLimit'); + expect(meta.jsHeapSizeLimit).to.be.a('string'); + expect(meta).to.have.property('totalJSHeapSize'); + expect(meta.totalJSHeapSize).to.be.a('string'); + expect(meta).to.have.property('usedJSHeapSize'); + expect(meta.usedJSHeapSize).to.be.a('string'); + } }); }); } From 9d8b950ebcee44ee339aa8bad054d6e416526d3e Mon Sep 17 00:00:00 2001 From: suchcodemuchwow Date: Mon, 1 Aug 2022 23:39:10 +0300 Subject: [PATCH 39/45] fix meta type for tests --- .../instrumented_events/from_the_browser/loaded_kibana.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts index 19d8a4889bfa1..5d9c58517c75c 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts @@ -65,11 +65,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { if (browser.isChromium) { // Kibana Loaded memory expect(meta).to.have.property('jsHeapSizeLimit'); - expect(meta.jsHeapSizeLimit).to.be.a('string'); + expect(meta.jsHeapSizeLimit).to.be.a('number'); expect(meta).to.have.property('totalJSHeapSize'); - expect(meta.totalJSHeapSize).to.be.a('string'); + expect(meta.totalJSHeapSize).to.be.a('number'); expect(meta).to.have.property('usedJSHeapSize'); - expect(meta.usedJSHeapSize).to.be.a('string'); + expect(meta.usedJSHeapSize).to.be.a('number'); } }); }); From 2d9e30f44232dcf141aa25c04ae330bc9b454567 Mon Sep 17 00:00:00 2001 From: suchcodemuchwow Date: Tue, 2 Aug 2022 01:06:37 +0300 Subject: [PATCH 40/45] remove status field --- .../instrumented_events/from_the_browser/loaded_dashboard.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts index b6dd9c752029d..0522ab5b41c2c 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_dashboard.ts @@ -40,14 +40,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const checkEmitsOnce = async (options?: GetEventsOptions) => { const events = await getEvents(Number.MAX_SAFE_INTEGER, options); - expect(events.length).to.be(1); const event = events[0]; expect(event.event_type).to.eql('performance_metric'); expect(event.properties.eventName).to.eql(DASHBOARD_LOADED_EVENT); expect(event.context.applicationId).to.be('dashboards'); expect(event.context.page).to.be('app'); expect(event.context.pageName).to.be('application:dashboards:app'); - expect(event.properties.status).to.be('done'); expect(event.properties.duration).to.be.a('number'); expect(event.properties.key1).to.eql('time_to_data'); expect(event.properties.value1).to.be.a('number'); From aef999c91bf61f8c7f8b5e72a80d1b61fdec9f46 Mon Sep 17 00:00:00 2001 From: suchcodemuchwow Date: Tue, 2 Aug 2022 14:28:00 +0300 Subject: [PATCH 41/45] fix pr comments --- .../src/analytics_service.test.ts | 2 +- .../core-analytics-browser-internal/src/analytics_service.ts | 1 - .../src/analytics_service.test.ts | 2 +- .../core-analytics-server-internal/src/analytics_service.ts | 1 - packages/kbn-ebt-tools/src/metric_events/helpers.ts | 4 ++-- packages/kbn-ebt-tools/src/metric_events/schema.ts | 2 +- .../instrumented_events/from_the_browser/loaded_kibana.ts | 2 +- 7 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts index fdc6f0dcccd61..43648e0fe1ae5 100644 --- a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts +++ b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts @@ -44,7 +44,7 @@ describe('AnalyticsService', () => { }); }); - test('should register the `metrics` and `clicks` event types on creation', () => { + test('should register the `performance_metric` and `click` event types on creation', () => { expect(analyticsClientMock.registerEventType).toHaveBeenCalledTimes(2); expect(analyticsClientMock.registerEventType.mock.calls[0]).toMatchInlineSnapshot(` Array [ diff --git a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts index 9cad35d22134d..938b0b043bc29 100644 --- a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts +++ b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.ts @@ -35,7 +35,6 @@ export class AnalyticsService { }); this.registerBuildInfoAnalyticsContext(core); - // Register special `performance_metrics` type registerPerformanceMetricEventType(this.analyticsClient); // We may eventually move the following to the client's package since they are not Kibana-specific diff --git a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts index 80dd29fba7ea4..c9ac02e54079d 100644 --- a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts +++ b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts @@ -34,7 +34,7 @@ describe('AnalyticsService', () => { `); }); - test('should register the `metrics` event type on creation', () => { + test('should register the `performance_metric` event type on creation', () => { expect(analyticsClientMock.registerEventType).toHaveBeenCalledTimes(1); expect(analyticsClientMock.registerEventType.mock.calls[0]).toMatchInlineSnapshot(` Array [ diff --git a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts index aac8048f166db..46b0726660e4c 100644 --- a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts +++ b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts @@ -30,7 +30,6 @@ export class AnalyticsService { }); this.registerBuildInfoAnalyticsContext(core); - // Register special `metrics` type registerPerformanceMetricEventType(this.analyticsClient); } diff --git a/packages/kbn-ebt-tools/src/metric_events/helpers.ts b/packages/kbn-ebt-tools/src/metric_events/helpers.ts index f332402b60cb8..6b0cb92c8f47c 100644 --- a/packages/kbn-ebt-tools/src/metric_events/helpers.ts +++ b/packages/kbn-ebt-tools/src/metric_events/helpers.ts @@ -12,7 +12,7 @@ import { type MetricEvent, METRIC_EVENT_SCHEMA } from './schema'; const PERFORMANCE_METRIC_EVENT_TYPE = 'performance_metric'; /** - * Register the `metrics` event type + * Register the `performance_metric` event type * @param analytics The {@link AnalyticsClient} during the setup phase (it has the method `registerEventType`) * @private To be called only by core's Analytics Service */ @@ -26,7 +26,7 @@ export function registerPerformanceMetricEventType( } /** - * Report a `metrics` event type. + * Report a `performance_metric` event type. * @param analytics The {@link AnalyticsClient} to report the events. * @param eventData The data to send, conforming the structure of a {@link MetricEvent}. */ diff --git a/packages/kbn-ebt-tools/src/metric_events/schema.ts b/packages/kbn-ebt-tools/src/metric_events/schema.ts index 14fd2d24c0845..0f4610447d64a 100644 --- a/packages/kbn-ebt-tools/src/metric_events/schema.ts +++ b/packages/kbn-ebt-tools/src/metric_events/schema.ts @@ -82,7 +82,7 @@ export interface MetricEvent { export const METRIC_EVENT_SCHEMA: RootSchema = { eventName: { type: 'keyword', - _meta: { description: 'Type of the event' }, + _meta: { description: 'The name of the action that is tracked in the metrics' }, }, meta: { type: 'pass_through', diff --git a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts index 5d9c58517c75c..e4ac2346b5893 100644 --- a/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts +++ b/test/analytics/tests/instrumented_events/from_the_browser/loaded_kibana.ts @@ -29,7 +29,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(event.properties.protocol).to.be.a('string'); }); - it('should emit the new kibana-loaded events', async () => { + it('should emit the kibana_loaded event', async () => { const [event] = await ebtUIHelper.getEvents(1, { eventTypes: ['performance_metric'], filters: { 'properties.eventName': { eq: 'kibana_loaded' } }, From e3efd40820f55ac69cf2ed7c97918dbd9edd23d1 Mon Sep 17 00:00:00 2001 From: suchcodemuchwow Date: Tue, 2 Aug 2022 15:02:23 +0300 Subject: [PATCH 42/45] update eventName comment for MetricEvent --- packages/kbn-ebt-tools/src/metric_events/schema.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/kbn-ebt-tools/src/metric_events/schema.ts b/packages/kbn-ebt-tools/src/metric_events/schema.ts index 0f4610447d64a..bb7a1f34b5826 100644 --- a/packages/kbn-ebt-tools/src/metric_events/schema.ts +++ b/packages/kbn-ebt-tools/src/metric_events/schema.ts @@ -13,7 +13,7 @@ import type { RootSchema } from '@kbn/analytics-client'; */ export interface MetricEvent { /** - * The name of the action that is tracked in the metrics. + * The name of the event that is tracked in the metrics i.e. kibana_loaded, kibana_started */ eventName: string; /** @@ -82,7 +82,10 @@ export interface MetricEvent { export const METRIC_EVENT_SCHEMA: RootSchema = { eventName: { type: 'keyword', - _meta: { description: 'The name of the action that is tracked in the metrics' }, + _meta: { + description: + 'The name of the event that is tracked in the metrics i.e. kibana_loaded, kibana_started', + }, }, meta: { type: 'pass_through', From 9f46d83f92d51ef8ca5cc26532feb94ccb2d8133 Mon Sep 17 00:00:00 2001 From: suchcodemuchwow Date: Tue, 2 Aug 2022 16:17:24 +0300 Subject: [PATCH 43/45] update event name test snapshot --- .../src/analytics_service.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts index 43648e0fe1ae5..9c438f2589663 100644 --- a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts +++ b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts @@ -59,7 +59,7 @@ describe('AnalyticsService', () => { }, "eventName": Object { "_meta": Object { - "description": "Type of the event", + "description": "The name of the event that is tracked in the metrics i.e. kibana_loaded, kibana_started", }, "type": "keyword", }, From 4c0e8831b5e8ee6056029b08d69501ba220f38ae Mon Sep 17 00:00:00 2001 From: suchcodemuchwow Date: Tue, 2 Aug 2022 17:13:03 +0300 Subject: [PATCH 44/45] update event name test snapshot for server --- .../src/analytics_service.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts index c9ac02e54079d..2609859ae9d8c 100644 --- a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts +++ b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts @@ -49,7 +49,7 @@ describe('AnalyticsService', () => { }, "eventName": Object { "_meta": Object { - "description": "Type of the event", + "description": "The name of the event that is tracked in the metrics i.e. kibana_loaded, kibana_started", }, "type": "keyword", }, From 8068f99696e040f8080016c4b2f88b0903eadac8 Mon Sep 17 00:00:00 2001 From: suchcodemuchwow Date: Wed, 3 Aug 2022 14:14:32 +0300 Subject: [PATCH 45/45] fix pr comments --- .../src/analytics_service.test.ts | 10 +++++----- packages/kbn-ebt-tools/src/index.ts | 2 +- .../helpers.test.ts | 4 ++-- .../helpers.ts | 6 +++--- .../index.ts | 2 +- .../schema.ts | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) rename packages/kbn-ebt-tools/src/{metric_events => performance_metric_events}/helpers.test.ts (96%) rename packages/kbn-ebt-tools/src/{metric_events => performance_metric_events}/helpers.ts (88%) rename packages/kbn-ebt-tools/src/{metric_events => performance_metric_events}/index.ts (87%) rename packages/kbn-ebt-tools/src/{metric_events => performance_metric_events}/schema.ts (97%) diff --git a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts index 9c438f2589663..d3514cb80edf3 100644 --- a/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts +++ b/packages/core/analytics/core-analytics-browser-internal/src/analytics_service.test.ts @@ -20,7 +20,7 @@ describe('AnalyticsService', () => { }); test('should register some context providers on creation', async () => { expect(analyticsClientMock.registerContextProvider).toHaveBeenCalledTimes(3); - await expect( + expect( await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[0][0].context$) ).toMatchInlineSnapshot(` Object { @@ -32,10 +32,10 @@ describe('AnalyticsService', () => { "version": "version", } `); - await expect( + expect( await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[1][0].context$) ).toEqual({ session_id: expect.any(String) }); - await expect( + expect( await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[2][0].context$) ).toEqual({ preferred_language: 'en-US', @@ -180,7 +180,7 @@ describe('AnalyticsService', () => { test('setup should register the elasticsearch info context provider (undefined)', async () => { const injectedMetadata = injectedMetadataServiceMock.createSetupContract(); analyticsService.setup({ injectedMetadata }); - await expect( + expect( await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[3][0].context$) ).toMatchInlineSnapshot(`undefined`); }); @@ -193,7 +193,7 @@ describe('AnalyticsService', () => { cluster_version: 'version', }); analyticsService.setup({ injectedMetadata }); - await expect( + expect( await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[3][0].context$) ).toMatchInlineSnapshot(` Object { diff --git a/packages/kbn-ebt-tools/src/index.ts b/packages/kbn-ebt-tools/src/index.ts index 334913623b12a..9357513d40f55 100644 --- a/packages/kbn-ebt-tools/src/index.ts +++ b/packages/kbn-ebt-tools/src/index.ts @@ -6,4 +6,4 @@ * Side Public License, v 1. */ -export * from './metric_events'; +export * from './performance_metric_events'; diff --git a/packages/kbn-ebt-tools/src/metric_events/helpers.test.ts b/packages/kbn-ebt-tools/src/performance_metric_events/helpers.test.ts similarity index 96% rename from packages/kbn-ebt-tools/src/metric_events/helpers.test.ts rename to packages/kbn-ebt-tools/src/performance_metric_events/helpers.test.ts index a1048849809ae..a6ad3970a6a97 100644 --- a/packages/kbn-ebt-tools/src/metric_events/helpers.test.ts +++ b/packages/kbn-ebt-tools/src/performance_metric_events/helpers.test.ts @@ -11,7 +11,7 @@ import { loggerMock } from '@kbn/logging-mocks'; import { registerPerformanceMetricEventType, reportPerformanceMetricEvent } from './helpers'; import { METRIC_EVENT_SCHEMA } from './schema'; -describe('metric event helpers', () => { +describe('performance metric event helpers', () => { let analyticsClient: AnalyticsClient; describe('registerPerformanceMetricEventType', () => { @@ -67,7 +67,7 @@ describe('metric event helpers', () => { }); }); - test('should fail if eventName is missing', () => { + test('should fail if eventName and duration is missing', () => { expect(() => reportPerformanceMetricEvent( analyticsClient, diff --git a/packages/kbn-ebt-tools/src/metric_events/helpers.ts b/packages/kbn-ebt-tools/src/performance_metric_events/helpers.ts similarity index 88% rename from packages/kbn-ebt-tools/src/metric_events/helpers.ts rename to packages/kbn-ebt-tools/src/performance_metric_events/helpers.ts index 6b0cb92c8f47c..ed971118687c3 100644 --- a/packages/kbn-ebt-tools/src/metric_events/helpers.ts +++ b/packages/kbn-ebt-tools/src/performance_metric_events/helpers.ts @@ -7,7 +7,7 @@ */ import type { AnalyticsClient } from '@kbn/analytics-client'; -import { type MetricEvent, METRIC_EVENT_SCHEMA } from './schema'; +import { type PerformanceMetricEvent, METRIC_EVENT_SCHEMA } from './schema'; const PERFORMANCE_METRIC_EVENT_TYPE = 'performance_metric'; @@ -19,7 +19,7 @@ const PERFORMANCE_METRIC_EVENT_TYPE = 'performance_metric'; export function registerPerformanceMetricEventType( analytics: Pick ) { - analytics.registerEventType({ + analytics.registerEventType({ eventType: PERFORMANCE_METRIC_EVENT_TYPE, schema: METRIC_EVENT_SCHEMA, }); @@ -32,7 +32,7 @@ export function registerPerformanceMetricEventType( */ export function reportPerformanceMetricEvent( analytics: Pick, - eventData: MetricEvent + eventData: PerformanceMetricEvent ) { analytics.reportEvent(PERFORMANCE_METRIC_EVENT_TYPE, eventData); } diff --git a/packages/kbn-ebt-tools/src/metric_events/index.ts b/packages/kbn-ebt-tools/src/performance_metric_events/index.ts similarity index 87% rename from packages/kbn-ebt-tools/src/metric_events/index.ts rename to packages/kbn-ebt-tools/src/performance_metric_events/index.ts index 95bbfeb2dad19..0002b082754dd 100644 --- a/packages/kbn-ebt-tools/src/metric_events/index.ts +++ b/packages/kbn-ebt-tools/src/performance_metric_events/index.ts @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -export type { MetricEvent } from './schema'; +export type { PerformanceMetricEvent as MetricEvent } from './schema'; export { registerPerformanceMetricEventType as registerPerformanceMetricEventType, reportPerformanceMetricEvent, diff --git a/packages/kbn-ebt-tools/src/metric_events/schema.ts b/packages/kbn-ebt-tools/src/performance_metric_events/schema.ts similarity index 97% rename from packages/kbn-ebt-tools/src/metric_events/schema.ts rename to packages/kbn-ebt-tools/src/performance_metric_events/schema.ts index bb7a1f34b5826..ed0b3a8eefde5 100644 --- a/packages/kbn-ebt-tools/src/metric_events/schema.ts +++ b/packages/kbn-ebt-tools/src/performance_metric_events/schema.ts @@ -11,7 +11,7 @@ import type { RootSchema } from '@kbn/analytics-client'; /** * Structure of the `metric` event */ -export interface MetricEvent { +export interface PerformanceMetricEvent { /** * The name of the event that is tracked in the metrics i.e. kibana_loaded, kibana_started */ @@ -79,7 +79,7 @@ export interface MetricEvent { value5?: number; } -export const METRIC_EVENT_SCHEMA: RootSchema = { +export const METRIC_EVENT_SCHEMA: RootSchema = { eventName: { type: 'keyword', _meta: {