From 036e19037ed702bf4b63f16cc8b3b6f9d7b785db Mon Sep 17 00:00:00 2001 From: Andre Pereira Date: Thu, 29 Feb 2024 12:41:31 +0000 Subject: [PATCH] Tempo: Better fallbacks for metrics query (#83619) * Use query as fallback when there's one series and no labels. Use "" as the fallback for empty label values. Stop using the `promLabels` value from the Tempo response * Set refId to remove mentions of promLabels * Add quotes around the string value, add space after comma separator * Use name as refId when possible --- .../plugins/datasource/tempo/datasource.ts | 2 +- .../datasource/tempo/resultTransformer.ts | 32 ++++++++++++------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/public/app/plugins/datasource/tempo/datasource.ts b/public/app/plugins/datasource/tempo/datasource.ts index d2ada1f496b..96fcb05b88c 100644 --- a/public/app/plugins/datasource/tempo/datasource.ts +++ b/public/app/plugins/datasource/tempo/datasource.ts @@ -714,7 +714,7 @@ export class TempoDatasource extends DataSourceWithBackend { return { - data: formatTraceQLMetrics(response.data), + data: formatTraceQLMetrics(queryValue, response.data), }; }), catchError((err) => { diff --git a/public/app/plugins/datasource/tempo/resultTransformer.ts b/public/app/plugins/datasource/tempo/resultTransformer.ts index 187c20b711a..fd47cdd3b0f 100644 --- a/public/app/plugins/datasource/tempo/resultTransformer.ts +++ b/public/app/plugins/datasource/tempo/resultTransformer.ts @@ -633,21 +633,31 @@ function transformToTraceData(data: TraceSearchMetadata) { } const metricsValueToString = (value: ProtoValue): string => { - return '' + (value.stringValue || value.intValue || value.doubleValue || value.boolValue || ''); + if (value.stringValue) { + return `"${value.stringValue}"`; + } + return '' + (value.intValue || value.doubleValue || value.boolValue || '""'); }; -export function formatTraceQLMetrics(data: TraceqlMetricsResponse) { - const frames = data.series.map((series) => { +export function formatTraceQLMetrics(query: string, data: TraceqlMetricsResponse) { + const frames = data.series.map((series, index) => { const labels: Labels = {}; - series.labels.forEach((label) => { + series.labels?.forEach((label) => { labels[label.key] = metricsValueToString(label.value); }); - const displayName = - series.labels.length === 1 - ? metricsValueToString(series.labels[0].value) - : `{${series.labels.map((label) => `${label.key}=${metricsValueToString(label.value)}`).join(',')}}`; + // If it's a single series, use the query as the displayName fallback + let name = data.series.length === 1 ? query : ''; + if (series.labels) { + if (series.labels.length === 1) { + // For single label series, use the label value as the displayName to improve readability + name = metricsValueToString(series.labels[0].value); + } else { + // otherwise build a string using the label keys and values + name = `{${series.labels.map((label) => `${label.key}=${metricsValueToString(label.value)}`).join(', ')}}`; + } + } return createDataFrame({ - refId: series.promLabels, + refId: name || `A${index}`, fields: [ { name: 'time', @@ -655,12 +665,12 @@ export function formatTraceQLMetrics(data: TraceqlMetricsResponse) { values: series.samples.map((sample) => parseInt(sample.timestampMs, 10)), }, { - name: series.promLabels, + name: name, labels, type: FieldType.number, values: series.samples.map((sample) => sample.value), config: { - displayNameFromDS: displayName, + displayNameFromDS: name, }, }, ],