mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Datasource Config Editor: Add event-based funnel for measuring CVR (#55105)
* Added start event on adding new DS from datasources/new page * Added end event + tests * revert analytics.ts changes * revert azure tracking changes * changed version in doc * update props name for consistency with plugin-platform PR to come * Updated tests
This commit is contained in:
parent
fce0a49284
commit
6ee69853dc
@ -1,11 +1,12 @@
|
||||
import { thunkTester } from 'test/core/thunk/thunkTester';
|
||||
|
||||
import { DataSourceSettings } from '@grafana/data';
|
||||
import { AppPluginMeta, DataSourceSettings, PluginMetaInfo, PluginType } from '@grafana/data';
|
||||
import { FetchError } from '@grafana/runtime';
|
||||
import { ThunkResult, ThunkDispatch } from 'app/types';
|
||||
|
||||
import { getMockDataSource } from '../__mocks__';
|
||||
import * as api from '../api';
|
||||
import { trackDataSourceCreated, trackDataSourceTested } from '../tracking';
|
||||
import { GenericDataSourcePlugin } from '../types';
|
||||
|
||||
import {
|
||||
@ -14,6 +15,7 @@ import {
|
||||
TestDataSourceDependencies,
|
||||
initDataSourceSettings,
|
||||
loadDataSource,
|
||||
addDataSource,
|
||||
} from './actions';
|
||||
import {
|
||||
initDataSourceSettingsSucceeded,
|
||||
@ -22,13 +24,20 @@ import {
|
||||
testDataSourceSucceeded,
|
||||
testDataSourceFailed,
|
||||
dataSourceLoaded,
|
||||
dataSourcesLoaded,
|
||||
} from './reducers';
|
||||
|
||||
jest.mock('../api');
|
||||
jest.mock('app/core/services/backend_srv');
|
||||
jest.mock('app/core/core');
|
||||
jest.mock('@grafana/runtime', () => ({
|
||||
...(jest.requireActual('@grafana/runtime') as unknown as object),
|
||||
getBackendSrv: jest.fn(),
|
||||
getDataSourceSrv: jest.fn().mockReturnValue({ reload: jest.fn() }),
|
||||
getBackendSrv: jest.fn().mockReturnValue({ get: jest.fn() }),
|
||||
}));
|
||||
jest.mock('../tracking', () => ({
|
||||
trackDataSourceCreated: jest.fn(),
|
||||
trackDataSourceTested: jest.fn(),
|
||||
}));
|
||||
|
||||
const getBackendSrvMock = () =>
|
||||
@ -210,6 +219,8 @@ describe('testDataSource', () => {
|
||||
status: '',
|
||||
message: '',
|
||||
}),
|
||||
type: 'cloudwatch',
|
||||
uid: 'CW1234',
|
||||
}),
|
||||
} as any),
|
||||
getBackendSrv: getBackendSrvMock,
|
||||
@ -222,9 +233,15 @@ describe('testDataSource', () => {
|
||||
};
|
||||
const dispatchedActions = await thunkTester(state)
|
||||
.givenThunk(testDataSource)
|
||||
.whenThunkIsDispatched('Azure Monitor', dependencies);
|
||||
.whenThunkIsDispatched('CloudWatch', dependencies);
|
||||
|
||||
expect(dispatchedActions).toEqual([testDataSourceStarting(), testDataSourceSucceeded(state.testingStatus)]);
|
||||
expect(trackDataSourceTested).toHaveBeenCalledWith({
|
||||
plugin_id: 'cloudwatch',
|
||||
datasource_uid: 'CW1234',
|
||||
grafana_version: '1.0',
|
||||
success: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('then testDataSourceFailed should be dispatched', async () => {
|
||||
@ -235,6 +252,8 @@ describe('testDataSource', () => {
|
||||
testDatasource: jest.fn().mockImplementation(() => {
|
||||
throw new Error('Error testing datasource');
|
||||
}),
|
||||
type: 'azure-monitor',
|
||||
uid: 'azM0nit0R',
|
||||
}),
|
||||
} as any),
|
||||
getBackendSrv: getBackendSrvMock,
|
||||
@ -253,6 +272,12 @@ describe('testDataSource', () => {
|
||||
.whenThunkIsDispatched('Azure Monitor', dependencies);
|
||||
|
||||
expect(dispatchedActions).toEqual([testDataSourceStarting(), testDataSourceFailed(result)]);
|
||||
expect(trackDataSourceTested).toHaveBeenCalledWith({
|
||||
plugin_id: 'azure-monitor',
|
||||
datasource_uid: 'azM0nit0R',
|
||||
grafana_version: '1.0',
|
||||
success: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('then testDataSourceFailed should be dispatched with response error message', async () => {
|
||||
@ -304,3 +329,34 @@ describe('testDataSource', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('addDataSource', () => {
|
||||
it('it creates a datasource and calls trackDataSourceCreated ', async () => {
|
||||
const meta: AppPluginMeta = {
|
||||
id: 'azure-monitor',
|
||||
module: '',
|
||||
baseUrl: 'xxx',
|
||||
info: { version: '1.2.3' } as PluginMetaInfo,
|
||||
type: PluginType.datasource,
|
||||
name: 'test DS',
|
||||
};
|
||||
const state = {
|
||||
dataSources: {
|
||||
dataSources: [],
|
||||
},
|
||||
};
|
||||
const dataSourceMock = { datasource: { uid: 'azure23' }, meta };
|
||||
(api.createDataSource as jest.Mock).mockResolvedValueOnce(dataSourceMock);
|
||||
(api.getDataSources as jest.Mock).mockResolvedValueOnce([]);
|
||||
|
||||
const dispatchedActions = await thunkTester(state).givenThunk(addDataSource).whenThunkIsDispatched(meta);
|
||||
|
||||
expect(dispatchedActions).toEqual([dataSourcesLoaded([])]);
|
||||
expect(trackDataSourceCreated).toHaveBeenCalledWith({
|
||||
plugin_id: 'azure-monitor',
|
||||
plugin_version: '1.2.3',
|
||||
datasource_uid: 'azure23',
|
||||
grafana_version: '1.0',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { DataSourcePluginMeta, DataSourceSettings, locationUtil } from '@grafana/data';
|
||||
import {
|
||||
config,
|
||||
DataSourceWithBackend,
|
||||
getDataSourceSrv,
|
||||
HealthCheckError,
|
||||
@ -17,6 +18,7 @@ import { DataSourcePluginCategory, ThunkDispatch, ThunkResult } from 'app/types'
|
||||
|
||||
import * as api from '../api';
|
||||
import { DATASOURCES_ROUTES } from '../constants';
|
||||
import { trackDataSourceCreated, trackDataSourceTested } from '../tracking';
|
||||
import { nameExits, findNewName } from '../utils';
|
||||
|
||||
import { buildCategories } from './buildCategories';
|
||||
@ -107,6 +109,12 @@ export const testDataSource = (
|
||||
const result = await dsApi.testDatasource();
|
||||
|
||||
dispatch(testDataSourceSucceeded(result));
|
||||
trackDataSourceTested({
|
||||
grafana_version: config.buildInfo.version,
|
||||
plugin_id: dsApi.type,
|
||||
datasource_uid: dsApi.uid,
|
||||
success: true,
|
||||
});
|
||||
} catch (err) {
|
||||
let message: string | undefined;
|
||||
let details: HealthCheckResultDetails;
|
||||
@ -121,6 +129,12 @@ export const testDataSource = (
|
||||
}
|
||||
|
||||
dispatch(testDataSourceFailed({ message, details }));
|
||||
trackDataSourceTested({
|
||||
grafana_version: config.buildInfo.version,
|
||||
plugin_id: dsApi.type,
|
||||
datasource_uid: dsApi.uid,
|
||||
success: false,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
@ -197,6 +211,13 @@ export function addDataSource(plugin: DataSourcePluginMeta, editLink = DATASOURC
|
||||
await getDatasourceSrv().reload();
|
||||
await contextSrv.fetchUserPermissions();
|
||||
|
||||
trackDataSourceCreated({
|
||||
grafana_version: config.buildInfo.version,
|
||||
plugin_id: plugin.id,
|
||||
datasource_uid: result.datasource.uid,
|
||||
plugin_version: result.meta?.info?.version,
|
||||
});
|
||||
|
||||
locationService.push(editLink.replace(/:uid/gi, result.datasource.uid));
|
||||
};
|
||||
}
|
||||
|
54
public/app/features/datasources/tracking.ts
Normal file
54
public/app/features/datasources/tracking.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
|
||||
/**
|
||||
* Used to track data source creation via either the specific plugin page `/plugins/<the-data-source>`
|
||||
* or the general datasources page `/datasources/new`
|
||||
*
|
||||
* This event corresponds to the start event of our data source creation funnel.
|
||||
* Combined with the end event, it allows answering questions about:
|
||||
* - Conversion (percentage of user that successfully set up a data source)
|
||||
* - Time spent on the config page
|
||||
*
|
||||
* Changelog:
|
||||
* - v9.1.7 : logging datasource, datasource_uid, grafana version
|
||||
*/
|
||||
export const trackDataSourceCreated = (props: DataSourceCreatedProps) => {
|
||||
reportInteraction('grafana_ds_add_datasource_clicked', props);
|
||||
};
|
||||
|
||||
type DataSourceCreatedProps = {
|
||||
grafana_version?: string;
|
||||
/** The unique id of the newly created data source */
|
||||
datasource_uid: string;
|
||||
/** The datasource id (e.g. Cloudwatch, Loki, Prometheus) */
|
||||
plugin_id: string;
|
||||
/** The plugin version (especially interesting in external plugins - core plugins are aligned with grafana version) */
|
||||
plugin_version?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to track data source testing
|
||||
*
|
||||
* This event corresponds to the end event of our data source creation funnel.
|
||||
* Combined with the start event, it allows answering questions about:
|
||||
* - Conversion (percentage of user that successfully set up a data source)
|
||||
* - Time spent on the config page
|
||||
*
|
||||
* Changelog:
|
||||
* - v9.1.7 : logging datasource, datasource_uid, grafana version and success
|
||||
*/
|
||||
export const trackDataSourceTested = (props: DataSourceTestedProps) => {
|
||||
reportInteraction('grafana_ds_test_datasource_clicked', props);
|
||||
};
|
||||
|
||||
type DataSourceTestedProps = {
|
||||
grafana_version?: string;
|
||||
/** The unique id of the newly created data source */
|
||||
datasource_uid: string;
|
||||
/** The datasource id (e.g. Cloudwatch, Loki, Prometheus) */
|
||||
plugin_id: string;
|
||||
/** The plugin version (especially interesting in external plugins - core plugins are aligned with grafana version) */
|
||||
plugin_version?: string;
|
||||
/** Whether or not the datasource test succeeded = the datasource was successfully configured */
|
||||
success: boolean;
|
||||
};
|
Loading…
Reference in New Issue
Block a user