Commit d825b9e7 by Agnès Toulet Committed by GitHub

Analytics: Send event when opening a dashboard (#22921)

* Analytics: add open dashboard event

* Analytics: move code to analyticsProcessor

* Dashboard: fix init tests

* Analytics: remove open event for new dashboard

* Analytics: rename analyticsProcessor functions
parent 8e1fe6a9
import { EchoEvent, EchoEventType } from '../services/EchoSrv'; import { EchoEvent, EchoEventType } from '../services/EchoSrv';
export interface MetaAnalyticsEventPayload { export interface DashboardInfo {
eventName: string; dashboardId: number;
dashboardId?: number; dashboardUid: string;
dashboardUid?: string; dashboardName: string;
dashboardName?: string;
folderName?: string; folderName?: string;
panelId?: number; }
panelName?: string;
export interface DataRequestInfo extends Partial<DashboardInfo> {
datasourceName: string; datasourceName: string;
datasourceId?: number; datasourceId?: number;
error?: string; panelId?: number;
panelName?: string;
duration: number; duration: number;
error?: string;
dataSize?: number; dataSize?: number;
} }
export enum MetaAnalyticsEventName {
DashboardView = 'dashboard-view',
DataRequest = 'data-request',
}
export interface DashboardViewEventPayload extends DashboardInfo {
eventName: MetaAnalyticsEventName.DashboardView;
}
export interface DataRequestEventPayload extends DataRequestInfo {
eventName: MetaAnalyticsEventName.DataRequest;
}
export type MetaAnalyticsEventPayload = DashboardViewEventPayload | DataRequestEventPayload;
export interface MetaAnalyticsEvent extends EchoEvent<EchoEventType.MetaAnalytics, MetaAnalyticsEventPayload> {} export interface MetaAnalyticsEvent extends EchoEvent<EchoEventType.MetaAnalytics, MetaAnalyticsEventPayload> {}
import { getDashboardSrv } from '../services/DashboardSrv'; import { getDashboardSrv } from '../services/DashboardSrv';
import { DashboardModel } from './DashboardModel';
import { PanelData, LoadingState, DataSourceApi } from '@grafana/data'; import { PanelData, LoadingState, DataSourceApi } from '@grafana/data';
import { reportMetaAnalytics, MetaAnalyticsEventPayload } from '@grafana/runtime'; import {
reportMetaAnalytics,
MetaAnalyticsEventName,
DataRequestEventPayload,
DashboardViewEventPayload,
} from '@grafana/runtime';
export function getAnalyticsProcessor(datasource: DataSourceApi) { export function emitDataRequestEvent(datasource: DataSourceApi) {
let done = false; let done = false;
return (data: PanelData) => { return (data: PanelData) => {
...@@ -16,16 +22,14 @@ export function getAnalyticsProcessor(datasource: DataSourceApi) { ...@@ -16,16 +22,14 @@ export function getAnalyticsProcessor(datasource: DataSourceApi) {
return; return;
} }
const eventData: MetaAnalyticsEventPayload = { const eventData: DataRequestEventPayload = {
eventName: MetaAnalyticsEventName.DataRequest,
datasourceName: datasource.name, datasourceName: datasource.name,
datasourceId: datasource.id, datasourceId: datasource.id,
panelId: data.request.panelId, panelId: data.request.panelId,
dashboardId: data.request.dashboardId, dashboardId: data.request.dashboardId,
// app: 'dashboard',
dataSize: 0, dataSize: 0,
duration: data.request.endTime - data.request.startTime, duration: data.request.endTime - data.request.startTime,
eventName: 'data-request',
// sessionId: '',
}; };
// enrich with dashboard info // enrich with dashboard info
...@@ -53,3 +57,15 @@ export function getAnalyticsProcessor(datasource: DataSourceApi) { ...@@ -53,3 +57,15 @@ export function getAnalyticsProcessor(datasource: DataSourceApi) {
done = true; done = true;
}; };
} }
export function emitDashboardViewEvent(dashboard: DashboardModel) {
const eventData: DashboardViewEventPayload = {
dashboardId: dashboard.id,
dashboardName: dashboard.title,
dashboardUid: dashboard.uid,
folderName: dashboard.meta.folderTitle,
eventName: MetaAnalyticsEventName.DashboardView,
};
reportMetaAnalytics(eventData);
}
...@@ -5,6 +5,8 @@ import { DashboardRouteInfo } from 'app/types'; ...@@ -5,6 +5,8 @@ import { DashboardRouteInfo } from 'app/types';
import { getBackendSrv } from 'app/core/services/backend_srv'; import { getBackendSrv } from 'app/core/services/backend_srv';
import { dashboardInitCompleted, dashboardInitFetching, dashboardInitServices } from './reducers'; import { dashboardInitCompleted, dashboardInitFetching, dashboardInitServices } from './reducers';
import { updateLocation } from '../../../core/actions'; import { updateLocation } from '../../../core/actions';
import { setEchoSrv } from '@grafana/runtime';
import { Echo } from '../../../core/services/echo/Echo';
jest.mock('app/core/services/backend_srv'); jest.mock('app/core/services/backend_srv');
...@@ -124,6 +126,7 @@ function describeInitScenario(description: string, scenarioFn: ScenarioFn) { ...@@ -124,6 +126,7 @@ function describeInitScenario(description: string, scenarioFn: ScenarioFn) {
beforeEach(async () => { beforeEach(async () => {
setupFn(); setupFn();
setEchoSrv(new Echo());
const store = mockStore(ctx.storeState); const store = mockStore(ctx.storeState);
// @ts-ignore // @ts-ignore
......
...@@ -25,6 +25,7 @@ import { DataQuery } from '@grafana/data'; ...@@ -25,6 +25,7 @@ import { DataQuery } from '@grafana/data';
import { getConfig } from '../../../core/config'; import { getConfig } from '../../../core/config';
import { initDashboardTemplating, processVariables } from '../../variables/state/actions'; import { initDashboardTemplating, processVariables } from '../../variables/state/actions';
import { variableAdapters } from '../../variables/adapters'; import { variableAdapters } from '../../variables/adapters';
import { emitDashboardViewEvent } from './analyticsProcessor';
export interface InitDashboardArgs { export interface InitDashboardArgs {
$injector: any; $injector: any;
...@@ -223,6 +224,11 @@ export function initDashboard(args: InitDashboardArgs): ThunkResult<void> { ...@@ -223,6 +224,11 @@ export function initDashboard(args: InitDashboardArgs): ThunkResult<void> {
// legacy srv state // legacy srv state
dashboardSrv.setCurrent(dashboard); dashboardSrv.setCurrent(dashboard);
// send open dashboard event
if (args.routeInfo !== DashboardRouteInfo.New) {
emitDashboardViewEvent(dashboard);
}
// yay we are done // yay we are done
dispatch(dashboardInitCompleted(dashboard)); dispatch(dashboardInitCompleted(dashboard));
}; };
......
...@@ -18,7 +18,7 @@ import { ...@@ -18,7 +18,7 @@ import {
DataFrame, DataFrame,
guessFieldTypes, guessFieldTypes,
} from '@grafana/data'; } from '@grafana/data';
import { getAnalyticsProcessor } from './analyticsProcessor'; import { emitDataRequestEvent } from './analyticsProcessor';
import { ExpressionDatasourceID, expressionDatasource } from 'app/features/expressions/ExpressionDatasource'; import { ExpressionDatasourceID, expressionDatasource } from 'app/features/expressions/ExpressionDatasource';
type MapOfResponsePackets = { [str: string]: DataQueryResponse }; type MapOfResponsePackets = { [str: string]: DataQueryResponse };
...@@ -120,7 +120,7 @@ export function runRequest(datasource: DataSourceApi, request: DataQueryRequest) ...@@ -120,7 +120,7 @@ export function runRequest(datasource: DataSourceApi, request: DataQueryRequest)
error: processQueryError(err), error: processQueryError(err),
}) })
), ),
tap(getAnalyticsProcessor(datasource)), tap(emitDataRequestEvent(datasource)),
// finalize is triggered when subscriber unsubscribes // finalize is triggered when subscriber unsubscribes
// This makes sure any still running network requests are cancelled // This makes sure any still running network requests are cancelled
finalize(cancelNetworkRequestsOnUnsubscribe(request)), finalize(cancelNetworkRequestsOnUnsubscribe(request)),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment