Tempo: Add template variable interpolation for filters (#83213)

* Interpolate template variables in filters

* Add tests
pull/83220/head
Joey 1 year ago committed by GitHub
parent 49d3cb29eb
commit 1631e41303
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 29
      public/app/plugins/datasource/tempo/datasource.test.ts
  2. 39
      public/app/plugins/datasource/tempo/datasource.ts

@ -93,7 +93,24 @@ describe('Tempo data source', () => {
minDuration: '$interpolationVar',
maxDuration: '$interpolationVar',
serviceMapQuery,
filters: [],
filters: [
{
id: 'service-name',
operator: '=',
scope: TraceqlSearchScope.Resource,
tag: 'service.name',
value: '$interpolationVarWithPipe',
valueType: 'string',
},
{
id: 'tagId',
operator: '=',
scope: TraceqlSearchScope.Span,
tag: '$interpolationVar',
value: '$interpolationVar',
valueType: 'string',
},
],
};
}
let templateSrv: TemplateSrv;
@ -110,7 +127,7 @@ describe('Tempo data source', () => {
templateSrv = initTemplateSrv([{ name: 'templateVariable1' }, { name: 'templateVariable2' }], expectedValues);
});
it('when traceId query for dashboard->explore', async () => {
it('when moving from dashboard to explore', async () => {
const expectedValues = {
interpolationVar: 'interpolationText',
interpolationText: 'interpolationText',
@ -129,9 +146,12 @@ describe('Tempo data source', () => {
expect(queries[0].minDuration).toBe(text);
expect(queries[0].maxDuration).toBe(text);
expect(queries[0].serviceMapQuery).toBe(text);
expect(queries[0].filters[0].value).toBe(textWithPipe);
expect(queries[0].filters[1].value).toBe(text);
expect(queries[0].filters[1].tag).toBe(text);
});
it('when traceId query for template variable', async () => {
it('when applying template variables', async () => {
const scopedText = 'scopedInterpolationText';
const ds = new TempoDatasource(defaultSettings, templateSrv);
const resp = ds.applyTemplateVariables(getQuery(), {
@ -144,6 +164,9 @@ describe('Tempo data source', () => {
expect(resp.search).toBe(scopedText);
expect(resp.minDuration).toBe(scopedText);
expect(resp.maxDuration).toBe(scopedText);
expect(resp.filters[0].value).toBe(textWithPipe);
expect(resp.filters[1].value).toBe(scopedText);
expect(resp.filters[1].tag).toBe(scopedText);
});
it('when serviceMapQuery is an array', async () => {

@ -377,9 +377,12 @@ export class TempoDatasource extends DataSourceWithBackend<TempoQuery, TempoJson
if (targets.traceqlSearch?.length) {
try {
if (config.featureToggles.metricsSummary) {
const groupBy = targets.traceqlSearch.find((t) => this.hasGroupBy(t));
if (groupBy) {
subQueries.push(this.handleMetricsSummary(groupBy, generateQueryFromFilters(groupBy.filters), options));
const target = targets.traceqlSearch.find((t) => this.hasGroupBy(t));
if (target) {
const appliedQuery = this.applyVariables(target, options.scopedVars);
subQueries.push(
this.handleMetricsSummary(appliedQuery, generateQueryFromFilters(appliedQuery.filters), options)
);
}
}
@ -387,25 +390,23 @@ export class TempoDatasource extends DataSourceWithBackend<TempoQuery, TempoJson
? targets.traceqlSearch.filter((t) => !this.hasGroupBy(t))
: targets.traceqlSearch;
if (traceqlSearchTargets.length > 0) {
const queryValueFromFilters = generateQueryFromFilters(traceqlSearchTargets[0].filters);
// We want to support template variables also in Search for consistency with other data sources
const queryValue = this.templateSrv.replace(queryValueFromFilters, options.scopedVars);
const appliedQuery = this.applyVariables(traceqlSearchTargets[0], options.scopedVars);
const queryValueFromFilters = generateQueryFromFilters(appliedQuery.filters);
reportInteraction('grafana_traces_traceql_search_queried', {
datasourceType: 'tempo',
app: options.app ?? '',
grafana_version: config.buildInfo.version,
query: queryValue ?? '',
query: queryValueFromFilters ?? '',
streaming: config.featureToggles.traceQLStreaming,
});
if (config.featureToggles.traceQLStreaming && this.isFeatureAvailable(FeatureName.streaming)) {
subQueries.push(this.handleStreamingSearch(options, traceqlSearchTargets, queryValue));
subQueries.push(this.handleStreamingSearch(options, traceqlSearchTargets, queryValueFromFilters));
} else {
subQueries.push(
this._request('/api/search', {
q: queryValue,
q: queryValueFromFilters,
limit: options.targets[0].limit ?? DEFAULT_LIMIT,
spss: options.targets[0].spss ?? DEFAULT_SPSS,
start: options.range.from.unix(),
@ -522,6 +523,24 @@ export class TempoDatasource extends DataSourceWithBackend<TempoQuery, TempoJson
};
}
if (query.filters) {
expandedQuery.filters = query.filters.map((filter) => {
const updatedFilter = {
...filter,
tag: this.templateSrv.replace(filter.tag ?? '', scopedVars),
};
if (filter.value) {
updatedFilter.value =
typeof filter.value === 'string'
? this.templateSrv.replace(filter.value ?? '', scopedVars, VariableFormatID.Pipe)
: filter.value.map((v) => this.templateSrv.replace(v ?? '', scopedVars, VariableFormatID.Pipe));
}
return updatedFilter;
});
}
return {
...expandedQuery,
query: this.templateSrv.replace(query.query ?? '', scopedVars, VariableFormatID.Pipe),

Loading…
Cancel
Save