From 6be341d505731afad94763ba94f02e06341da8a5 Mon Sep 17 00:00:00 2001 From: Brendan O'Handley Date: Fri, 13 Jan 2023 12:13:52 -0500 Subject: [PATCH] Prometheus: Add query tracking (#61004) * merge fix * remove comments from debugging --- .../datasource/prometheus/datasource.tsx | 19 ++++---- .../plugins/datasource/prometheus/tracking.ts | 46 +++++++++++++++++++ 2 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 public/app/plugins/datasource/prometheus/tracking.ts diff --git a/public/app/plugins/datasource/prometheus/datasource.tsx b/public/app/plugins/datasource/prometheus/datasource.tsx index f21492ecc01..872c9b3c0fe 100644 --- a/public/app/plugins/datasource/prometheus/datasource.tsx +++ b/public/app/plugins/datasource/prometheus/datasource.tsx @@ -51,6 +51,7 @@ import { renderLegendFormat } from './legend'; import PrometheusMetricFindQuery from './metric_find_query'; import { getInitHints, getQueryHints } from './query_hints'; import { getOriginalMetricName, transform, transformV2 } from './result_transformer'; +import { trackQuery } from './tracking'; import { ExemplarTraceIdDestination, PromDataErrorResponse, @@ -440,14 +441,15 @@ export class PrometheusDatasource query(request: DataQueryRequest): Observable { if (this.access === 'proxy') { const targets = request.targets.map((target) => this.processTargetV2(target, request)); - - return super - .query({ ...request, targets: targets.flat() }) - .pipe( - map((response) => - transformV2(response, request, { exemplarTraceIdDestinations: this.exemplarTraceIdDestinations }) - ) - ); + const startTime = new Date(); + return super.query({ ...request, targets: targets.flat() }).pipe( + map((response) => + transformV2(response, request, { exemplarTraceIdDestinations: this.exemplarTraceIdDestinations }) + ), + tap((response: DataQueryResponse) => { + trackQuery(response, request, startTime); + }) + ); // Run queries trough browser/proxy } else { const start = this.getPrometheusTime(request.range.from, false); @@ -607,6 +609,7 @@ export class PrometheusDatasource ...this.getRangeScopedVars(options.range), }); } + query.step = interval; let expr = target.expr; diff --git a/public/app/plugins/datasource/prometheus/tracking.ts b/public/app/plugins/datasource/prometheus/tracking.ts new file mode 100644 index 00000000000..1e20523adf1 --- /dev/null +++ b/public/app/plugins/datasource/prometheus/tracking.ts @@ -0,0 +1,46 @@ +import { CoreApp, DataQueryRequest, DataQueryResponse } from '@grafana/data'; +import { reportInteraction, config } from '@grafana/runtime'; + +import { PromQuery } from './types'; + +export function trackQuery( + response: DataQueryResponse, + request: DataQueryRequest & { targets: PromQuery[] }, + startTime: Date +): void { + const { app, targets: queries } = request; + // We do want to track panel-editor and explore + // We do not want to track queries from the dashboard or viewing a panel + // also included in the tracking is cloud-alerting, unified-alerting, and unknown + if (app === CoreApp.Dashboard || app === CoreApp.PanelViewer) { + return; + } + + for (const query of queries) { + reportInteraction('grafana_prometheus_query_executed', { + app, + grafana_version: config.buildInfo.version, + has_data: response.data.some((frame) => frame.length > 0), + has_error: response.error !== undefined, + expr: query.expr, + format: query.format, + instant: query.instant, + range: query.range, + exemplar: query.exemplar, + hinting: query.hinting, + interval: query.interval, + intervalFactor: query.intervalFactor, + utcOffsetSec: query.utcOffsetSec, + legend: query.legendFormat, + valueWithRefId: query.valueWithRefId, + requestId: query.requestId, + showingGraph: query.showingGraph, + showingTable: query.showingTable, + editor_mode: query.editorMode, + simultaneously_sent_query_count: queries.length, + time_range_from: request?.range?.from?.toISOString(), + time_range_to: request?.range?.to?.toISOString(), + time_taken: Date.now() - startTime.getTime(), + }); + } +}