Skip to content

Commit

Permalink
[Fleet] Improve performance of data stream API (elastic#97058)
Browse files Browse the repository at this point in the history
* Improve performance of data stream API

* Remove extra logger, replace filter with reduce

* Remove unused import
  • Loading branch information
jen-huang authored and madirey committed May 11, 2021
1 parent f03b207 commit 1c94d96
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 40 deletions.
82 changes: 51 additions & 31 deletions x-pack/plugins/fleet/server/routes/data_streams/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
*/

import { keyBy, keys, merge } from 'lodash';
import type { RequestHandler, SavedObjectsClientContract } from 'src/core/server';
import type { RequestHandler, SavedObjectsBulkGetObject } from 'src/core/server';

import type { DataStream } from '../../types';
import { KibanaAssetType, KibanaSavedObjectType } from '../../../common';
import { KibanaSavedObjectType } from '../../../common';
import type { GetDataStreamsResponse } from '../../../common';
import { getPackageSavedObjects, getKibanaSavedObject } from '../../services/epm/packages/get';
import { getPackageSavedObjects } from '../../services/epm/packages/get';
import { defaultIngestErrorHandler } from '../../errors';

const DATA_STREAM_INDEX_PATTERN = 'logs-*-*,metrics-*-*,traces-*-*';
Expand Down Expand Up @@ -78,6 +78,40 @@ export const getListHandler: RequestHandler = async (context, request, response)
const packageSavedObjectsByName = keyBy(packageSavedObjects.saved_objects, 'id');
const packageMetadata: any = {};

// Get dashboard information for all packages
const dashboardIdsByPackageName = packageSavedObjects.saved_objects.reduce<
Record<string, string[]>
>((allDashboards, pkgSavedObject) => {
const dashboards: string[] = [];
(pkgSavedObject.attributes?.installed_kibana || []).forEach((o) => {
if (o.type === KibanaSavedObjectType.dashboard) {
dashboards.push(o.id);
}
});
allDashboards[pkgSavedObject.id] = dashboards;
return allDashboards;
}, {});
const allDashboardSavedObjects = await context.core.savedObjects.client.bulkGet<{
title?: string;
}>(
Object.values(dashboardIdsByPackageName).reduce<SavedObjectsBulkGetObject[]>(
(allDashboards, dashboardIds) => {
return allDashboards.concat(
dashboardIds.map((id) => ({
id,
type: KibanaSavedObjectType.dashboard,
fields: ['title'],
}))
);
},
[]
)
);
const allDashboardSavedObjectsById = keyBy(
allDashboardSavedObjects.saved_objects,
(dashboardSavedObject) => dashboardSavedObject.id
);

// Query additional information for each data stream
const dataStreamPromises = dataStreamNames.map(async (dataStreamName) => {
const dataStream = dataStreams[dataStreamName];
Expand Down Expand Up @@ -158,19 +192,23 @@ export const getListHandler: RequestHandler = async (context, request, response)
// - and we didn't pick the metadata in an earlier iteration of this map()
if (!packageMetadata[pkgName]) {
// then pick the dashboards from the package saved object
const dashboards =
pkgSavedObject.attributes?.installed_kibana?.filter(
(o) => o.type === KibanaSavedObjectType.dashboard
) || [];
// and then pick the human-readable titles from the dashboard saved objects
const enhancedDashboards = await getEnhancedDashboards(
context.core.savedObjects.client,
dashboards
);
const packageDashboardIds = dashboardIdsByPackageName[pkgName] || [];
const packageDashboards = packageDashboardIds.reduce<
Array<{ id: string; title: string }>
>((dashboards, dashboardId) => {
const dashboard = allDashboardSavedObjectsById[dashboardId];
if (dashboard) {
dashboards.push({
id: dashboard.id,
title: dashboard.attributes.title || dashboard.id,
});
}
return dashboards;
}, []);

packageMetadata[pkgName] = {
version: pkgSavedObject.attributes?.version || '',
dashboards: enhancedDashboards,
dashboards: packageDashboards,
};
}

Expand All @@ -195,21 +233,3 @@ export const getListHandler: RequestHandler = async (context, request, response)
return defaultIngestErrorHandler({ error, response });
}
};

const getEnhancedDashboards = async (
savedObjectsClient: SavedObjectsClientContract,
dashboards: any[]
) => {
const dashboardsPromises = dashboards.map(async (db) => {
const dbSavedObject: any = await getKibanaSavedObject(
savedObjectsClient,
KibanaAssetType.dashboard,
db.id
);
return {
id: db.id,
title: dbSavedObject.attributes?.title || db.id,
};
});
return await Promise.all(dashboardsPromises);
};
9 changes: 0 additions & 9 deletions x-pack/plugins/fleet/server/services/epm/packages/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import type {
RegistryPackage,
EpmPackageAdditions,
} from '../../../../common/types';
import type { KibanaAssetType } from '../../../types';
import type { Installation, PackageInfo } from '../../../types';
import { IngestManagerError } from '../../../errors';
import { appContextService } from '../../';
Expand Down Expand Up @@ -260,11 +259,3 @@ function sortByName(a: { name: string }, b: { name: string }) {
return 0;
}
}

export async function getKibanaSavedObject(
savedObjectsClient: SavedObjectsClientContract,
type: KibanaAssetType,
id: string
) {
return savedObjectsClient.get(type, id);
}

0 comments on commit 1c94d96

Please sign in to comment.