From 1cc2bf00a8e7b7fa5b90ea465f1b72d7d3b7d537 Mon Sep 17 00:00:00 2001 From: Nick Peihl Date: Wed, 13 Jul 2022 10:30:40 -0400 Subject: [PATCH] Add telemetry for layers when opening map --- .../maps/public/reducers/map/layer_utils.ts | 124 +----------------- .../routes/map_page/saved_map/saved_map.ts | 35 ++++- 2 files changed, 34 insertions(+), 125 deletions(-) diff --git a/x-pack/plugins/maps/public/reducers/map/layer_utils.ts b/x-pack/plugins/maps/public/reducers/map/layer_utils.ts index 0ee3b20678c0e..206cc4a740192 100644 --- a/x-pack/plugins/maps/public/reducers/map/layer_utils.ts +++ b/x-pack/plugins/maps/public/reducers/map/layer_utils.ts @@ -5,23 +5,9 @@ * 2.0. */ -import { METRIC_TYPE } from '@kbn/analytics'; -import { - EMSTMSSourceDescriptor, - ESGeoGridSourceDescriptor, - ESSearchSourceDescriptor, - LayerDescriptor, -} from '../../../common/descriptor_types'; +import { LayerDescriptor } from '../../../common/descriptor_types'; import { MapState } from './types'; -import { getUsageCollection } from '../../kibana_services'; import { copyPersistentState, TRACKED_LAYER_DESCRIPTOR } from '../copy_persistent_state'; -import { - APP_ID, - SOURCE_TYPES, - GRID_RESOLUTION, - RENDER_AS, - SCALING_TYPES, -} from '../../../common/constants'; export function getLayerIndex(list: LayerDescriptor[], layerId: string): number { return list.findIndex(({ id }) => layerId === id); @@ -167,111 +153,3 @@ export function setLayer( newLayerList[layerIndex] = layerDescriptor; return newLayerList; } - -export function incrementLayerUsage(layerList: LayerDescriptor[]): void { - const usageCollector = getUsageCollection(); - if (!usageCollector) { - return; - } - - for (const layer of layerList) { - const { sourceDescriptor } = layer; - switch (sourceDescriptor?.type) { - case undefined: - break; - case SOURCE_TYPES.ES_GEO_GRID: { - const { resolution, requestType } = sourceDescriptor as ESGeoGridSourceDescriptor; - let agg; - const resolutionType = GRID_RESOLUTION[resolution].toLowerCase(); - if (requestType === RENDER_AS.POINT) { - agg = 'clusters'; - } else if (requestType === RENDER_AS.GRID) { - agg = 'grids'; - } else if (requestType === RENDER_AS.HEX) { - agg = 'hexagons'; - } else if (requestType === RENDER_AS.HEATMAP) { - agg = 'heatmap'; - } else return; - usageCollector.reportUiCounter(APP_ID, METRIC_TYPE.LOADED, [ - `view_layer_es_agg_${agg}`, - `resolution_${resolutionType}`, - ]); - break; - } - case SOURCE_TYPES.ES_SEARCH: { - const { scalingType } = sourceDescriptor as ESSearchSourceDescriptor; - let scaling; - let layer = 'es_docs'; - if (scalingType === SCALING_TYPES.LIMIT) { - scaling = 'limit'; - } else if (scalingType === SCALING_TYPES.CLUSTERS) { - scaling = 'clusters'; - } else if (scalingType === SCALING_TYPES.MVT) { - scaling = 'mvt'; - } else if (scalingType === SCALING_TYPES.TOP_HITS) { - // Count top hits layer separately from documents - layer = 'es_top_hits'; - scaling = 'top_hits'; - // TODO machine learning anomalies layer - } else return; - usageCollector.reportUiCounter(APP_ID, METRIC_TYPE.LOADED, [ - `view_layer_${layer}`, - `scaling_${scaling}`, - ]); - break; - } - case SOURCE_TYPES.ES_PEW_PEW: { - usageCollector.reportUiCounter(APP_ID, METRIC_TYPE.LOADED, `view_layer_es_point_to_point`); - break; - } - case SOURCE_TYPES.ES_GEO_LINE: { - usageCollector.reportUiCounter(APP_ID, METRIC_TYPE.LOADED, `view_layer_es_tracks`); - break; - } - case SOURCE_TYPES.EMS_TMS: { - let emsLayer; - const { isAutoSelect, id } = sourceDescriptor as EMSTMSSourceDescriptor; - if (isAutoSelect) { - emsLayer = 'auto'; - } else if (id === 'dark_map') { - emsLayer = 'dark'; - } else if (id === 'road_map_desaturated') { - emsLayer = 'roadmap_desaturated'; - } else if (id === 'road_map') { - emsLayer = 'roadmap'; - } else return; - usageCollector.reportUiCounter(APP_ID, METRIC_TYPE.LOADED, [ - `view_layer_ems_basemap`, - `ems_basemap_${emsLayer}`, - ]); - break; - } - case SOURCE_TYPES.EMS_FILE: { - usageCollector.reportUiCounter(APP_ID, METRIC_TYPE.LOADED, `view_layer_ems_region`); - break; - } - case SOURCE_TYPES.KIBANA_TILEMAP: { - usageCollector.reportUiCounter(APP_ID, METRIC_TYPE.LOADED, `view_layer_kbn_tms_raster`); - break; - } - case SOURCE_TYPES.WMS: { - usageCollector.reportUiCounter(APP_ID, METRIC_TYPE.LOADED, `view_layer_wms`); - break; - } - case SOURCE_TYPES.EMS_XYZ: { - usageCollector.reportUiCounter(APP_ID, METRIC_TYPE.LOADED, `view_layer_tms_raster`); - break; - } - case SOURCE_TYPES.MVT_SINGLE_LAYER: { - usageCollector.reportUiCounter(APP_ID, METRIC_TYPE.LOADED, `view_layer_tms_mvt`); - break; - } - // TODO Can we import the ML_ANOMALY const from @kbn/ml-plugin? - case 'ML_ANOMALIES': { - usageCollector.reportUiCounter(APP_ID, METRIC_TYPE.LOADED, `view_layer_ml_anomalies`); - } - default: - break; - } - } -} diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts b/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts index 2e01db29fce85..d746f7af5b7cd 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts @@ -6,6 +6,7 @@ */ import _ from 'lodash'; +import { METRIC_TYPE } from '@kbn/analytics'; import { i18n } from '@kbn/i18n'; import { EmbeddableStateTransfer } from '@kbn/embeddable-plugin/public'; import { OnSaveProps } from '@kbn/saved-objects-plugin/public'; @@ -40,6 +41,7 @@ import { getIsAllowByValueEmbeddables, getSavedObjectsTagging, getTimeFilter, + getUsageCollection, } from '../../../kibana_services'; import { goToSpecifiedPath } from '../../../render_app'; import { LayerDescriptor } from '../../../../common/descriptor_types'; @@ -50,7 +52,7 @@ import { createBasemapLayerDescriptor } from '../../../classes/layers/create_bas import { whenLicenseInitialized } from '../../../licensed_features'; import { SerializedMapState, SerializedUiState } from './types'; import { setAutoOpenLayerWizardId } from '../../../actions/ui_actions'; -import { incrementLayerUsage } from '../../../reducers/map/layer_utils'; +import { LayerStatsCollector } from '../../../../common/telemetry'; function setMapSettingsFromEncodedState(settings: Partial) { const decodedCustomIcons = settings.customIcons @@ -137,6 +139,8 @@ export class SavedMap { } } + this._reportUsage(); + if (this._mapEmbeddableInput && this._mapEmbeddableInput.mapSettings !== undefined) { this._store.dispatch(setMapSettingsFromEncodedState(this._mapEmbeddableInput.mapSettings)); } else if (this._attributes?.mapStateJSON) { @@ -224,7 +228,6 @@ export class SavedMap { this._store.dispatch(setHiddenLayers(this._mapEmbeddableInput.hiddenLayers)); } this._initialLayerListConfig = copyPersistentState(layerList); - incrementLayerUsage(this._initialLayerListConfig); if (this._defaultLayerWizard) { this._store.dispatch(setAutoOpenLayerWizardId(this._defaultLayerWizard)); @@ -272,6 +275,34 @@ export class SavedMap { : this._attributes!.title; } + private _reportUsage(): void { + const usageCollector = getUsageCollection(); + if (!usageCollector || !this._attributes) { + return; + } + + const layerStatsCollector = new LayerStatsCollector(this._attributes); + + const uiCounterEvents = { + layer: layerStatsCollector.getLayerCounts(), + scaling: layerStatsCollector.getScalingCounts(), + resolution: layerStatsCollector.getResolutionCounts(), + join: layerStatsCollector.getJoinCounts(), + ems_basemap: layerStatsCollector.getBasemapCounts(), + }; + + for (const [eventType, eventTypeMetrics] of Object.entries(uiCounterEvents)) { + for (const [eventName, count] of Object.entries(eventTypeMetrics)) { + usageCollector.reportUiCounter( + APP_ID, + METRIC_TYPE.LOADED, + `${eventType}_${eventName}`, + count + ); + } + } + } + setBreadcrumbs() { if (!this._attributes) { throw new Error('Invalid usage, must await whenReady before calling hasUnsavedChanges');