Skip to content

Commit

Permalink
Add telemetry for layers when opening map
Browse files Browse the repository at this point in the history
  • Loading branch information
nickpeihl committed Jul 13, 2022
1 parent 1d1338b commit 1cc2bf0
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 125 deletions.
124 changes: 1 addition & 123 deletions x-pack/plugins/maps/public/reducers/map/layer_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
}
}
35 changes: 33 additions & 2 deletions x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -40,6 +41,7 @@ import {
getIsAllowByValueEmbeddables,
getSavedObjectsTagging,
getTimeFilter,
getUsageCollection,
} from '../../../kibana_services';
import { goToSpecifiedPath } from '../../../render_app';
import { LayerDescriptor } from '../../../../common/descriptor_types';
Expand All @@ -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<MapSettings>) {
const decodedCustomIcons = settings.customIcons
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -224,7 +228,6 @@ export class SavedMap {
this._store.dispatch<any>(setHiddenLayers(this._mapEmbeddableInput.hiddenLayers));
}
this._initialLayerListConfig = copyPersistentState(layerList);
incrementLayerUsage(this._initialLayerListConfig);

if (this._defaultLayerWizard) {
this._store.dispatch<any>(setAutoOpenLayerWizardId(this._defaultLayerWizard));
Expand Down Expand Up @@ -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');
Expand Down

0 comments on commit 1cc2bf0

Please sign in to comment.