diff --git a/public/app/plugins/datasource/loki/configuration/ConfigEditor.tsx b/public/app/plugins/datasource/loki/configuration/ConfigEditor.tsx index c64c437b0d0..1e368aea391 100644 --- a/public/app/plugins/datasource/loki/configuration/ConfigEditor.tsx +++ b/public/app/plugins/datasource/loki/configuration/ConfigEditor.tsx @@ -1,7 +1,7 @@ -import React from 'react'; +import React, { useCallback } from 'react'; import { DataSourcePluginOptionsEditorProps, DataSourceSettings } from '@grafana/data'; -import { config } from '@grafana/runtime'; +import { config, reportInteraction } from '@grafana/runtime'; import { AlertingSettings, DataSourceHttpSettings } from '@grafana/ui'; import { LokiOptions } from '../types'; @@ -30,6 +30,14 @@ const setDerivedFields = makeJsonUpdater('derivedFields'); export const ConfigEditor = (props: Props) => { const { options, onOptionsChange } = props; + const updatePredefinedOperations = useCallback( + (value: string) => { + reportInteraction('grafana_loki_predefined_operations_changed', { value }); + onOptionsChange(setPredefinedOperations(options, value)); + }, + [options, onOptionsChange] + ); + return ( <> { maxLines={options.jsonData.maxLines || ''} onMaxLinedChange={(value) => onOptionsChange(setMaxLines(options, value))} predefinedOperations={options.jsonData.predefinedOperations || ''} - onPredefinedOperationsChange={(value) => onOptionsChange(setPredefinedOperations(options, value))} + onPredefinedOperationsChange={updatePredefinedOperations} /> trackQuery(response, fixedRequest, startTime))); + return this.runQuery(fixedRequest).pipe( + tap((response) => + trackQuery(response, fixedRequest, startTime, { predefinedOperations: this.predefinedOperations }) + ) + ); } runQuery(fixedRequest: DataQueryRequest) { diff --git a/public/app/plugins/datasource/loki/querySplitting.test.ts b/public/app/plugins/datasource/loki/querySplitting.test.ts index 107a2bf548f..06e5c413e33 100644 --- a/public/app/plugins/datasource/loki/querySplitting.test.ts +++ b/public/app/plugins/datasource/loki/querySplitting.test.ts @@ -91,7 +91,8 @@ describe('runSplitQuery()', () => { }, ], request, - new Date() + new Date(), + { predefinedOperations: '' } ); }); }); diff --git a/public/app/plugins/datasource/loki/querySplitting.ts b/public/app/plugins/datasource/loki/querySplitting.ts index a5c07af654d..36fb89c61ce 100644 --- a/public/app/plugins/datasource/loki/querySplitting.ts +++ b/public/app/plugins/datasource/loki/querySplitting.ts @@ -281,7 +281,9 @@ export function runSplitQuery(datasource: LokiDatasource, request: DataQueryRequ return runSplitGroupedQueries(datasource, requests).pipe( tap((response) => { if (response.state === LoadingState.Done) { - trackGroupedQueries(response, requests, request, startTime); + trackGroupedQueries(response, requests, request, startTime, { + predefinedOperations: datasource.predefinedOperations, + }); } }) ); diff --git a/public/app/plugins/datasource/loki/tracking.test.ts b/public/app/plugins/datasource/loki/tracking.test.ts index 34ee5a6efbd..24d530efbdf 100644 --- a/public/app/plugins/datasource/loki/tracking.test.ts +++ b/public/app/plugins/datasource/loki/tracking.test.ts @@ -92,6 +92,35 @@ test('Tracks queries', () => { time_range_from: '2023-02-08T05:00:00.000Z', time_range_to: '2023-02-10T06:00:00.000Z', time_taken: 0, + predefined_operations_applied: 'n/a', + }); +}); + +test('Tracks predefined operations', () => { + trackQuery({ data: [] }, originalRequest, new Date(), { predefinedOperations: 'count_over_time' }); + + expect(reportInteraction).toHaveBeenCalledWith('grafana_loki_query_executed', { + app: 'explore', + bytes_processed: 0, + editor_mode: 'builder', + grafana_version: '1.0', + has_data: false, + has_error: false, + is_split: false, + legend: undefined, + line_limit: undefined, + obfuscated_query: 'count_over_time({Identifier=String}[1m])', + parsed_query: + 'LogQL,Expr,MetricExpr,RangeAggregationExpr,RangeOp,CountOverTime,LogRangeExpr,Selector,Matchers,Matcher,Identifier,Eq,String,Range,Duration', + query_type: 'metric', + query_vector_type: undefined, + resolution: 1, + simultaneously_executed_query_count: 2, + simultaneously_hidden_query_count: 1, + time_range_from: '2023-02-08T05:00:00.000Z', + time_range_to: '2023-02-10T06:00:00.000Z', + time_taken: 0, + predefined_operations_applied: true, }); }); @@ -123,6 +152,7 @@ test('Tracks grouped queries', () => { time_range_from: '2023-02-08T05:00:00.000Z', time_range_to: '2023-02-10T06:00:00.000Z', time_taken: 0, + predefined_operations_applied: 'n/a', }); expect(reportInteraction).toHaveBeenCalledWith('grafana_loki_query_executed', { @@ -149,5 +179,6 @@ test('Tracks grouped queries', () => { time_range_from: '2023-02-08T05:00:00.000Z', time_range_to: '2023-02-10T06:00:00.000Z', time_taken: 0, + predefined_operations_applied: 'n/a', }); }); diff --git a/public/app/plugins/datasource/loki/tracking.ts b/public/app/plugins/datasource/loki/tracking.ts index 7ed19a40ea6..cd6c117e147 100644 --- a/public/app/plugins/datasource/loki/tracking.ts +++ b/public/app/plugins/datasource/loki/tracking.ts @@ -53,6 +53,10 @@ type LokiOnDashboardLoadedTrackingEvent = { queries_with_changed_legend_count: number; }; +export type LokiTrackingSettings = { + predefinedOperations?: string; +}; + export const onDashboardLoadedHandler = ({ payload: { dashboardId, orgId, grafanaVersion, queries }, }: DashboardLoadedEvent) => { @@ -148,6 +152,7 @@ export function trackQuery( response: DataQueryResponse, request: DataQueryRequest, startTime: Date, + trackingSettings: LokiTrackingSettings = {}, extraPayload: Record = {} ): void { // We only want to track usage for these specific apps @@ -184,6 +189,9 @@ export function trackQuery( time_taken: Date.now() - startTime.getTime(), bytes_processed: totalBytes, is_split: false, + predefined_operations_applied: trackingSettings.predefinedOperations + ? query.expr.includes(trackingSettings.predefinedOperations) + : 'n/a', ...extraPayload, }); } @@ -193,7 +201,8 @@ export function trackGroupedQueries( response: DataQueryResponse, groupedRequests: LokiGroupedRequest[], originalRequest: DataQueryRequest, - startTime: Date + startTime: Date, + trackingSettings: LokiTrackingSettings = {} ): void { const splittingPayload = { split_query_group_count: groupedRequests.length, @@ -206,7 +215,7 @@ export function trackGroupedQueries( for (const group of groupedRequests) { const split_query_partition_size = group.partition.length; - trackQuery(response, group.request, startTime, { + trackQuery(response, group.request, startTime, trackingSettings, { ...splittingPayload, split_query_partition_size, });