mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 11:05:39 -04:00
[ML] Adding job import export usage telemetry collection (#107772)
* [ML] Adding job import export usage telemtry collection * removing accidental managemet type change * adding tests * changes based on review * adding constant for event ids * adding toHaveBeenCalledWith tests * renaming tests Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
91366f0221
commit
f074091ef1
11 changed files with 183 additions and 33 deletions
15
x-pack/plugins/ml/common/constants/usage_collection.ts
Normal file
15
x-pack/plugins/ml/common/constants/usage_collection.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const ML_USAGE_EVENT = {
|
||||||
|
IMPORTED_ANOMALY_DETECTOR_JOBS: 'imported_anomaly_detector_jobs',
|
||||||
|
IMPORTED_DATA_FRAME_ANALYTICS_JOBS: 'imported_data_frame_analytics_jobs',
|
||||||
|
EXPORTED_ANOMALY_DETECTOR_JOBS: 'exported_anomaly_detector_jobs',
|
||||||
|
EXPORTED_DATA_FRAME_ANALYTICS_JOBS: 'exported_data_frame_analytics_jobs',
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type MlUsageEvent = typeof ML_USAGE_EVENT[keyof typeof ML_USAGE_EVENT];
|
|
@ -11,6 +11,7 @@ import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
import { AppMountParameters, CoreStart, HttpStart } from 'kibana/public';
|
import { AppMountParameters, CoreStart, HttpStart } from 'kibana/public';
|
||||||
|
|
||||||
|
import type { UsageCollectionSetup } from 'src/plugins/usage_collection/public';
|
||||||
import { Storage } from '../../../../../src/plugins/kibana_utils/public';
|
import { Storage } from '../../../../../src/plugins/kibana_utils/public';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -19,7 +20,8 @@ import {
|
||||||
} from '../../../../../src/plugins/kibana_react/public';
|
} from '../../../../../src/plugins/kibana_react/public';
|
||||||
import { setDependencyCache, clearCache } from './util/dependency_cache';
|
import { setDependencyCache, clearCache } from './util/dependency_cache';
|
||||||
import { setLicenseCache } from './license';
|
import { setLicenseCache } from './license';
|
||||||
import { MlSetupDependencies, MlStartDependencies } from '../plugin';
|
import type { MlSetupDependencies, MlStartDependencies } from '../plugin';
|
||||||
|
import { mlUsageCollectionProvider } from './services/usage_collection';
|
||||||
|
|
||||||
import { MlRouter } from './routing';
|
import { MlRouter } from './routing';
|
||||||
import { mlApiServicesProvider } from './services/ml_api_service';
|
import { mlApiServicesProvider } from './services/ml_api_service';
|
||||||
|
@ -39,11 +41,12 @@ const localStorage = new Storage(window.localStorage);
|
||||||
/**
|
/**
|
||||||
* Provides global services available across the entire ML app.
|
* Provides global services available across the entire ML app.
|
||||||
*/
|
*/
|
||||||
export function getMlGlobalServices(httpStart: HttpStart) {
|
export function getMlGlobalServices(httpStart: HttpStart, usageCollection?: UsageCollectionSetup) {
|
||||||
const httpService = new HttpService(httpStart);
|
const httpService = new HttpService(httpStart);
|
||||||
return {
|
return {
|
||||||
httpService,
|
httpService,
|
||||||
mlApiServices: mlApiServicesProvider(httpService),
|
mlApiServices: mlApiServicesProvider(httpService),
|
||||||
|
mlUsageCollection: mlUsageCollectionProvider(usageCollection),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,8 +71,8 @@ const App: FC<AppProps> = ({ coreStart, deps, appMountParams }) => {
|
||||||
setBreadcrumbs: coreStart.chrome!.setBreadcrumbs,
|
setBreadcrumbs: coreStart.chrome!.setBreadcrumbs,
|
||||||
redirectToMlAccessDeniedPage,
|
redirectToMlAccessDeniedPage,
|
||||||
};
|
};
|
||||||
|
|
||||||
const services = {
|
const services = {
|
||||||
appName: 'ML',
|
|
||||||
kibanaVersion: deps.kibanaVersion,
|
kibanaVersion: deps.kibanaVersion,
|
||||||
share: deps.share,
|
share: deps.share,
|
||||||
data: deps.data,
|
data: deps.data,
|
||||||
|
@ -80,6 +83,7 @@ const App: FC<AppProps> = ({ coreStart, deps, appMountParams }) => {
|
||||||
maps: deps.maps,
|
maps: deps.maps,
|
||||||
triggersActionsUi: deps.triggersActionsUi,
|
triggersActionsUi: deps.triggersActionsUi,
|
||||||
dataVisualizer: deps.dataVisualizer,
|
dataVisualizer: deps.dataVisualizer,
|
||||||
|
usageCollection: deps.usageCollection,
|
||||||
...coreStart,
|
...coreStart,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -94,7 +98,10 @@ const App: FC<AppProps> = ({ coreStart, deps, appMountParams }) => {
|
||||||
<ApplicationUsageTrackingProvider>
|
<ApplicationUsageTrackingProvider>
|
||||||
<I18nContext>
|
<I18nContext>
|
||||||
<KibanaContextProvider
|
<KibanaContextProvider
|
||||||
services={{ ...services, mlServices: getMlGlobalServices(coreStart.http) }}
|
services={{
|
||||||
|
...services,
|
||||||
|
mlServices: getMlGlobalServices(coreStart.http, deps.usageCollection),
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<MlRouter pageDeps={pageDeps} />
|
<MlRouter pageDeps={pageDeps} />
|
||||||
</KibanaContextProvider>
|
</KibanaContextProvider>
|
||||||
|
|
|
@ -46,6 +46,7 @@ export const ExportJobsFlyout: FC<Props> = ({ isDisabled, currentTab }) => {
|
||||||
const {
|
const {
|
||||||
services: {
|
services: {
|
||||||
notifications: { toasts },
|
notifications: { toasts },
|
||||||
|
mlServices: { mlUsageCollection },
|
||||||
},
|
},
|
||||||
} = useMlKibana();
|
} = useMlKibana();
|
||||||
|
|
||||||
|
@ -121,6 +122,13 @@ export const ExportJobsFlyout: FC<Props> = ({ isDisabled, currentTab }) => {
|
||||||
await jobsExportService.exportDataframeAnalyticsJobs(selectedJobIds);
|
await jobsExportService.exportDataframeAnalyticsJobs(selectedJobIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mlUsageCollection.count(
|
||||||
|
selectedJobType === 'anomaly-detector'
|
||||||
|
? 'exported_anomaly_detector_jobs'
|
||||||
|
: 'exported_data_frame_analytics_jobs',
|
||||||
|
selectedJobIds.length
|
||||||
|
);
|
||||||
|
|
||||||
setExporting(false);
|
setExporting(false);
|
||||||
setShowFlyout(false);
|
setShowFlyout(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -54,6 +54,7 @@ export const ImportJobsFlyout: FC<Props> = ({ isDisabled }) => {
|
||||||
indexPatterns: { getTitles: getIndexPatternTitles },
|
indexPatterns: { getTitles: getIndexPatternTitles },
|
||||||
},
|
},
|
||||||
notifications: { toasts },
|
notifications: { toasts },
|
||||||
|
mlServices: { mlUsageCollection },
|
||||||
},
|
},
|
||||||
} = useMlKibana();
|
} = useMlKibana();
|
||||||
|
|
||||||
|
@ -175,6 +176,7 @@ export const ImportJobsFlyout: FC<Props> = ({ isDisabled }) => {
|
||||||
const renamedJobs = jobImportService.renameAdJobs(jobIdObjects, adJobs);
|
const renamedJobs = jobImportService.renameAdJobs(jobIdObjects, adJobs);
|
||||||
try {
|
try {
|
||||||
await bulkCreateADJobs(renamedJobs);
|
await bulkCreateADJobs(renamedJobs);
|
||||||
|
mlUsageCollection.count('imported_anomaly_detector_jobs', renamedJobs.length);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// display unexpected error
|
// display unexpected error
|
||||||
displayErrorToast(error);
|
displayErrorToast(error);
|
||||||
|
@ -182,6 +184,7 @@ export const ImportJobsFlyout: FC<Props> = ({ isDisabled }) => {
|
||||||
} else if (jobType === 'data-frame-analytics') {
|
} else if (jobType === 'data-frame-analytics') {
|
||||||
const renamedJobs = jobImportService.renameDfaJobs(jobIdObjects, dfaJobs);
|
const renamedJobs = jobImportService.renameDfaJobs(jobIdObjects, dfaJobs);
|
||||||
await bulkCreateDfaJobs(renamedJobs);
|
await bulkCreateDfaJobs(renamedJobs);
|
||||||
|
mlUsageCollection.count('imported_data_frame_analytics_jobs', renamedJobs.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
setImporting(false);
|
setImporting(false);
|
||||||
|
|
|
@ -5,21 +5,22 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { DataPublicPluginStart } from 'src/plugins/data/public';
|
import type { DataPublicPluginStart } from 'src/plugins/data/public';
|
||||||
import { CoreStart } from 'kibana/public';
|
import type { CoreStart } from 'kibana/public';
|
||||||
|
import type { UsageCollectionSetup } from 'src/plugins/usage_collection/public';
|
||||||
import {
|
import {
|
||||||
useKibana,
|
useKibana,
|
||||||
KibanaReactContextValue,
|
KibanaReactContextValue,
|
||||||
} from '../../../../../../../src/plugins/kibana_react/public';
|
} from '../../../../../../../src/plugins/kibana_react/public';
|
||||||
import { SecurityPluginSetup } from '../../../../../security/public';
|
import type { SecurityPluginSetup } from '../../../../../security/public';
|
||||||
import { LicenseManagementUIPluginSetup } from '../../../../../license_management/public';
|
import type { LicenseManagementUIPluginSetup } from '../../../../../license_management/public';
|
||||||
import { SharePluginStart } from '../../../../../../../src/plugins/share/public';
|
import type { SharePluginStart } from '../../../../../../../src/plugins/share/public';
|
||||||
import { MlServicesContext } from '../../app';
|
import type { MlServicesContext } from '../../app';
|
||||||
import { IStorageWrapper } from '../../../../../../../src/plugins/kibana_utils/public';
|
import type { IStorageWrapper } from '../../../../../../../src/plugins/kibana_utils/public';
|
||||||
import type { EmbeddableStart } from '../../../../../../../src/plugins/embeddable/public';
|
import type { EmbeddableStart } from '../../../../../../../src/plugins/embeddable/public';
|
||||||
import type { MapsStartApi } from '../../../../../maps/public';
|
import type { MapsStartApi } from '../../../../../maps/public';
|
||||||
import type { DataVisualizerPluginStart } from '../../../../../data_visualizer/public';
|
import type { DataVisualizerPluginStart } from '../../../../../data_visualizer/public';
|
||||||
import { TriggersAndActionsUIPublicPluginStart } from '../../../../../triggers_actions_ui/public';
|
import type { TriggersAndActionsUIPublicPluginStart } from '../../../../../triggers_actions_ui/public';
|
||||||
|
|
||||||
interface StartPlugins {
|
interface StartPlugins {
|
||||||
data: DataPublicPluginStart;
|
data: DataPublicPluginStart;
|
||||||
|
@ -30,10 +31,10 @@ interface StartPlugins {
|
||||||
maps?: MapsStartApi;
|
maps?: MapsStartApi;
|
||||||
triggersActionsUi?: TriggersAndActionsUIPublicPluginStart;
|
triggersActionsUi?: TriggersAndActionsUIPublicPluginStart;
|
||||||
dataVisualizer?: DataVisualizerPluginStart;
|
dataVisualizer?: DataVisualizerPluginStart;
|
||||||
|
usageCollection?: UsageCollectionSetup;
|
||||||
}
|
}
|
||||||
export type StartServices = CoreStart &
|
export type StartServices = CoreStart &
|
||||||
StartPlugins & {
|
StartPlugins & {
|
||||||
appName: string;
|
|
||||||
kibanaVersion: string;
|
kibanaVersion: string;
|
||||||
storage: IStorageWrapper;
|
storage: IStorageWrapper;
|
||||||
} & MlServicesContext;
|
} & MlServicesContext;
|
||||||
|
|
|
@ -9,13 +9,15 @@ import { i18n } from '@kbn/i18n';
|
||||||
|
|
||||||
import type { CoreSetup } from 'kibana/public';
|
import type { CoreSetup } from 'kibana/public';
|
||||||
import type { ManagementSetup } from 'src/plugins/management/public';
|
import type { ManagementSetup } from 'src/plugins/management/public';
|
||||||
|
import type { UsageCollectionSetup } from 'src/plugins/usage_collection/public';
|
||||||
import type { MlStartDependencies } from '../../plugin';
|
import type { MlStartDependencies } from '../../plugin';
|
||||||
|
|
||||||
import type { ManagementAppMountParams } from '../../../../../../src/plugins/management/public';
|
import type { ManagementAppMountParams } from '../../../../../../src/plugins/management/public';
|
||||||
|
|
||||||
export function registerManagementSection(
|
export function registerManagementSection(
|
||||||
management: ManagementSetup,
|
management: ManagementSetup,
|
||||||
core: CoreSetup<MlStartDependencies>
|
core: CoreSetup<MlStartDependencies>,
|
||||||
|
deps: { usageCollection?: UsageCollectionSetup }
|
||||||
) {
|
) {
|
||||||
return management.sections.section.insightsAndAlerting.registerApp({
|
return management.sections.section.insightsAndAlerting.registerApp({
|
||||||
id: 'jobsListLink',
|
id: 'jobsListLink',
|
||||||
|
@ -25,7 +27,7 @@ export function registerManagementSection(
|
||||||
order: 2,
|
order: 2,
|
||||||
async mount(params: ManagementAppMountParams) {
|
async mount(params: ManagementAppMountParams) {
|
||||||
const { mountApp } = await import('./jobs_list');
|
const { mountApp } = await import('./jobs_list');
|
||||||
return mountApp(core, params);
|
return mountApp(core, params, deps);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,10 @@ import {
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
|
|
||||||
import type { SpacesContextProps } from 'src/plugins/spaces_oss/public';
|
import type { SpacesContextProps } from 'src/plugins/spaces_oss/public';
|
||||||
|
import type { UsageCollectionSetup } from 'src/plugins/usage_collection/public';
|
||||||
import type { DataPublicPluginStart } from 'src/plugins/data/public';
|
import type { DataPublicPluginStart } from 'src/plugins/data/public';
|
||||||
import { PLUGIN_ID } from '../../../../../../common/constants/app';
|
import { PLUGIN_ID } from '../../../../../../common/constants/app';
|
||||||
import { ManagementAppMountParams } from '../../../../../../../../../src/plugins/management/public/';
|
import type { ManagementAppMountParams } from '../../../../../../../../../src/plugins/management/public';
|
||||||
|
|
||||||
import { checkGetManagementMlJobsResolver } from '../../../../capabilities/check_capabilities';
|
import { checkGetManagementMlJobsResolver } from '../../../../capabilities/check_capabilities';
|
||||||
import {
|
import {
|
||||||
|
@ -39,7 +40,7 @@ import { JobsListView } from '../../../../jobs/jobs_list/components/jobs_list_vi
|
||||||
import { DataFrameAnalyticsList } from '../../../../data_frame_analytics/pages/analytics_management/components/analytics_list';
|
import { DataFrameAnalyticsList } from '../../../../data_frame_analytics/pages/analytics_management/components/analytics_list';
|
||||||
import { AccessDeniedPage } from '../access_denied_page';
|
import { AccessDeniedPage } from '../access_denied_page';
|
||||||
import { InsufficientLicensePage } from '../insufficient_license_page';
|
import { InsufficientLicensePage } from '../insufficient_license_page';
|
||||||
import { SharePluginStart } from '../../../../../../../../../src/plugins/share/public';
|
import type { SharePluginStart } from '../../../../../../../../../src/plugins/share/public';
|
||||||
import type { SpacesPluginStart } from '../../../../../../../spaces/public';
|
import type { SpacesPluginStart } from '../../../../../../../spaces/public';
|
||||||
import { JobSpacesSyncFlyout } from '../../../../components/job_spaces_sync';
|
import { JobSpacesSyncFlyout } from '../../../../components/job_spaces_sync';
|
||||||
import { getDefaultAnomalyDetectionJobsListState } from '../../../../jobs/jobs_list/jobs';
|
import { getDefaultAnomalyDetectionJobsListState } from '../../../../jobs/jobs_list/jobs';
|
||||||
|
@ -47,7 +48,7 @@ import { getMlGlobalServices } from '../../../../app';
|
||||||
import { ListingPageUrlState } from '../../../../../../common/types/common';
|
import { ListingPageUrlState } from '../../../../../../common/types/common';
|
||||||
import { getDefaultDFAListState } from '../../../../data_frame_analytics/pages/analytics_management/page';
|
import { getDefaultDFAListState } from '../../../../data_frame_analytics/pages/analytics_management/page';
|
||||||
import { ExportJobsFlyout, ImportJobsFlyout } from '../../../../components/import_export_jobs';
|
import { ExportJobsFlyout, ImportJobsFlyout } from '../../../../components/import_export_jobs';
|
||||||
import { JobType } from '../../../../../../common/types/saved_objects';
|
import type { JobType } from '../../../../../../common/types/saved_objects';
|
||||||
|
|
||||||
interface Tab extends EuiTabbedContentTab {
|
interface Tab extends EuiTabbedContentTab {
|
||||||
'data-test-subj': string;
|
'data-test-subj': string;
|
||||||
|
@ -128,7 +129,8 @@ export const JobsListPage: FC<{
|
||||||
history: ManagementAppMountParams['history'];
|
history: ManagementAppMountParams['history'];
|
||||||
spacesApi?: SpacesPluginStart;
|
spacesApi?: SpacesPluginStart;
|
||||||
data: DataPublicPluginStart;
|
data: DataPublicPluginStart;
|
||||||
}> = ({ coreStart, share, history, spacesApi, data }) => {
|
usageCollection?: UsageCollectionSetup;
|
||||||
|
}> = ({ coreStart, share, history, spacesApi, data, usageCollection }) => {
|
||||||
const spacesEnabled = spacesApi !== undefined;
|
const spacesEnabled = spacesApi !== undefined;
|
||||||
const [initialized, setInitialized] = useState(false);
|
const [initialized, setInitialized] = useState(false);
|
||||||
const [accessDenied, setAccessDenied] = useState(false);
|
const [accessDenied, setAccessDenied] = useState(false);
|
||||||
|
@ -219,7 +221,13 @@ export const JobsListPage: FC<{
|
||||||
<RedirectAppLinks application={coreStart.application}>
|
<RedirectAppLinks application={coreStart.application}>
|
||||||
<I18nContext>
|
<I18nContext>
|
||||||
<KibanaContextProvider
|
<KibanaContextProvider
|
||||||
services={{ ...coreStart, share, data, mlServices: getMlGlobalServices(coreStart.http) }}
|
services={{
|
||||||
|
...coreStart,
|
||||||
|
share,
|
||||||
|
data,
|
||||||
|
usageCollection,
|
||||||
|
mlServices: getMlGlobalServices(coreStart.http, usageCollection),
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<ContextWrapper feature={PLUGIN_ID}>
|
<ContextWrapper feature={PLUGIN_ID}>
|
||||||
<Router history={history}>
|
<Router history={history}>
|
||||||
|
|
|
@ -7,16 +7,17 @@
|
||||||
|
|
||||||
import ReactDOM, { unmountComponentAtNode } from 'react-dom';
|
import ReactDOM, { unmountComponentAtNode } from 'react-dom';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { CoreSetup, CoreStart } from 'kibana/public';
|
import type { CoreSetup, CoreStart } from 'kibana/public';
|
||||||
import type { DataPublicPluginStart } from 'src/plugins/data/public';
|
import type { DataPublicPluginStart } from 'src/plugins/data/public';
|
||||||
import { ManagementAppMountParams } from '../../../../../../../src/plugins/management/public/';
|
import type { UsageCollectionSetup } from 'src/plugins/usage_collection/public';
|
||||||
import { MlStartDependencies } from '../../../plugin';
|
import type { ManagementAppMountParams } from '../../../../../../../src/plugins/management/public/';
|
||||||
|
import type { MlStartDependencies } from '../../../plugin';
|
||||||
import { JobsListPage } from './components';
|
import { JobsListPage } from './components';
|
||||||
import { getJobsListBreadcrumbs } from '../breadcrumbs';
|
import { getJobsListBreadcrumbs } from '../breadcrumbs';
|
||||||
import { setDependencyCache, clearCache } from '../../util/dependency_cache';
|
import { setDependencyCache, clearCache } from '../../util/dependency_cache';
|
||||||
import './_index.scss';
|
import './_index.scss';
|
||||||
import { SharePluginStart } from '../../../../../../../src/plugins/share/public';
|
import type { SharePluginStart } from '../../../../../../../src/plugins/share/public';
|
||||||
import { SpacesPluginStart } from '../../../../../spaces/public';
|
import type { SpacesPluginStart } from '../../../../../spaces/public';
|
||||||
|
|
||||||
const renderApp = (
|
const renderApp = (
|
||||||
element: HTMLElement,
|
element: HTMLElement,
|
||||||
|
@ -24,10 +25,18 @@ const renderApp = (
|
||||||
coreStart: CoreStart,
|
coreStart: CoreStart,
|
||||||
share: SharePluginStart,
|
share: SharePluginStart,
|
||||||
data: DataPublicPluginStart,
|
data: DataPublicPluginStart,
|
||||||
spacesApi?: SpacesPluginStart
|
spacesApi?: SpacesPluginStart,
|
||||||
|
usageCollection?: UsageCollectionSetup
|
||||||
) => {
|
) => {
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
React.createElement(JobsListPage, { coreStart, history, share, data, spacesApi }),
|
React.createElement(JobsListPage, {
|
||||||
|
coreStart,
|
||||||
|
history,
|
||||||
|
share,
|
||||||
|
data,
|
||||||
|
spacesApi,
|
||||||
|
usageCollection,
|
||||||
|
}),
|
||||||
element
|
element
|
||||||
);
|
);
|
||||||
return () => {
|
return () => {
|
||||||
|
@ -38,7 +47,8 @@ const renderApp = (
|
||||||
|
|
||||||
export async function mountApp(
|
export async function mountApp(
|
||||||
core: CoreSetup<MlStartDependencies>,
|
core: CoreSetup<MlStartDependencies>,
|
||||||
params: ManagementAppMountParams
|
params: ManagementAppMountParams,
|
||||||
|
deps: { usageCollection?: UsageCollectionSetup }
|
||||||
) {
|
) {
|
||||||
const [coreStart, pluginsStart] = await core.getStartServices();
|
const [coreStart, pluginsStart] = await core.getStartServices();
|
||||||
|
|
||||||
|
@ -56,6 +66,7 @@ export async function mountApp(
|
||||||
coreStart,
|
coreStart,
|
||||||
pluginsStart.share,
|
pluginsStart.share,
|
||||||
pluginsStart.data,
|
pluginsStart.data,
|
||||||
pluginsStart.spaces
|
pluginsStart.spaces,
|
||||||
|
deps.usageCollection
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* 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 type { UsageCollectionSetup } from 'src/plugins/usage_collection/public';
|
||||||
|
|
||||||
|
import { mlUsageCollectionProvider } from './usage_collection';
|
||||||
|
|
||||||
|
describe('usage_collection', () => {
|
||||||
|
let usageCollection: jest.Mocked<UsageCollectionSetup>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
usageCollection = ({
|
||||||
|
reportUiCounter: jest.fn(),
|
||||||
|
} as unknown) as jest.Mocked<UsageCollectionSetup>;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should use usageCollection for usage events', () => {
|
||||||
|
const mlUsageCollection = mlUsageCollectionProvider(usageCollection);
|
||||||
|
|
||||||
|
mlUsageCollection.click('exported_anomaly_detector_jobs');
|
||||||
|
mlUsageCollection.count('exported_data_frame_analytics_jobs');
|
||||||
|
expect(usageCollection.reportUiCounter).toHaveBeenCalledTimes(2);
|
||||||
|
expect(usageCollection.reportUiCounter).toHaveBeenCalledWith(
|
||||||
|
'ml',
|
||||||
|
'click',
|
||||||
|
'exported_anomaly_detector_jobs',
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
expect(usageCollection.reportUiCounter).toHaveBeenCalledWith(
|
||||||
|
'ml',
|
||||||
|
'count',
|
||||||
|
'exported_data_frame_analytics_jobs',
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not use usageCollection if usageCollection is disabled', () => {
|
||||||
|
const mlUsageCollection = mlUsageCollectionProvider(undefined);
|
||||||
|
mlUsageCollection.click('imported_anomaly_detector_jobs', 1);
|
||||||
|
mlUsageCollection.count('imported_data_frame_analytics_jobs', 2);
|
||||||
|
expect(usageCollection.reportUiCounter).toHaveBeenCalledTimes(0);
|
||||||
|
|
||||||
|
expect(usageCollection.reportUiCounter).not.toHaveBeenCalledWith(
|
||||||
|
'ml',
|
||||||
|
'click',
|
||||||
|
'imported_anomaly_detector_jobs',
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
expect(usageCollection.reportUiCounter).not.toHaveBeenCalledWith(
|
||||||
|
'ml',
|
||||||
|
'count',
|
||||||
|
'imported_data_frame_analytics_jobs',
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* 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 type { UsageCollectionSetup } from 'src/plugins/usage_collection/public';
|
||||||
|
import { METRIC_TYPE } from '@kbn/analytics';
|
||||||
|
import { PLUGIN_ID } from '../../../common/constants/app';
|
||||||
|
import { MlUsageEvent } from '../../../common/constants/usage_collection';
|
||||||
|
|
||||||
|
export function mlUsageCollectionProvider(usageCollection?: UsageCollectionSetup) {
|
||||||
|
if (usageCollection === undefined) {
|
||||||
|
// if usageCollection is disabled, swallow the clicks and counts
|
||||||
|
const noop = (eventNames: string | string[], count?: number) => undefined;
|
||||||
|
return {
|
||||||
|
click: noop,
|
||||||
|
count: noop,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
click: (eventNames: MlUsageEvent | MlUsageEvent[], count?: number) =>
|
||||||
|
usageCollection.reportUiCounter(PLUGIN_ID, METRIC_TYPE.CLICK, eventNames, count),
|
||||||
|
count: (eventNames: MlUsageEvent | MlUsageEvent[], count?: number) =>
|
||||||
|
usageCollection.reportUiCounter(PLUGIN_ID, METRIC_TYPE.COUNT, eventNames, count),
|
||||||
|
};
|
||||||
|
}
|
|
@ -42,10 +42,10 @@ import {
|
||||||
TriggersAndActionsUIPublicPluginSetup,
|
TriggersAndActionsUIPublicPluginSetup,
|
||||||
TriggersAndActionsUIPublicPluginStart,
|
TriggersAndActionsUIPublicPluginStart,
|
||||||
} from '../../triggers_actions_ui/public';
|
} from '../../triggers_actions_ui/public';
|
||||||
import { DataVisualizerPluginStart } from '../../data_visualizer/public';
|
import type { DataVisualizerPluginStart } from '../../data_visualizer/public';
|
||||||
import { PluginSetupContract as AlertingSetup } from '../../alerting/public';
|
import type { PluginSetupContract as AlertingSetup } from '../../alerting/public';
|
||||||
import { registerManagementSection } from './application/management';
|
import { registerManagementSection } from './application/management';
|
||||||
import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public';
|
import type { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public';
|
||||||
|
|
||||||
export interface MlStartDependencies {
|
export interface MlStartDependencies {
|
||||||
data: DataPublicPluginStart;
|
data: DataPublicPluginStart;
|
||||||
|
@ -127,7 +127,9 @@ export class MlPlugin implements Plugin<MlPluginSetup, MlPluginStart> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pluginsSetup.management) {
|
if (pluginsSetup.management) {
|
||||||
registerManagementSection(pluginsSetup.management, core).enable();
|
registerManagementSection(pluginsSetup.management, core, {
|
||||||
|
usageCollection: pluginsSetup.usageCollection,
|
||||||
|
}).enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
const licensing = pluginsSetup.licensing.license$.pipe(take(1));
|
const licensing = pluginsSetup.licensing.license$.pipe(take(1));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue