mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Maps] Iterate over saved object & index patterns pages to collect telemetry results (#73077)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
057e9a72e0
commit
dfcf7fe686
2 changed files with 107 additions and 78 deletions
|
@ -6,23 +6,17 @@
|
|||
|
||||
import mapSavedObjects from './test_resources/sample_map_saved_objects.json';
|
||||
import indexPatternSavedObjects from './test_resources/sample_index_pattern_saved_objects';
|
||||
import { buildMapsTelemetry } from './maps_telemetry';
|
||||
|
||||
describe('buildMapsTelemetry', () => {
|
||||
const settings = { showMapVisualizationTypes: false };
|
||||
import {
|
||||
buildMapsIndexPatternsTelemetry,
|
||||
buildMapsSavedObjectsTelemetry,
|
||||
getLayerLists,
|
||||
} from './maps_telemetry';
|
||||
|
||||
describe('buildMapsSavedObjectsTelemetry', () => {
|
||||
test('returns zeroed telemetry data when there are no saved objects', async () => {
|
||||
const result = buildMapsTelemetry({
|
||||
mapSavedObjects: [],
|
||||
indexPatternSavedObjects: [],
|
||||
settings,
|
||||
});
|
||||
const result = buildMapsSavedObjectsTelemetry([]);
|
||||
|
||||
expect(result).toMatchObject({
|
||||
indexPatternsWithGeoFieldCount: 0,
|
||||
indexPatternsWithGeoPointFieldCount: 0,
|
||||
indexPatternsWithGeoShapeFieldCount: 0,
|
||||
geoShapeAggLayersCount: 0,
|
||||
attributesPerMap: {
|
||||
dataSourcesCount: {
|
||||
avg: 0,
|
||||
|
@ -38,20 +32,14 @@ describe('buildMapsTelemetry', () => {
|
|||
},
|
||||
},
|
||||
mapsTotalCount: 0,
|
||||
settings: {
|
||||
showMapVisualizationTypes: false,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('returns expected telemetry data from saved objects', async () => {
|
||||
const result = buildMapsTelemetry({ mapSavedObjects, indexPatternSavedObjects, settings });
|
||||
const layerLists = getLayerLists(mapSavedObjects);
|
||||
const result = buildMapsSavedObjectsTelemetry(layerLists);
|
||||
|
||||
expect(result).toMatchObject({
|
||||
indexPatternsWithGeoFieldCount: 3,
|
||||
indexPatternsWithGeoPointFieldCount: 2,
|
||||
indexPatternsWithGeoShapeFieldCount: 1,
|
||||
geoShapeAggLayersCount: 2,
|
||||
attributesPerMap: {
|
||||
dataSourcesCount: {
|
||||
avg: 2,
|
||||
|
@ -94,9 +82,18 @@ describe('buildMapsTelemetry', () => {
|
|||
},
|
||||
},
|
||||
mapsTotalCount: 5,
|
||||
settings: {
|
||||
showMapVisualizationTypes: false,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('returns expected telemetry data from index patterns', async () => {
|
||||
const layerLists = getLayerLists(mapSavedObjects);
|
||||
const result = buildMapsIndexPatternsTelemetry(indexPatternSavedObjects, layerLists);
|
||||
|
||||
expect(result).toMatchObject({
|
||||
indexPatternsWithGeoFieldCount: 3,
|
||||
indexPatternsWithGeoPointFieldCount: 2,
|
||||
indexPatternsWithGeoShapeFieldCount: 1,
|
||||
geoShapeAggLayersCount: 2,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
import { ISavedObjectsRepository, SavedObject, SavedObjectsClientContract } from 'kibana/server';
|
||||
import { SavedObject } from 'kibana/server';
|
||||
import { IFieldType, IndexPatternAttributes } from 'src/plugins/data/public';
|
||||
import {
|
||||
ES_GEO_FIELD_TYPE,
|
||||
|
@ -40,12 +40,14 @@ interface ILayerTypeCount {
|
|||
[key: string]: number;
|
||||
}
|
||||
|
||||
export interface MapsUsage {
|
||||
settings: Settings;
|
||||
indexPatternsWithGeoFieldCount: number;
|
||||
indexPatternsWithGeoPointFieldCount: number;
|
||||
indexPatternsWithGeoShapeFieldCount: number;
|
||||
geoShapeAggLayersCount: number;
|
||||
export interface GeoIndexPatternsUsage {
|
||||
indexPatternsWithGeoFieldCount?: number;
|
||||
indexPatternsWithGeoPointFieldCount?: number;
|
||||
indexPatternsWithGeoShapeFieldCount?: number;
|
||||
geoShapeAggLayersCount?: number;
|
||||
}
|
||||
|
||||
export interface LayersStatsUsage {
|
||||
mapsTotalCount: number;
|
||||
timeCaptured: string;
|
||||
attributesPerMap: {
|
||||
|
@ -64,6 +66,10 @@ export interface MapsUsage {
|
|||
};
|
||||
}
|
||||
|
||||
export interface MapsUsage extends LayersStatsUsage, GeoIndexPatternsUsage {
|
||||
settings: Settings;
|
||||
}
|
||||
|
||||
function getUniqueLayerCounts(layerCountsList: ILayerTypeCount[], mapsCount: number) {
|
||||
const uniqueLayerTypes = _.uniq(_.flatten(layerCountsList.map((lTypes) => Object.keys(lTypes))));
|
||||
|
||||
|
@ -228,16 +234,28 @@ export function getLayerLists(mapSavedObjects: MapSavedObject[]): LayerDescripto
|
|||
});
|
||||
}
|
||||
|
||||
export function buildMapsTelemetry({
|
||||
mapSavedObjects,
|
||||
indexPatternSavedObjects,
|
||||
settings,
|
||||
}: {
|
||||
mapSavedObjects: MapSavedObject[];
|
||||
indexPatternSavedObjects: Array<SavedObject<IndexPatternAttributes>>;
|
||||
settings: Settings;
|
||||
}): MapsUsage {
|
||||
const layerLists: LayerDescriptor[][] = getLayerLists(mapSavedObjects);
|
||||
export function buildMapsIndexPatternsTelemetry(
|
||||
indexPatternSavedObjects: Array<SavedObject<IndexPatternAttributes>>,
|
||||
layerLists: LayerDescriptor[][]
|
||||
): GeoIndexPatternsUsage {
|
||||
const {
|
||||
indexPatternsWithGeoFieldCount,
|
||||
indexPatternsWithGeoPointFieldCount,
|
||||
indexPatternsWithGeoShapeFieldCount,
|
||||
} = getIndexPatternsWithGeoFieldCount(indexPatternSavedObjects);
|
||||
|
||||
// Tracks whether user uses Gold+ only functionality
|
||||
const geoShapeAggLayersCount = getGeoShapeAggCount(layerLists, indexPatternSavedObjects);
|
||||
|
||||
return {
|
||||
indexPatternsWithGeoFieldCount,
|
||||
indexPatternsWithGeoPointFieldCount,
|
||||
indexPatternsWithGeoShapeFieldCount,
|
||||
geoShapeAggLayersCount,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildMapsSavedObjectsTelemetry(layerLists: LayerDescriptor[][]): LayersStatsUsage {
|
||||
const mapsCount = layerLists.length;
|
||||
|
||||
const dataSourcesCount = layerLists.map((layerList: LayerDescriptor[]) => {
|
||||
|
@ -256,21 +274,7 @@ export function buildMapsTelemetry({
|
|||
const dataSourcesCountSum = _.sum(dataSourcesCount);
|
||||
const layersCountSum = _.sum(layersCount);
|
||||
|
||||
const {
|
||||
indexPatternsWithGeoFieldCount,
|
||||
indexPatternsWithGeoPointFieldCount,
|
||||
indexPatternsWithGeoShapeFieldCount,
|
||||
} = getIndexPatternsWithGeoFieldCount(indexPatternSavedObjects);
|
||||
|
||||
// Tracks whether user users Gold+ only functionality
|
||||
const geoShapeAggLayersCount = getGeoShapeAggCount(layerLists, indexPatternSavedObjects);
|
||||
|
||||
return {
|
||||
settings,
|
||||
indexPatternsWithGeoFieldCount,
|
||||
indexPatternsWithGeoPointFieldCount,
|
||||
indexPatternsWithGeoShapeFieldCount,
|
||||
geoShapeAggLayersCount,
|
||||
// Total count of maps
|
||||
mapsTotalCount: mapsCount,
|
||||
// Time of capture
|
||||
|
@ -299,30 +303,58 @@ export function buildMapsTelemetry({
|
|||
},
|
||||
};
|
||||
}
|
||||
async function getMapSavedObjects(
|
||||
savedObjectsClient: SavedObjectsClientContract | ISavedObjectsRepository
|
||||
) {
|
||||
const mapsSavedObjects = await savedObjectsClient.find<MapSavedObjectAttributes>({
|
||||
type: MAP_SAVED_OBJECT_TYPE,
|
||||
});
|
||||
return mapsSavedObjects.saved_objects;
|
||||
}
|
||||
|
||||
async function getIndexPatternSavedObjects(
|
||||
savedObjectsClient: SavedObjectsClientContract | ISavedObjectsRepository
|
||||
export async function execTransformOverMultipleSavedObjectPages<T>(
|
||||
savedObjectType: string,
|
||||
transform: (savedObjects: Array<SavedObject<T>>) => void
|
||||
) {
|
||||
const indexPatternSavedObjects = await savedObjectsClient.find<IndexPatternAttributes>({
|
||||
type: 'index-pattern',
|
||||
});
|
||||
return indexPatternSavedObjects.saved_objects;
|
||||
}
|
||||
|
||||
export async function getMapsTelemetry(config: MapsConfigType) {
|
||||
const savedObjectsClient = getInternalRepository();
|
||||
const mapSavedObjects = await getMapSavedObjects(savedObjectsClient);
|
||||
const indexPatternSavedObjects = await getIndexPatternSavedObjects(savedObjectsClient);
|
||||
const settings = {
|
||||
showMapVisualizationTypes: config.showMapVisualizationTypes,
|
||||
};
|
||||
return buildMapsTelemetry({ mapSavedObjects, indexPatternSavedObjects, settings });
|
||||
|
||||
let currentPage = 1;
|
||||
// Seed values
|
||||
let page = 0;
|
||||
let perPage = 0;
|
||||
let total = 0;
|
||||
let savedObjects = [];
|
||||
|
||||
do {
|
||||
const savedObjectsFindResult = await savedObjectsClient.find<T>({
|
||||
type: savedObjectType,
|
||||
page: currentPage++,
|
||||
});
|
||||
({ page, per_page: perPage, saved_objects: savedObjects, total } = savedObjectsFindResult);
|
||||
transform(savedObjects);
|
||||
} while (page * perPage < total);
|
||||
}
|
||||
|
||||
export async function getMapsTelemetry(config: MapsConfigType): Promise<MapsUsage> {
|
||||
// Get layer descriptors for Maps saved objects. This is not set up
|
||||
// to be done incrementally (i.e. - per page) but minimally we at least
|
||||
// build a list of small footprint objects
|
||||
const layerLists: LayerDescriptor[][] = [];
|
||||
await execTransformOverMultipleSavedObjectPages<MapSavedObjectAttributes>(
|
||||
MAP_SAVED_OBJECT_TYPE,
|
||||
(savedObjects) => layerLists.push(...getLayerLists(savedObjects))
|
||||
);
|
||||
const savedObjectsTelemetry = buildMapsSavedObjectsTelemetry(layerLists);
|
||||
|
||||
// Incrementally harvest index pattern saved objects telemetry
|
||||
const indexPatternsTelemetry = {};
|
||||
await execTransformOverMultipleSavedObjectPages<IndexPatternAttributes>(
|
||||
'index-pattern',
|
||||
(savedObjects) =>
|
||||
_.mergeWith(
|
||||
indexPatternsTelemetry,
|
||||
buildMapsIndexPatternsTelemetry(savedObjects, layerLists),
|
||||
(prevVal, currVal) => prevVal || 0 + currVal || 0 // Additive merge
|
||||
)
|
||||
);
|
||||
|
||||
return {
|
||||
settings: {
|
||||
showMapVisualizationTypes: config.showMapVisualizationTypes,
|
||||
},
|
||||
...indexPatternsTelemetry,
|
||||
...savedObjectsTelemetry,
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue