Tempo: dashboard feature tracking (#61210)

* grafana_tempo_dashboard_loaded

* Update version

* Updates

* Added more tracking stats + updates
matyax/snapping-test
Joey Tawadrous 2 years ago committed by GitHub
parent 98cadb3aa0
commit 58c4c95e92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      public/app/plugins/datasource/tempo/module.ts
  2. 113
      public/app/plugins/datasource/tempo/tracking.test.ts
  3. 91
      public/app/plugins/datasource/tempo/tracking.ts

@ -1,11 +1,17 @@
import { DataSourcePlugin } from '@grafana/data';
import { DataSourcePlugin, DashboardLoadedEvent } from '@grafana/data';
import { getAppEvents } from '@grafana/runtime';
import CheatSheet from './CheatSheet';
import { TempoQueryField } from './QueryEditor/QueryField';
import { ConfigEditor } from './configuration/ConfigEditor';
import { TempoDatasource } from './datasource';
import { onDashboardLoadedHandler } from './tracking';
import { TempoQuery } from './types';
export const plugin = new DataSourcePlugin(TempoDatasource)
.setQueryEditor(TempoQueryField)
.setConfigEditor(ConfigEditor)
.setQueryEditorHelp(CheatSheet);
// Subscribe to on dashboard loaded event so that we can track plugin adoption
getAppEvents().subscribe<DashboardLoadedEvent<TempoQuery>>(DashboardLoadedEvent, onDashboardLoadedHandler);

@ -0,0 +1,113 @@
import { DashboardLoadedEvent } from '@grafana/data';
import { reportInteraction } from '@grafana/runtime';
import './module';
jest.mock('@grafana/runtime', () => {
return {
...jest.requireActual('@grafana/runtime'),
reportInteraction: jest.fn(),
getAppEvents: () => ({
subscribe: jest.fn((_, handler) => {
handler(
new DashboardLoadedEvent({
dashboardId: 'dash',
orgId: 1,
userId: 1,
grafanaVersion: 'v9.4.0',
queries: {
tempo: [
{
datasource: { type: 'tempo', uid: 'abc' },
queryType: 'nativeSearch',
refId: 'A',
},
{
datasource: { type: 'tempo', uid: 'abc' },
queryType: 'nativeSearch',
spanName: 'HTTP',
refId: 'A',
},
{
datasource: { type: 'tempo', uid: 'abc' },
queryType: 'nativeSearch',
spanName: '$var',
refId: 'A',
},
{
datasource: { type: 'tempo', uid: 'abc' },
queryType: 'search',
linkedQuery: {
expr: '{}',
},
refId: 'A',
},
{
datasource: { type: 'tempo', uid: 'abc' },
queryType: 'search',
linkedQuery: {
expr: '{$var}',
},
refId: 'A',
},
{
datasource: { type: 'tempo', uid: 'abc' },
queryType: 'serviceMap',
serviceMapQuery: '{}',
refId: 'A',
},
{
datasource: { type: 'tempo', uid: 'abc' },
queryType: 'serviceMap',
serviceMapQuery: '{$var}',
refId: 'A',
},
{
datasource: { type: 'tempo', uid: 'abc' },
queryType: 'traceql',
query: '{}',
refId: 'A',
},
{
datasource: { type: 'tempo', uid: 'abc' },
queryType: 'traceql',
query: '{$var}',
refId: 'A',
},
{
datasource: { type: 'tempo', uid: 'abc' },
queryType: 'upload',
refId: 'A',
},
],
},
})
);
}),
}),
getTemplateSrv: () => ({
containsTemplate: (val: string): boolean => {
return val != null && val.includes('$');
},
}),
};
});
describe('on dashboard loaded', () => {
it('triggers reportInteraction with grafana_tempo_dashboard_loaded', () => {
expect(reportInteraction).toHaveBeenCalledWith('grafana_tempo_dashboard_loaded', {
grafana_version: 'v9.4.0',
dashboard_id: 'dash',
org_id: 1,
traceql_query_count: 2,
search_query_count: 2,
service_map_query_count: 2,
upload_query_count: 1,
native_search_query_count: 3,
traceql_queries_with_template_variables_count: 1,
search_queries_with_template_variables_count: 1,
service_map_queries_with_template_variables_count: 1,
native_search_queries_with_template_variables_count: 1,
});
});
});

@ -0,0 +1,91 @@
import { DashboardLoadedEvent } from '@grafana/data';
import { getTemplateSrv, reportInteraction } from '@grafana/runtime';
import pluginJson from './plugin.json';
import { TempoQuery } from './types';
type TempoOnDashboardLoadedTrackingEvent = {
grafana_version?: string;
dashboard_id?: string;
org_id?: number;
native_search_query_count: number;
search_query_count: number;
service_map_query_count: number;
traceql_query_count: number;
upload_query_count: number;
native_search_queries_with_template_variables_count: number;
search_queries_with_template_variables_count: number;
service_map_queries_with_template_variables_count: number;
traceql_queries_with_template_variables_count: number;
};
export const onDashboardLoadedHandler = ({
payload: { dashboardId, orgId, grafanaVersion, queries },
}: DashboardLoadedEvent<TempoQuery>) => {
try {
const tempoQueries = queries[pluginJson.id];
if (!tempoQueries?.length) {
return;
}
let stats: TempoOnDashboardLoadedTrackingEvent = {
grafana_version: grafanaVersion,
dashboard_id: dashboardId,
org_id: orgId,
native_search_query_count: 0,
search_query_count: 0,
service_map_query_count: 0,
traceql_query_count: 0,
upload_query_count: 0,
native_search_queries_with_template_variables_count: 0,
search_queries_with_template_variables_count: 0,
service_map_queries_with_template_variables_count: 0,
traceql_queries_with_template_variables_count: 0,
};
for (const query of tempoQueries) {
if (query.hide) {
continue;
}
if (query.queryType === 'nativeSearch') {
stats.native_search_query_count++;
if (
(query.serviceName && hasTemplateVariables(query.serviceName)) ||
(query.spanName && hasTemplateVariables(query.spanName)) ||
(query.search && hasTemplateVariables(query.search)) ||
(query.minDuration && hasTemplateVariables(query.minDuration)) ||
(query.maxDuration && hasTemplateVariables(query.maxDuration))
) {
stats.native_search_queries_with_template_variables_count++;
}
} else if (query.queryType === 'search') {
stats.search_query_count++;
if (query.linkedQuery && query.linkedQuery.expr && hasTemplateVariables(query.linkedQuery.expr)) {
stats.search_queries_with_template_variables_count++;
}
} else if (query.queryType === 'serviceMap') {
stats.service_map_query_count++;
if (query.serviceMapQuery && hasTemplateVariables(query.serviceMapQuery)) {
stats.service_map_queries_with_template_variables_count++;
}
} else if (query.queryType === 'traceql') {
stats.traceql_query_count++;
if (hasTemplateVariables(query.query)) {
stats.traceql_queries_with_template_variables_count++;
}
} else if (query.queryType === 'upload') {
stats.upload_query_count++;
}
}
reportInteraction('grafana_tempo_dashboard_loaded', stats);
} catch (error) {
console.error('error in tempo tracking handler', error);
}
};
const hasTemplateVariables = (val: string): boolean => {
return getTemplateSrv().containsTemplate(val);
};
Loading…
Cancel
Save