-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Maps] Remove extra layer of telemetry nesting under "attributes" (#6…
…6137) * Return attributes when telemetry created instead of whole saved object. Update integration test * Change 'maps-telemetry' to 'maps' * No need to create a saved object anymore. This is leftover from task manager telemetry mgmt * Add test confirming attrs undefined. Change tests to check for 'maps' iso 'maps-telemetry' * Add two more tests confirming expected telemetry shape * Review feedback. Use TELEMETRY_TYPE constant and set to APP_ID # Conflicts: # x-pack/plugins/maps/server/maps_telemetry/maps_telemetry.ts
- Loading branch information
Aaron Caldwell
committed
Jun 23, 2020
1 parent
44e4659
commit 0c82155
Showing
3 changed files
with
190 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
185 changes: 185 additions & 0 deletions
185
x-pack/plugins/maps/server/maps_telemetry/maps_telemetry.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import _ from 'lodash'; | ||
import { | ||
SavedObjectsClientContract, | ||
SavedObjectAttributes, | ||
SavedObjectAttribute, | ||
} from 'kibana/server'; | ||
import { IFieldType, IIndexPattern } from 'src/plugins/data/public'; | ||
import { SOURCE_TYPES, ES_GEO_FIELD_TYPE, MAP_SAVED_OBJECT_TYPE } from '../../common/constants'; | ||
import { LayerDescriptor } from '../../common/descriptor_types'; | ||
import { MapSavedObject } from '../../common/map_saved_object_type'; | ||
// @ts-ignore | ||
import { getInternalRepository } from '../kibana_server_services'; | ||
import { MapsConfigType } from '../../config'; | ||
|
||
interface IStats { | ||
[key: string]: { | ||
min: number; | ||
max: number; | ||
avg: number; | ||
}; | ||
} | ||
|
||
interface ILayerTypeCount { | ||
[key: string]: number; | ||
} | ||
|
||
function getUniqueLayerCounts(layerCountsList: ILayerTypeCount[], mapsCount: number) { | ||
const uniqueLayerTypes = _.uniq(_.flatten(layerCountsList.map((lTypes) => Object.keys(lTypes)))); | ||
|
||
return uniqueLayerTypes.reduce((accu: IStats, type: string) => { | ||
const typeCounts = layerCountsList.reduce( | ||
(tCountsAccu: number[], tCounts: ILayerTypeCount): number[] => { | ||
if (tCounts[type]) { | ||
tCountsAccu.push(tCounts[type]); | ||
} | ||
return tCountsAccu; | ||
}, | ||
[] | ||
); | ||
const typeCountsSum = _.sum(typeCounts); | ||
accu[type] = { | ||
min: typeCounts.length ? _.min(typeCounts) : 0, | ||
max: typeCounts.length ? _.max(typeCounts) : 0, | ||
avg: typeCountsSum ? typeCountsSum / mapsCount : 0, | ||
}; | ||
return accu; | ||
}, {}); | ||
} | ||
|
||
function getIndexPatternsWithGeoFieldCount(indexPatterns: IIndexPattern[]) { | ||
const fieldLists = indexPatterns.map((indexPattern) => | ||
indexPattern.attributes && indexPattern.attributes.fields | ||
? JSON.parse(indexPattern.attributes.fields) | ||
: [] | ||
); | ||
|
||
const fieldListsWithGeoFields = fieldLists.filter((fields) => | ||
fields.some( | ||
(field: IFieldType) => | ||
field.type === ES_GEO_FIELD_TYPE.GEO_POINT || field.type === ES_GEO_FIELD_TYPE.GEO_SHAPE | ||
) | ||
); | ||
|
||
const fieldListsWithGeoPointFields = fieldLists.filter((fields) => | ||
fields.some((field: IFieldType) => field.type === ES_GEO_FIELD_TYPE.GEO_POINT) | ||
); | ||
|
||
const fieldListsWithGeoShapeFields = fieldLists.filter((fields) => | ||
fields.some((field: IFieldType) => field.type === ES_GEO_FIELD_TYPE.GEO_SHAPE) | ||
); | ||
|
||
return { | ||
indexPatternsWithGeoFieldCount: fieldListsWithGeoFields.length, | ||
indexPatternsWithGeoPointFieldCount: fieldListsWithGeoPointFields.length, | ||
indexPatternsWithGeoShapeFieldCount: fieldListsWithGeoShapeFields.length, | ||
}; | ||
} | ||
|
||
export function buildMapsTelemetry({ | ||
mapSavedObjects, | ||
indexPatternSavedObjects, | ||
settings, | ||
}: { | ||
mapSavedObjects: MapSavedObject[]; | ||
indexPatternSavedObjects: IIndexPattern[]; | ||
settings: SavedObjectAttribute; | ||
}): SavedObjectAttributes { | ||
const layerLists = mapSavedObjects.map((savedMapObject) => | ||
savedMapObject.attributes && savedMapObject.attributes.layerListJSON | ||
? JSON.parse(savedMapObject.attributes.layerListJSON) | ||
: [] | ||
); | ||
const mapsCount = layerLists.length; | ||
|
||
const dataSourcesCount = layerLists.map((lList) => { | ||
// todo: not every source-descriptor has an id | ||
// @ts-ignore | ||
const sourceIdList = lList.map((layer: LayerDescriptor) => layer.sourceDescriptor.id); | ||
return _.uniq(sourceIdList).length; | ||
}); | ||
|
||
const layersCount = layerLists.map((lList) => lList.length); | ||
const layerTypesCount = layerLists.map((lList) => _.countBy(lList, 'type')); | ||
|
||
// Count of EMS Vector layers used | ||
const emsLayersCount = layerLists.map((lList) => | ||
_(lList) | ||
.countBy((layer: LayerDescriptor) => { | ||
const isEmsFile = _.get(layer, 'sourceDescriptor.type') === SOURCE_TYPES.EMS_FILE; | ||
return isEmsFile && _.get(layer, 'sourceDescriptor.id'); | ||
}) | ||
.pick((val, key) => key !== 'false') | ||
.value() | ||
); | ||
|
||
const dataSourcesCountSum = _.sum(dataSourcesCount); | ||
const layersCountSum = _.sum(layersCount); | ||
|
||
const { | ||
indexPatternsWithGeoFieldCount, | ||
indexPatternsWithGeoPointFieldCount, | ||
indexPatternsWithGeoShapeFieldCount, | ||
} = getIndexPatternsWithGeoFieldCount(indexPatternSavedObjects); | ||
return { | ||
settings, | ||
indexPatternsWithGeoFieldCount, | ||
indexPatternsWithGeoPointFieldCount, | ||
indexPatternsWithGeoShapeFieldCount, | ||
// Total count of maps | ||
mapsTotalCount: mapsCount, | ||
// Time of capture | ||
timeCaptured: new Date().toISOString(), | ||
attributesPerMap: { | ||
// Count of data sources per map | ||
dataSourcesCount: { | ||
min: dataSourcesCount.length ? _.min(dataSourcesCount) : 0, | ||
max: dataSourcesCount.length ? _.max(dataSourcesCount) : 0, | ||
avg: dataSourcesCountSum ? layersCountSum / mapsCount : 0, | ||
}, | ||
// Total count of layers per map | ||
layersCount: { | ||
min: layersCount.length ? _.min(layersCount) : 0, | ||
max: layersCount.length ? _.max(layersCount) : 0, | ||
avg: layersCountSum ? layersCountSum / mapsCount : 0, | ||
}, | ||
// Count of layers by type | ||
layerTypesCount: { | ||
...getUniqueLayerCounts(layerTypesCount, mapsCount), | ||
}, | ||
// Count of layer by EMS region | ||
emsVectorLayersCount: { | ||
...getUniqueLayerCounts(emsLayersCount, mapsCount), | ||
}, | ||
}, | ||
}; | ||
} | ||
async function getMapSavedObjects(savedObjectsClient: SavedObjectsClientContract) { | ||
const mapsSavedObjects = await savedObjectsClient.find({ type: MAP_SAVED_OBJECT_TYPE }); | ||
return _.get(mapsSavedObjects, 'saved_objects', []); | ||
} | ||
|
||
async function getIndexPatternSavedObjects(savedObjectsClient: SavedObjectsClientContract) { | ||
const indexPatternSavedObjects = await savedObjectsClient.find({ type: 'index-pattern' }); | ||
return _.get(indexPatternSavedObjects, 'saved_objects', []); | ||
} | ||
|
||
export async function getMapsTelemetry(config: MapsConfigType) { | ||
const savedObjectsClient = getInternalRepository(); | ||
// @ts-ignore | ||
const mapSavedObjects: MapSavedObject[] = await getMapSavedObjects(savedObjectsClient); | ||
const indexPatternSavedObjects: IIndexPattern[] = await getIndexPatternSavedObjects( | ||
// @ts-ignore | ||
savedObjectsClient | ||
); | ||
const settings: SavedObjectAttribute = { | ||
showMapVisualizationTypes: config.showMapVisualizationTypes, | ||
}; | ||
return buildMapsTelemetry({ mapSavedObjects, indexPatternSavedObjects, settings }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters