mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
#121908 - [Maps] Use UI counters to instrument when a geo field is visualized with visualizeGeoFieldAction (#123540)
* #121908 - Maps usage tracking feature * #e-121908 - refactoring; Added naming constants for used apps; * #121908 - updates for UiCounterMetricType, schema, metric analytics * #121908 - refactoring; Fixed import syntax, type in report * #121908 - refactoring * #121908 - refactoring * 121908 - refactoring Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
81c5fbf538
commit
cf102be8be
14 changed files with 56 additions and 46 deletions
|
@ -8,16 +8,20 @@
|
|||
|
||||
import { METRIC_TYPE } from './';
|
||||
|
||||
export type UiCounterMetricType = METRIC_TYPE.CLICK | METRIC_TYPE.LOADED | METRIC_TYPE.COUNT;
|
||||
export type UiCounterMetricType =
|
||||
| METRIC_TYPE.CLICK
|
||||
| METRIC_TYPE.LOADED
|
||||
| METRIC_TYPE.COUNT
|
||||
| string;
|
||||
export interface UiCounterMetricConfig {
|
||||
type: UiCounterMetricType;
|
||||
type: string;
|
||||
appName: string;
|
||||
eventName: string;
|
||||
count?: number;
|
||||
}
|
||||
|
||||
export interface UiCounterMetric {
|
||||
type: UiCounterMetricType;
|
||||
type: string;
|
||||
appName: string;
|
||||
eventName: string;
|
||||
count: number;
|
||||
|
|
|
@ -7,11 +7,15 @@
|
|||
*/
|
||||
|
||||
import moment from 'moment-timezone';
|
||||
import { UnreachableCaseError, wrapArray } from './util';
|
||||
import { wrapArray } from './util';
|
||||
import { ApplicationUsageTracker } from './application_usage_tracker';
|
||||
import { Metric, UiCounterMetricType, METRIC_TYPE } from './metrics';
|
||||
import { Metric, METRIC_TYPE } from './metrics';
|
||||
const REPORT_VERSION = 3;
|
||||
|
||||
import type { UiCounterMetric, UiCounterMetricType } from './metrics/ui_counter';
|
||||
import type { UserAgentMetric } from './metrics/user_agent';
|
||||
import type { ApplicationUsageMetric } from './metrics/application_usage';
|
||||
|
||||
export interface Report {
|
||||
reportVersion: typeof REPORT_VERSION;
|
||||
uiCounter?: Record<
|
||||
|
@ -77,55 +81,35 @@ export class ReportManager {
|
|||
const { appName, type } = metric;
|
||||
return `${appName}-${type}`;
|
||||
}
|
||||
case METRIC_TYPE.CLICK:
|
||||
case METRIC_TYPE.LOADED:
|
||||
case METRIC_TYPE.COUNT: {
|
||||
const { appName, eventName, type } = metric;
|
||||
return `${appName}-${type}-${eventName}`;
|
||||
}
|
||||
case METRIC_TYPE.APPLICATION_USAGE: {
|
||||
const { appId, viewId } = metric;
|
||||
const { appId, viewId } = metric as ApplicationUsageMetric;
|
||||
return ApplicationUsageTracker.serializeKey({ appId, viewId });
|
||||
}
|
||||
default:
|
||||
throw new UnreachableCaseError(metric);
|
||||
const { appName, eventName, type } = metric as UiCounterMetric;
|
||||
return `${appName}-${type}-${eventName}`;
|
||||
}
|
||||
}
|
||||
private assignReport(report: Report, metric: Metric) {
|
||||
const key = ReportManager.createMetricKey(metric);
|
||||
switch (metric.type) {
|
||||
case METRIC_TYPE.USER_AGENT: {
|
||||
const { appName, type, userAgent } = metric;
|
||||
const { appName, type, userAgent } = metric as UserAgentMetric;
|
||||
if (userAgent) {
|
||||
report.userAgent = {
|
||||
[key]: {
|
||||
key,
|
||||
appName,
|
||||
type,
|
||||
userAgent: metric.userAgent,
|
||||
userAgent,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
case METRIC_TYPE.CLICK:
|
||||
case METRIC_TYPE.LOADED:
|
||||
case METRIC_TYPE.COUNT: {
|
||||
const { appName, type, eventName, count } = metric;
|
||||
report.uiCounter = report.uiCounter || {};
|
||||
const currentTotal = report.uiCounter[key]?.total;
|
||||
report.uiCounter[key] = {
|
||||
key,
|
||||
appName,
|
||||
eventName,
|
||||
type,
|
||||
total: this.incrementTotal(count, currentTotal),
|
||||
};
|
||||
return;
|
||||
}
|
||||
case METRIC_TYPE.APPLICATION_USAGE: {
|
||||
const { numberOfClicks, startTime, appId, viewId } = metric;
|
||||
const { numberOfClicks, startTime, appId, viewId } = metric as ApplicationUsageMetric;
|
||||
const minutesOnScreen = moment().diff(startTime, 'minutes', true);
|
||||
|
||||
report.application_usage = report.application_usage || {};
|
||||
|
@ -144,7 +128,17 @@ export class ReportManager {
|
|||
return;
|
||||
}
|
||||
default:
|
||||
throw new UnreachableCaseError(metric);
|
||||
const { appName, type, eventName, count } = metric as UiCounterMetric;
|
||||
report.uiCounter = report.uiCounter || {};
|
||||
const currentTotal = report.uiCounter[key]?.total;
|
||||
report.uiCounter[key] = {
|
||||
key,
|
||||
appName,
|
||||
eventName,
|
||||
type,
|
||||
total: this.incrementTotal(count, currentTotal),
|
||||
};
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,13 +7,7 @@
|
|||
*/
|
||||
|
||||
import { wrapArray } from './util';
|
||||
import {
|
||||
Metric,
|
||||
createUiCounterMetric,
|
||||
trackUsageAgent,
|
||||
UiCounterMetricType,
|
||||
ApplicationUsageMetric,
|
||||
} from './metrics';
|
||||
import { Metric, createUiCounterMetric, trackUsageAgent, ApplicationUsageMetric } from './metrics';
|
||||
|
||||
import { Storage, ReportStorageManager } from './storage';
|
||||
import { Report, ReportManager } from './report';
|
||||
|
@ -77,7 +71,7 @@ export class Reporter {
|
|||
|
||||
public reportUiCounter = (
|
||||
appName: string,
|
||||
type: UiCounterMetricType,
|
||||
type: string,
|
||||
eventNames: string | string[],
|
||||
count?: number
|
||||
) => {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export const APP_ID = 'discover';
|
||||
export const DEFAULT_COLUMNS_SETTING = 'defaultColumns';
|
||||
export const SAMPLE_SIZE_SETTING = 'discover:sampleSize';
|
||||
export const SORT_DEFAULT_ORDER_SETTING = 'discover:sort:defaultOrder';
|
||||
|
|
|
@ -14,6 +14,7 @@ import {
|
|||
} from '../../../../../../../ui_actions/public';
|
||||
import { getUiActions } from '../../../../../kibana_services';
|
||||
import { DataViewField, KBN_FIELD_TYPES } from '../../../../../../../data/common';
|
||||
import { APP_ID } from '../../../../../../common';
|
||||
|
||||
function getTriggerConstant(type: string) {
|
||||
return type === KBN_FIELD_TYPES.GEO_POINT || type === KBN_FIELD_TYPES.GEO_SHAPE
|
||||
|
@ -52,6 +53,7 @@ export function triggerVisualizeActions(
|
|||
indexPatternId,
|
||||
fieldName: field.name,
|
||||
contextualFields,
|
||||
originatingApp: APP_ID,
|
||||
};
|
||||
getUiActions().getTrigger(trigger).exec(triggerOptions);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ export interface VisualizeFieldContext {
|
|||
fieldName: string;
|
||||
indexPatternId: string;
|
||||
contextualFields?: string[];
|
||||
originatingApp?: string;
|
||||
}
|
||||
|
||||
export const ACTION_VISUALIZE_FIELD = 'ACTION_VISUALIZE_FIELD';
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
|
||||
import { schema, TypeOf } from '@kbn/config-schema';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
|
||||
const applicationUsageReportSchema = schema.object({
|
||||
minutesOnScreen: schema.number(),
|
||||
|
@ -34,11 +33,7 @@ export const reportSchema = schema.object({
|
|||
schema.string(),
|
||||
schema.object({
|
||||
key: schema.string(),
|
||||
type: schema.oneOf([
|
||||
schema.literal<METRIC_TYPE>(METRIC_TYPE.CLICK),
|
||||
schema.literal<METRIC_TYPE>(METRIC_TYPE.LOADED),
|
||||
schema.literal<METRIC_TYPE>(METRIC_TYPE.COUNT),
|
||||
]),
|
||||
type: schema.string(),
|
||||
appName: schema.string(),
|
||||
eventName: schema.string(),
|
||||
total: schema.number(),
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { KBN_FIELD_TYPES } from '../../../../src/plugins/data/common';
|
||||
|
||||
export const APP_ID = 'data_visualizer';
|
||||
export const UI_SETTING_MAX_FILE_SIZE = 'fileUpload:maxFileSize';
|
||||
|
||||
export const MB = Math.pow(2, 20);
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
} from '../../../../index_data_visualizer/services/timefilter_refresh_service';
|
||||
import { JOB_FIELD_TYPES } from '../../../../../../common/constants';
|
||||
import { VISUALIZE_GEO_FIELD_TRIGGER } from '../../../../../../../../../src/plugins/ui_actions/public';
|
||||
import { APP_ID } from '../../../../../../common/constants';
|
||||
|
||||
export function getActions(
|
||||
indexPattern: IndexPattern,
|
||||
|
@ -87,6 +88,7 @@ export function getActions(
|
|||
indexPatternId: indexPattern.id,
|
||||
fieldName: item.fieldName,
|
||||
contextualFields: [],
|
||||
originatingApp: APP_ID,
|
||||
};
|
||||
const testActions = await services?.uiActions.getTriggerCompatibleActions(
|
||||
VISUALIZE_GEO_FIELD_TRIGGER,
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
import { getVisualizeGeoFieldMessage } from '../../../utils';
|
||||
import { DragDrop } from '../../../drag_drop';
|
||||
import { GlobeIllustration } from '../../../assets/globe_illustration';
|
||||
import { APP_ID } from '../../../../common/constants';
|
||||
import './geo_field_workspace_panel.scss';
|
||||
|
||||
interface Props {
|
||||
|
@ -41,6 +42,7 @@ export function GeoFieldWorkspacePanel(props: Props) {
|
|||
props.uiActions.getTrigger(VISUALIZE_GEO_FIELD_TRIGGER).exec({
|
||||
indexPatternId: props.indexPatternId,
|
||||
fieldName: props.fieldName,
|
||||
originatingApp: APP_ID,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
VISUALIZE_GEO_FIELD_TRIGGER,
|
||||
UiActionsStart,
|
||||
} from '../../../../../src/plugins/ui_actions/public';
|
||||
import { APP_ID } from '../../common/constants';
|
||||
|
||||
interface Props {
|
||||
indexPatternId: string;
|
||||
|
@ -50,6 +51,7 @@ export function VisualizeGeoFieldButton(props: Props) {
|
|||
props.uiActions.getTrigger(VISUALIZE_GEO_FIELD_TRIGGER).exec({
|
||||
indexPatternId: props.indexPatternId,
|
||||
fieldName: props.fieldName,
|
||||
originatingApp: APP_ID,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ export const getPresentationUtilContext = () => pluginsStart.presentationUtil.Co
|
|||
export const getSecurityService = () => pluginsStart.security;
|
||||
export const getSpacesApi = () => pluginsStart.spaces;
|
||||
export const getTheme = () => coreStart.theme;
|
||||
export const getUsageCollection = () => pluginsStart.usageCollection;
|
||||
|
||||
// xpack.maps.* kibana.yml settings from this plugin
|
||||
let mapAppConfig: MapsConfigType;
|
||||
|
|
|
@ -103,6 +103,7 @@ export interface MapsPluginStartDependencies {
|
|||
security?: SecurityPluginStart;
|
||||
spaces?: SpacesPluginStart;
|
||||
mapsEms: MapsEmsPluginPublicStart;
|
||||
usageCollection?: UsageCollectionSetup;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
import uuid from 'uuid/v4';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { SerializableRecord } from '@kbn/utility-types';
|
||||
import { getUsageCollection } from '../kibana_services';
|
||||
import { APP_ID } from '../../common/constants';
|
||||
|
||||
import {
|
||||
createAction,
|
||||
ACTION_VISUALIZE_GEO_FIELD,
|
||||
|
@ -43,6 +46,13 @@ export const visualizeGeoFieldAction = createAction<VisualizeFieldContext>({
|
|||
execute: async (context) => {
|
||||
const { app, path, state } = await getMapsLink(context);
|
||||
|
||||
const usageCollection = getUsageCollection();
|
||||
usageCollection?.reportUiCounter(
|
||||
APP_ID,
|
||||
'visualize_geo_field',
|
||||
context.originatingApp ? context.originatingApp : 'unknownOriginatingApp'
|
||||
);
|
||||
|
||||
getCore().application.navigateToApp(app, {
|
||||
path,
|
||||
state,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue