diff --git a/CHANGELOG.md b/CHANGELOG.md index e17bb7d1a207..aaf804ef5adc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,7 +56,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - [Dynamic Configurations] Pass request headers when making application config calls ([#6164](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6164)) - [Discover] Options button to configure legacy mode and remove the top navigation option ([#6170](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6170)) - [Multiple Datasource] Add default functionality for customer to choose default datasource ([#6058](https://github.com/opensearch-project/OpenSearch-Dashboards/issues/6058)) - +- Enable UI Metric Collector to collect UI Metrics and Application Usage ([#6203](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6203)) ### 🐛 Bug Fixes diff --git a/config/opensearch_dashboards.yml b/config/opensearch_dashboards.yml index 99df1d808bab..30fddb2b7b08 100644 --- a/config/opensearch_dashboards.yml +++ b/config/opensearch_dashboards.yml @@ -305,3 +305,7 @@ # Set the value to true to enable workspace feature # workspace.enabled: false + +# Set the value to true to enable Ui Metric Collectors in Usage Collector +# This publishes the Application Usage and UI Metrics into the saved object, which can be accessed by /api/stats?extended=true&legacy=true&exclude_usage=false +# usageCollection.uiMetric.enabled: false \ No newline at end of file diff --git a/packages/osd-analytics/src/reporter.ts b/packages/osd-analytics/src/reporter.ts index d4d7b68a25a2..7dedf5b7ac38 100644 --- a/packages/osd-analytics/src/reporter.ts +++ b/packages/osd-analytics/src/reporter.ts @@ -36,7 +36,7 @@ import { Report, ReportManager } from './report'; import { ApplicationUsage } from './metrics'; export interface ReporterConfig { - // http: ReportHTTP; + http: ReportHTTP; storage?: Storage; checkInterval?: number; debug?: boolean; @@ -49,7 +49,7 @@ export class Reporter { checkInterval: number; private interval?: NodeJS.Timer; private lastAppId?: string; - // private http: ReportHTTP; + private http: ReportHTTP; private reportManager: ReportManager; private storageManager: ReportStorageManager; private readonly applicationUsage: ApplicationUsage; @@ -59,8 +59,8 @@ export class Reporter { private started = false; constructor(config: ReporterConfig) { - const { storage, debug, checkInterval = 90000, storageKey = 'analytics' } = config; - // this.http = http; + const { http, storage, debug, checkInterval = 90000, storageKey = 'analytics' } = config; + this.http = http; this.checkInterval = checkInterval; this.applicationUsage = new ApplicationUsage(); this.storageManager = new ReportStorageManager(storageKey, storage); @@ -144,14 +144,14 @@ export class Reporter { public reportApplicationUsage(appId?: string) { this.log(`Reporting application changed to ${appId}`); this.lastAppId = appId || this.lastAppId; - // const appChangedReport = this.applicationUsage.appChanged(appId); - // if (appChangedReport) this.saveToReport([appChangedReport]); + const appChangedReport = this.applicationUsage.appChanged(appId); + if (appChangedReport) this.saveToReport([appChangedReport]); } public sendReports = async () => { if (!this.reportManager.isReportEmpty()) { try { - // await this.http(this.reportManager.report); + await this.http(this.reportManager.report); this.flushReport(); } catch (err) { this.log(`Error Sending Metrics Report ${err}`); diff --git a/src/plugins/usage_collection/public/services/create_reporter.ts b/src/plugins/usage_collection/public/services/create_reporter.ts index 31b77eb862eb..6485e5b45f1f 100644 --- a/src/plugins/usage_collection/public/services/create_reporter.ts +++ b/src/plugins/usage_collection/public/services/create_reporter.ts @@ -38,20 +38,20 @@ interface AnalyicsReporterConfig { } export function createReporter(config: AnalyicsReporterConfig): Reporter { - const { localStorage, debug } = config; + const { localStorage, debug, fetch } = config; return new Reporter({ debug, storage: localStorage, - // async http(report) { - // const response = await fetch.post('/api/ui_metric/report', { - // body: JSON.stringify({ report }), - // }); + async http(report) { + const response = await fetch.post('/api/ui_metric/report', { + body: JSON.stringify({ report }), + }); - // if (response.status !== 'ok') { - // throw Error('Unable to store report.'); - // } - // return response; - // }, + if (response.status !== 'ok') { + throw Error('Unable to store report.'); + } + return response; + }, }); } diff --git a/src/plugins/usage_collection/server/config.ts b/src/plugins/usage_collection/server/config.ts index 1a12e58113a1..5bc9ec500cdb 100644 --- a/src/plugins/usage_collection/server/config.ts +++ b/src/plugins/usage_collection/server/config.ts @@ -34,7 +34,7 @@ import { DEFAULT_MAXIMUM_WAIT_TIME_FOR_ALL_COLLECTORS_IN_S } from '../common/con export const configSchema = schema.object({ uiMetric: schema.object({ - enabled: schema.boolean({ defaultValue: true }), + enabled: schema.boolean({ defaultValue: false }), debug: schema.boolean({ defaultValue: schema.contextRef('dev') }), }), maximumWaitTimeForAllCollectorsInS: schema.number({ diff --git a/src/plugins/usage_collection/server/routes/report_metrics.ts b/src/plugins/usage_collection/server/routes/report_metrics.ts index 75080a6b440d..1964e1bf27e1 100644 --- a/src/plugins/usage_collection/server/routes/report_metrics.ts +++ b/src/plugins/usage_collection/server/routes/report_metrics.ts @@ -28,15 +28,14 @@ * under the License. */ -// import { schema } from '@osd/config-schema'; +import { schema } from '@osd/config-schema'; import { IRouter, ISavedObjectsRepository } from 'opensearch-dashboards/server'; -// import { storeReport, reportSchema } from '../report'; +import { storeReport, reportSchema } from '../report'; export function registerUiMetricRoute( router: IRouter, getSavedObjects: () => ISavedObjectsRepository | undefined ) { - /* router.post( { path: '/api/ui_metric/report', @@ -59,5 +58,5 @@ export function registerUiMetricRoute( return res.ok({ body: { status: 'fail' } }); } } - );*/ + ); } diff --git a/src/plugins/vis_type_vega/server/types.ts b/src/plugins/vis_type_vega/server/types.ts index 9695f6dc23d7..38c04c60707e 100644 --- a/src/plugins/vis_type_vega/server/types.ts +++ b/src/plugins/vis_type_vega/server/types.ts @@ -32,7 +32,7 @@ import { Observable } from 'rxjs'; import { HomeServerPluginSetup } from '../../home/server'; import { UsageCollectionSetup } from '../../usage_collection/server'; -export type ConfigObservable = Observable<{ kibana: { index: string } }>; +export type ConfigObservable = Observable<{ opensearchDashboards: { index: string } }>; export interface VegaSavedObjectAttributes { title: string; diff --git a/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.test.ts b/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.test.ts index c0c21266f0e4..6d9384945960 100644 --- a/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.test.ts +++ b/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.test.ts @@ -87,7 +87,7 @@ const getMockCallCluster = (hits?: unknown[]) => jest.fn().mockReturnValue(Promise.resolve({ hits: { hits } }) as unknown) as LegacyAPICaller; describe('Vega visualization usage collector', () => { - const configMock = of({ kibana: { index: '' } }); + const configMock = of({ opensearchDashboards: { index: '' } }); const usageCollector = getUsageCollector(configMock, { home: ({ sampleData: { diff --git a/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.ts b/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.ts index c9ba07c09289..edd52d5c9e10 100644 --- a/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.ts +++ b/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.ts @@ -151,7 +151,7 @@ export function getUsageCollector( type: VEGA_USAGE_TYPE, isReady: () => true, fetch: async (callCluster: LegacyAPICaller) => { - const { index } = (await config.pipe(first()).toPromise()).kibana; + const { index } = (await config.pipe(first()).toPromise()).opensearchDashboards; return await getStats(callCluster, index, dependencies); },