From 062a0e7212f495330408359fee7c42e2c6839abc Mon Sep 17 00:00:00 2001 From: Joey <90795735+joey-grafana@users.noreply.github.com> Date: Tue, 11 Mar 2025 12:43:02 +0000 Subject: [PATCH] Tempo: fallback for intrinsic tags (#101677) * Add intrinsics fallback * Add test * Update tests * Prettier * Remove extra uniq --- .../tempo/SearchTraceQLEditor/utils.test.ts | 11 +++++++++-- .../tempo/SearchTraceQLEditor/utils.ts | 18 +++++++++++------- .../datasource/tempo/language_provider.test.ts | 9 +++++++-- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.test.ts b/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.test.ts index e76cdf168e6..57c2dadc2b1 100644 --- a/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.test.ts +++ b/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.test.ts @@ -3,12 +3,14 @@ import { uniq } from 'lodash'; import { TraceqlFilter, TraceqlSearchScope } from '../dataquery.gen'; import { TempoDatasource } from '../datasource'; import TempoLanguageProvider from '../language_provider'; +import { intrinsics } from '../traceql/traceql'; import { filterToQuerySection, generateQueryFromAdHocFilters, getAllTags, getFilteredTags, + getIntrinsicTags, getTagsByScope, getUnscopedTags, } from './utils'; @@ -94,7 +96,7 @@ describe('gets correct tags', () => { it('for all tags', () => { const tags = getAllTags(v2Tags); - expect(tags).toEqual(['cluster', 'container', 'db', 'duration', 'kind', 'name', 'status']); + expect(tags).toEqual(uniq(['cluster', 'container', 'db', 'duration', 'kind', 'name', 'status'].concat(intrinsics))); }); it('for tags by resource scope', () => { @@ -106,6 +108,11 @@ describe('gets correct tags', () => { const tags = getTagsByScope(v2Tags, TraceqlSearchScope.Span); expect(tags).toEqual(['db']); }); + + it('for intrinsic tags', () => { + const tags = getIntrinsicTags(v2Tags); + expect(tags).toEqual(testIntrinsics); + }); }); describe('filterToQuerySection returns the correct query section for a filter', () => { @@ -179,7 +186,7 @@ describe('filterToQuerySection returns the correct query section for a filter', }); export const emptyTags = []; -export const testIntrinsics = ['duration', 'kind', 'name', 'status']; +export const testIntrinsics = uniq(['duration', 'kind', 'name', 'status'].concat(intrinsics)); export const v1Tags = ['bar', 'foo']; export const v2Tags = [ { diff --git a/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.ts b/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.ts index e1a599e99b3..5b4313ce6f2 100644 --- a/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.ts +++ b/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.ts @@ -7,6 +7,7 @@ import { VariableFormatID } from '@grafana/schema'; import { TraceqlFilter, TraceqlSearchScope } from '../dataquery.gen'; import { getEscapedSpanNames } from '../datasource'; import TempoLanguageProvider from '../language_provider'; +import { intrinsics } from '../traceql/traceql'; import { Scope } from '../types'; export const interpolateFilters = (filters: TraceqlFilter[], scopedVars?: ScopedVars) => { @@ -132,13 +133,16 @@ export const getUnscopedTags = (scopes: Scope[]) => { }; export const getIntrinsicTags = (scopes: Scope[]) => { - return uniq( - scopes - .map((scope: Scope) => - scope.name && scope.name === TraceqlSearchScope.Intrinsic && scope.tags ? scope.tags : [] - ) - .flat() - ); + let tags = scopes + .map((scope: Scope) => (scope.name && scope.name === TraceqlSearchScope.Intrinsic && scope.tags ? scope.tags : [])) + .flat(); + + // Add the default intrinsic tags to the list of tags. + // This is needed because the /api/v2/search/tags API + // may not always return all the default intrinsic tags + // but generally has the most up to date list. + tags = uniq(tags.concat(intrinsics)); + return tags; }; export const getAllTags = (scopes: Scope[]) => { diff --git a/public/app/plugins/datasource/tempo/language_provider.test.ts b/public/app/plugins/datasource/tempo/language_provider.test.ts index 9bd44f33bed..7aff5eb7b18 100644 --- a/public/app/plugins/datasource/tempo/language_provider.test.ts +++ b/public/app/plugins/datasource/tempo/language_provider.test.ts @@ -1,7 +1,10 @@ +import { uniq } from 'lodash'; + import { v1Tags, v2Tags } from './SearchTraceQLEditor/utils.test'; import { TraceqlSearchScope } from './dataquery.gen'; import { TempoDatasource } from './datasource'; import TempoLanguageProvider from './language_provider'; +import { intrinsics } from './traceql/traceql'; import { Scope } from './types'; describe('Language_provider', () => { @@ -15,7 +18,7 @@ describe('Language_provider', () => { it('for API v2 intrinsic tags', async () => { const lp = setup(undefined, v2Tags); const tags = lp.getMetricsSummaryTags(TraceqlSearchScope.Intrinsic); - expect(tags).toEqual(['duration', 'kind', 'name', 'status']); + expect(tags).toEqual(uniq(['duration', 'kind', 'name', 'status'].concat(intrinsics))); }); it('for API v2 resource tags', async () => { @@ -105,7 +108,9 @@ describe('Language_provider', () => { it('for API v2 tags', async () => { const lp = setup(undefined, v2Tags); const tags = lp.getAutocompleteTags(); - expect(tags).toEqual(['cluster', 'container', 'db', 'duration', 'kind', 'name', 'status']); + expect(tags).toEqual( + uniq(['cluster', 'container', 'db', 'duration', 'kind', 'name', 'status'].concat(intrinsics)) + ); }); });