[Infra] Optimize infra's initial load bundles (#191948)

closes https://github.com/elastic/kibana/issues/191628

## Summary

Improves the initial infra bundle size from ~100kb to ~54kb (~46%) by
lazy loading the inventory and metrics view services

| Before  | After |
| ------------- | ------------- |
|<img width="600" alt="image"
src="https://github.com/user-attachments/assets/76fc4fdc-a2b7-46d3-8ad9-6599a2471250">|
<img width="600" alt="image"
src="https://github.com/user-attachments/assets/90610f76-267f-4f7b-9510-b3204c261db4">|
| <img width="600" alt="image"
src="https://github.com/user-attachments/assets/65513bcc-ec20-4b6e-87ef-376b6dde84d0">|<img
width="600" alt="image"
src="https://github.com/user-attachments/assets/bacb0416-0cfd-4a2f-9239-159ec4ccf920">

In addition to that, Infra routes were split into chunks

---------

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Carlos Crespo 2024-09-05 23:16:00 +02:00 committed by GitHub
parent 57ae12ccae
commit 252352c673
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 124 additions and 310 deletions

View file

@ -148,7 +148,6 @@ export const applicationUsageSchema = {
graph: commonSchema,
logs: commonSchema,
metrics: commonSchema,
infra: commonSchema, // It's a forward app so we'll likely never report it
fleet: commonSchema,
integrations: commonSchema,
ingestManager: commonSchema,

View file

@ -3801,137 +3801,6 @@
}
}
},
"infra": {
"properties": {
"appId": {
"type": "keyword",
"_meta": {
"description": "The application being tracked"
}
},
"viewId": {
"type": "keyword",
"_meta": {
"description": "Always `main`"
}
},
"clicks_total": {
"type": "long",
"_meta": {
"description": "General number of clicks in the application since we started counting them"
}
},
"clicks_7_days": {
"type": "long",
"_meta": {
"description": "General number of clicks in the application over the last 7 days"
}
},
"clicks_30_days": {
"type": "long",
"_meta": {
"description": "General number of clicks in the application over the last 30 days"
}
},
"clicks_90_days": {
"type": "long",
"_meta": {
"description": "General number of clicks in the application over the last 90 days"
}
},
"minutes_on_screen_total": {
"type": "float",
"_meta": {
"description": "Minutes the application is active and on-screen since we started counting them."
}
},
"minutes_on_screen_7_days": {
"type": "float",
"_meta": {
"description": "Minutes the application is active and on-screen over the last 7 days"
}
},
"minutes_on_screen_30_days": {
"type": "float",
"_meta": {
"description": "Minutes the application is active and on-screen over the last 30 days"
}
},
"minutes_on_screen_90_days": {
"type": "float",
"_meta": {
"description": "Minutes the application is active and on-screen over the last 90 days"
}
},
"views": {
"type": "array",
"items": {
"properties": {
"appId": {
"type": "keyword",
"_meta": {
"description": "The application being tracked"
}
},
"viewId": {
"type": "keyword",
"_meta": {
"description": "The application view being tracked"
}
},
"clicks_total": {
"type": "long",
"_meta": {
"description": "General number of clicks in the application sub view since we started counting them"
}
},
"clicks_7_days": {
"type": "long",
"_meta": {
"description": "General number of clicks in the active application sub view over the last 7 days"
}
},
"clicks_30_days": {
"type": "long",
"_meta": {
"description": "General number of clicks in the active application sub view over the last 30 days"
}
},
"clicks_90_days": {
"type": "long",
"_meta": {
"description": "General number of clicks in the active application sub view over the last 90 days"
}
},
"minutes_on_screen_total": {
"type": "float",
"_meta": {
"description": "Minutes the application sub view is active and on-screen since we started counting them."
}
},
"minutes_on_screen_7_days": {
"type": "float",
"_meta": {
"description": "Minutes the application is active and on-screen active application sub view over the last 7 days"
}
},
"minutes_on_screen_30_days": {
"type": "float",
"_meta": {
"description": "Minutes the application is active and on-screen active application sub view over the last 30 days"
}
},
"minutes_on_screen_90_days": {
"type": "float",
"_meta": {
"description": "Minutes the application is active and on-screen active application sub view over the last 90 days"
}
}
}
}
}
}
},
"fleet": {
"properties": {
"appId": {

View file

@ -1,98 +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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
import { createBrowserHistory, History } from 'history';
import { AppMountParameters, CoreStart } from '@kbn/core/public';
import React from 'react';
import ReactDOM from 'react-dom';
import { RouteProps } from 'react-router-dom';
import { Router, Routes, Route } from '@kbn/shared-ux-router';
// This exists purely to facilitate legacy app/infra URL redirects.
// It will be removed in 8.0.0.
export async function renderApp(core: CoreStart, { element }: AppMountParameters) {
const history = createBrowserHistory();
ReactDOM.render(
<KibanaRenderContextProvider {...core}>
<LegacyApp history={history} />
</KibanaRenderContextProvider>,
element
);
return () => {
ReactDOM.unmountComponentAtNode(element);
};
}
const LegacyApp: React.FunctionComponent<{ history: History<unknown> }> = ({ history }) => {
return (
<Router history={history}>
<Routes>
<Route
path={'/'}
render={({ location }: RouteProps) => {
if (!location) {
return null;
}
let nextPath = '';
let nextBasePath = '';
let nextSearch;
if (
location.hash.indexOf('#infrastructure') > -1 ||
location.hash.indexOf('#/infrastructure') > -1
) {
nextPath = location.hash.replace(
new RegExp(
'#infrastructure/|#/infrastructure/|#/infrastructure|#infrastructure',
'g'
),
''
);
nextBasePath = location.pathname.replace('app/infra', 'app/metrics');
} else if (
location.hash.indexOf('#logs') > -1 ||
location.hash.indexOf('#/logs') > -1
) {
nextPath = location.hash.replace(new RegExp('#logs/|#/logs/|#/logs|#logs', 'g'), '');
nextBasePath = location.pathname.replace('app/infra', 'app/logs');
} else {
// This covers /app/infra and /app/infra/home (both of which used to render
// the metrics inventory page)
nextPath = 'inventory';
nextBasePath = location.pathname.replace('app/infra', 'app/metrics');
nextSearch = undefined;
}
// app/infra#infrastructure/metrics/:type/:node was changed to app/metrics/detail/:type/:node, this
// accounts for that edge case
nextPath = nextPath.replace('metrics/', 'detail/');
// Query parameters (location.search) will arrive as part of location.hash and not location.search
const nextPathParts = nextPath.split('?');
nextPath = nextPathParts[0];
nextSearch = nextPathParts[1] ? nextPathParts[1] : undefined;
const builtPathname = `${nextBasePath}/${nextPath}`;
const builtSearch = nextSearch ? `?${nextSearch}` : '';
let nextUrl = `${builtPathname}${builtSearch}`;
nextUrl = nextUrl.replace('//', '/');
window.location.href = nextUrl;
return null;
}}
/>
</Routes>
</Router>
);
};

View file

@ -124,11 +124,9 @@ export function Dashboards() {
}
}, [
allAvailableDashboards,
asset.type,
currentDashboard?.dashboardSavedObjectId,
dashboards,
setUrlState,
telemetry,
urlState?.dashboardId,
]);

View file

@ -45,7 +45,7 @@ export const useSourceFetcher = ({ sourceId }: { sourceId: string }) => {
method: 'GET',
}
);
telemetry?.reportPerformanceMetricEvent(
telemetry.reportPerformanceMetricEvent(
'infra_source_load',
performance.now() - start,
{},

View file

@ -8,10 +8,8 @@ import * as rt from 'io-ts';
import { pipe } from 'fp-ts/lib/pipeable';
import { fold } from 'fp-ts/lib/Either';
import { constant, identity } from 'fp-ts/lib/function';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useUiTracker } from '@kbn/observability-shared-plugin/public';
import {
MutationContext,
SavedViewResult,
@ -67,7 +65,10 @@ export const useInventoryViews = (): UseInventoryViewsResult => {
isFetching: isFetchingViews,
} = useQuery({
queryKey: queryKeys.find,
queryFn: () => inventoryViews.client.findInventoryViews(),
queryFn: async () => {
const client = await inventoryViews.getClient();
return client.findInventoryViews();
},
enabled: false, // We will manually fetch the list when necessary
placeholderData: [], // Use a default empty array instead of undefined
onError: (error: ServerError) => notify.getViewFailure(error.body?.message ?? error.message),
@ -79,7 +80,10 @@ export const useInventoryViews = (): UseInventoryViewsResult => {
const { data: currentView, isFetching: isFetchingCurrentView } = useQuery({
queryKey: queryKeys.getById(currentViewId),
queryFn: ({ queryKey: [, id] }) => inventoryViews.client.getInventoryView(id),
queryFn: async ({ queryKey: [, id] }) => {
const client = await inventoryViews.getClient();
return client.getInventoryView(id);
},
onError: (error: ServerError) => {
notify.getViewFailure(error.body?.message ?? error.message);
switchViewById(defaultViewId);
@ -123,7 +127,10 @@ export const useInventoryViews = (): UseInventoryViewsResult => {
ServerError,
CreateInventoryViewAttributesRequestPayload
>({
mutationFn: (attributes) => inventoryViews.client.createInventoryView(attributes),
mutationFn: async (attributes) => {
const client = await inventoryViews.getClient();
return client.createInventoryView(attributes);
},
onError: (error) => {
notify.upsertViewFailure(error.body?.message ?? error.message);
},
@ -138,7 +145,10 @@ export const useInventoryViews = (): UseInventoryViewsResult => {
ServerError,
UpdateViewParams<UpdateInventoryViewAttributesRequestPayload>
>({
mutationFn: ({ id, attributes }) => inventoryViews.client.updateInventoryView(id, attributes),
mutationFn: async ({ id, attributes }) => {
const client = await inventoryViews.getClient();
return client.updateInventoryView(id, attributes);
},
onError: (error) => {
notify.upsertViewFailure(error.body?.message ?? error.message);
},
@ -153,7 +163,10 @@ export const useInventoryViews = (): UseInventoryViewsResult => {
string,
MutationContext<InventoryView>
>({
mutationFn: (id: string) => inventoryViews.client.deleteInventoryView(id),
mutationFn: async (id: string) => {
const client = await inventoryViews.getClient();
return client.deleteInventoryView(id);
},
/**
* To provide a quick feedback, we perform an optimistic update on the list
* when deleting a view.

View file

@ -8,7 +8,6 @@ import * as rt from 'io-ts';
import { pipe } from 'fp-ts/lib/pipeable';
import { fold } from 'fp-ts/lib/Either';
import { constant, identity } from 'fp-ts/lib/function';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useUiTracker } from '@kbn/observability-shared-plugin/public';
@ -72,7 +71,10 @@ export const useMetricsExplorerViews = (): UseMetricsExplorerViewsResult => {
isFetching: isFetchingViews,
} = useQuery({
queryKey: queryKeys.find,
queryFn: () => metricsExplorerViews.client.findMetricsExplorerViews(),
queryFn: async () => {
const client = await metricsExplorerViews.getClient();
return client.findMetricsExplorerViews();
},
enabled: false, // We will manually fetch the list when necessary
placeholderData: [], // Use a default empty array instead of undefined
onError: (error: ServerError) => notify.getViewFailure(error.body?.message ?? error.message),
@ -84,7 +86,10 @@ export const useMetricsExplorerViews = (): UseMetricsExplorerViewsResult => {
const { data: currentView, isFetching: isFetchingCurrentView } = useQuery({
queryKey: queryKeys.getById(currentViewId),
queryFn: ({ queryKey: [, id] }) => metricsExplorerViews.client.getMetricsExplorerView(id),
queryFn: async ({ queryKey: [, id] }) => {
const client = await metricsExplorerViews.getClient();
return client.getMetricsExplorerView(id);
},
onError: (error: ServerError) => {
notify.getViewFailure(error.body?.message ?? error.message);
switchViewById(defaultViewId);
@ -128,7 +133,10 @@ export const useMetricsExplorerViews = (): UseMetricsExplorerViewsResult => {
ServerError,
CreateMetricsExplorerViewAttributesRequestPayload
>({
mutationFn: (attributes) => metricsExplorerViews.client.createMetricsExplorerView(attributes),
mutationFn: async (attributes) => {
const client = await metricsExplorerViews.getClient();
return client.createMetricsExplorerView(attributes);
},
onError: (error) => {
notify.upsertViewFailure(error.body?.message ?? error.message);
},
@ -143,8 +151,10 @@ export const useMetricsExplorerViews = (): UseMetricsExplorerViewsResult => {
ServerError,
UpdateViewParams<UpdateMetricsExplorerViewAttributesRequestPayload>
>({
mutationFn: ({ id, attributes }) =>
metricsExplorerViews.client.updateMetricsExplorerView(id, attributes),
mutationFn: async ({ id, attributes }) => {
const client = await metricsExplorerViews.getClient();
return client.updateMetricsExplorerView(id, attributes);
},
onError: (error) => {
notify.upsertViewFailure(error.body?.message ?? error.message);
},
@ -159,7 +169,10 @@ export const useMetricsExplorerViews = (): UseMetricsExplorerViewsResult => {
string,
MutationContext<MetricsExplorerView>
>({
mutationFn: (id: string) => metricsExplorerViews.client.deleteMetricsExplorerView(id),
mutationFn: async (id: string) => {
const client = await metricsExplorerViews.getClient();
return client.deleteMetricsExplorerView(id);
},
/**
* To provide a quick feedback, we perform an optimistic update on the list
* when deleting a view.

View file

@ -23,8 +23,5 @@ export const plugin: PluginInitializer<
return new Plugin(context);
};
export { FORMATTERS } from '../common/formatters';
export { InfraFormatterType } from './common/inventory/types';
// Shared components
export type { InfraClientStartExports } from './types';

View file

@ -16,6 +16,7 @@ import {
ObservabilityOnboardingLocatorParams,
OBSERVABILITY_ONBOARDING_LOCATOR,
} from '@kbn/deeplinks-observability';
import { dynamic } from '@kbn/shared-ux-utility';
import { LazyAlertDropdownWrapper } from '../../alerting/log_threshold';
import { HelpCenterContent } from '../../components/help_center_content';
import { useReadOnlyBadge } from '../../hooks/use_readonly_badge';
@ -26,9 +27,14 @@ import { LogEntryRatePage } from './log_entry_rate';
import { LogsSettingsPage } from './settings';
import { StreamPage } from './stream';
import { isDevMode } from '../../utils/dev_mode';
import { StateMachinePlayground } from '../../observability_logs/xstate_helpers';
import { NotFoundPage } from '../404';
const StateMachinePlayground = dynamic(() =>
import('../../observability_logs/xstate_helpers').then((mod) => ({
default: mod.StateMachinePlayground,
}))
);
export const LogsPageContent: React.FunctionComponent = () => {
const { application, share } = useKibana<{ share: SharePublicStart }>().services;
const uiCapabilities = application?.capabilities;

View file

@ -66,7 +66,7 @@ export const useHostsView = () => {
}
);
const duration = performance.now() - start;
telemetry?.reportPerformanceMetricEvent(
telemetry.reportPerformanceMetricEvent(
'infra_hosts_table_load',
duration,
{ key1: 'data_load', value1: duration },

View file

@ -25,11 +25,9 @@ import {
ObservabilityOnboardingLocatorParams,
OBSERVABILITY_ONBOARDING_LOCATOR,
} from '@kbn/deeplinks-observability';
import { dynamic } from '@kbn/shared-ux-utility';
import { HelpCenterContent } from '../../components/help_center_content';
import { useReadOnlyBadge } from '../../hooks/use_readonly_badge';
import { MetricsExplorerPage } from './metrics_explorer';
import { SnapshotPage } from './inventory_view';
import { NodeDetail } from './metric_detail';
import { MetricsSettingsPage } from './settings';
import { MetricsAlertDropdown } from '../../alerting/common/components/metrics_alert_dropdown';
import { AlertPrefillProvider } from '../../alerting/use_alert_prefill';
@ -39,7 +37,6 @@ import { HeaderActionMenuContext } from '../../containers/header_action_menu_pro
import { NotFoundPage } from '../404';
import { ReactQueryProvider } from '../../containers/react_query_provider';
import { usePluginConfig } from '../../containers/plugin_config_context';
import { HostsPage } from './hosts';
import { RedirectWithQueryParams } from '../../utils/redirect_with_query_params';
import { SearchSessionProvider } from '../../hooks/use_search_session';
import { OnboardingFlow } from '../../components/shared/templates/no_data_config';
@ -48,6 +45,17 @@ const ADD_DATA_LABEL = i18n.translate('xpack.infra.metricsHeaderAddDataButtonLab
defaultMessage: 'Add data',
});
const MetricsExplorerPage = dynamic(() =>
import('./metrics_explorer').then((mod) => ({ default: mod.MetricsExplorerPage }))
);
const SnapshotPage = dynamic(() =>
import('./inventory_view').then((mod) => ({ default: mod.SnapshotPage }))
);
const NodeDetail = dynamic(() =>
import('./metric_detail').then((mod) => ({ default: mod.NodeDetail }))
);
const HostsPage = dynamic(() => import('./hosts').then((mod) => ({ default: mod.HostsPage })));
export const InfrastructurePage = () => {
const config = usePluginConfig();
const { application } = useKibana<{ share: SharePublicStart }>().services;

View file

@ -350,21 +350,6 @@ export class Plugin implements InfraClientPluginClass {
},
});
/* This exists purely to facilitate URL redirects from the old App ID ("infra"),
to our new App IDs ("metrics" and "logs"). With version 8.0.0 we can remove this. */
core.application.register({
id: 'infra',
appRoute: '/app/infra',
title: 'infra',
visibleIn: [],
mount: async (params: AppMountParameters) => {
const [coreStart] = await core.getStartServices();
const { renderApp } = await import('./apps/legacy_app');
return renderApp(coreStart, params);
},
});
startDep$AndHostViewFlag$.subscribe(
([_startServices, isInfrastructureHostsViewEnabled]: [
[CoreStart, InfraClientStartDeps, InfraClientStartExports],
@ -385,14 +370,9 @@ export class Plugin implements InfraClientPluginClass {
}
start(core: InfraClientCoreStart, plugins: InfraClientStartDeps) {
const inventoryViews = this.inventoryViews.start({
http: core.http,
});
const metricsExplorerViews = this.metricsExplorerViews?.start({
http: core.http,
});
const { http } = core;
const inventoryViews = this.inventoryViews.start({ http });
const metricsExplorerViews = this.metricsExplorerViews?.start({ http });
const telemetry = this.telemetry.start();
plugins.uiActions.registerAction<EmbeddableApiContext>({

View file

@ -5,6 +5,5 @@
* 2.0.
*/
export * from './inventory_views_client';
export * from './inventory_views_service';
export * from './types';

View file

@ -9,7 +9,7 @@ import { createInventoryViewsClientMock } from './inventory_views_client.mock';
import { InventoryViewsServiceStart } from './types';
export const createInventoryViewsServiceStartMock = () => ({
client: createInventoryViewsClientMock(),
getClient: () => Promise.resolve(createInventoryViewsClientMock()),
});
export const _ensureTypeCompatibility = (): InventoryViewsServiceStart =>

View file

@ -5,21 +5,33 @@
* 2.0.
*/
import { InventoryViewsClient } from './inventory_views_client';
import {
import type {
InventoryViewsServiceStartDeps,
InventoryViewsServiceSetup,
InventoryViewsServiceStart,
IInventoryViewsClient,
} from './types';
export class InventoryViewsService {
public setup(): InventoryViewsServiceSetup {}
private client?: IInventoryViewsClient;
public setup(): InventoryViewsServiceSetup {
return {};
}
public start({ http }: InventoryViewsServiceStartDeps): InventoryViewsServiceStart {
const client = new InventoryViewsClient(http);
return {
client,
getClient: () => this.getClient({ http }),
};
}
private async getClient({ http }: InventoryViewsServiceStartDeps) {
if (!this.client) {
const { InventoryViewsClient } = await import('./inventory_views_client');
const client = new InventoryViewsClient(http);
this.client = client;
}
return this.client;
}
}

View file

@ -5,8 +5,8 @@
* 2.0.
*/
import { HttpStart } from '@kbn/core/public';
import {
import type { HttpStart } from '@kbn/core/public';
import type {
CreateInventoryViewAttributesRequestPayload,
CreateInventoryViewResponsePayload,
FindInventoryViewResponsePayload,
@ -15,10 +15,11 @@ import {
UpdateInventoryViewResponsePayload,
} from '../../../common/http_api/latest';
export type InventoryViewsServiceSetup = void;
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface InventoryViewsServiceSetup {}
export interface InventoryViewsServiceStart {
client: IInventoryViewsClient;
getClient: () => Promise<IInventoryViewsClient>;
}
export interface InventoryViewsServiceStartDeps {

View file

@ -5,6 +5,5 @@
* 2.0.
*/
export * from './metrics_explorer_views_client';
export * from './metrics_explorer_views_service';
export * from './types';

View file

@ -9,7 +9,7 @@ import { createMetricsExplorerViewsClientMock } from './metrics_explorer_views_c
import { MetricsExplorerViewsServiceStart } from './types';
export const createMetricsExplorerViewsServiceStartMock = () => ({
client: createMetricsExplorerViewsClientMock(),
getClient: () => Promise.resolve(createMetricsExplorerViewsClientMock()),
});
export const _ensureTypeCompatibility = (): MetricsExplorerViewsServiceStart =>

View file

@ -5,21 +5,33 @@
* 2.0.
*/
import { MetricsExplorerViewsClient } from './metrics_explorer_views_client';
import {
import type {
MetricsExplorerViewsServiceStartDeps,
MetricsExplorerViewsServiceSetup,
MetricsExplorerViewsServiceStart,
IMetricsExplorerViewsClient,
} from './types';
export class MetricsExplorerViewsService {
public setup(): MetricsExplorerViewsServiceSetup {}
private client?: IMetricsExplorerViewsClient;
public setup(): MetricsExplorerViewsServiceSetup {
return {};
}
public start({ http }: MetricsExplorerViewsServiceStartDeps): MetricsExplorerViewsServiceStart {
const client = new MetricsExplorerViewsClient(http);
return {
client,
getClient: () => this.getClient({ http }),
};
}
private async getClient({ http }: MetricsExplorerViewsServiceStartDeps) {
if (!this.client) {
const { MetricsExplorerViewsClient } = await import('./metrics_explorer_views_client');
const client = new MetricsExplorerViewsClient(http);
this.client = client;
}
return this.client;
}
}

View file

@ -5,19 +5,20 @@
* 2.0.
*/
import { HttpStart } from '@kbn/core/public';
import {
import type { HttpStart } from '@kbn/core/public';
import type {
FindMetricsExplorerViewResponsePayload,
CreateMetricsExplorerViewResponsePayload,
UpdateMetricsExplorerViewResponsePayload,
GetMetricsExplorerViewResponsePayload,
} from '../../../common/http_api';
import { MetricsExplorerViewAttributes } from '../../../common/metrics_explorer_views';
import type { MetricsExplorerViewAttributes } from '../../../common/metrics_explorer_views';
export type MetricsExplorerViewsServiceSetup = void;
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface MetricsExplorerViewsServiceSetup {}
export interface MetricsExplorerViewsServiceStart {
client: IMetricsExplorerViewsClient;
getClient: () => Promise<IMetricsExplorerViewsClient>;
}
export interface MetricsExplorerViewsServiceStartDeps {

View file

@ -4,8 +4,12 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { AnalyticsServiceSetup } from '@kbn/core-analytics-browser';
import { TelemetryServiceSetupParams, ITelemetryClient, InfraTelemetryEventParams } from './types';
import type { AnalyticsServiceSetup } from '@kbn/core-analytics-browser';
import type {
TelemetryServiceSetupParams,
TelemetryServiceStart,
InfraTelemetryEventParams,
} from './types';
import { infraTelemetryEvents } from './telemetry_events';
import { TelemetryClient } from './telemetry_client';
@ -23,7 +27,7 @@ export class TelemetryService {
);
}
public start(): ITelemetryClient {
public start(): TelemetryServiceStart {
if (!this.analytics) {
throw new Error(
'The TelemetryService.setup() method has not been invoked, be sure to call it during the plugin setup.'

View file

@ -11,6 +11,8 @@ export interface TelemetryServiceSetupParams {
analytics: AnalyticsServiceSetup;
}
export type TelemetryServiceStart = ITelemetryClient;
export enum InfraTelemetryEventTypes {
HOSTS_VIEW_QUERY_SUBMITTED = 'Hosts View Query Submitted',
HOSTS_ENTRY_CLICKED = 'Host Entry Clicked',

View file

@ -53,7 +53,7 @@ import { LogsDataAccessPluginStart } from '@kbn/logs-data-access-plugin/public';
import type { UnwrapPromise } from '../common/utility_types';
import { InventoryViewsServiceStart } from './services/inventory_views';
import { MetricsExplorerViewsServiceStart } from './services/metrics_explorer_views';
import { ITelemetryClient } from './services/telemetry';
import { TelemetryServiceStart } from './services/telemetry';
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface InfraClientSetupExports {}
@ -61,7 +61,7 @@ export interface InfraClientSetupExports {}
export interface InfraClientStartExports {
inventoryViews: InventoryViewsServiceStart;
metricsExplorerViews?: MetricsExplorerViewsServiceStart;
telemetry: ITelemetryClient;
telemetry: TelemetryServiceStart;
}
export interface InfraClientSetupDeps {
@ -106,7 +106,6 @@ export interface InfraClientStartDeps {
uiActions: UiActionsStart;
unifiedSearch: UnifiedSearchPublicPluginStart;
usageCollection: UsageCollectionStart;
telemetry?: ITelemetryClient;
fieldFormats: FieldFormatsStart;
licensing: LicensingPluginStart;
licenseManagement?: LicenseManagementUIPluginSetup;