diff --git a/packages/grafana-prometheus/src/datasource.ts b/packages/grafana-prometheus/src/datasource.ts index e69327b718e..29b53f51902 100644 --- a/packages/grafana-prometheus/src/datasource.ts +++ b/packages/grafana-prometheus/src/datasource.ts @@ -449,8 +449,7 @@ export class PrometheusDatasource } const scopedVars = { - __interval: { text: this.interval, value: this.interval }, - __interval_ms: { text: rangeUtil.intervalToMs(this.interval), value: rangeUtil.intervalToMs(this.interval) }, + ...this.getIntervalVars(), ...this.getRangeScopedVars(options?.range ?? getDefaultTimeRange()), }; const interpolated = this.templateSrv.replace(query, scopedVars, this.interpolateQueryExpr); @@ -458,6 +457,13 @@ export class PrometheusDatasource return metricFindQuery.process(options?.range ?? getDefaultTimeRange()); } + getIntervalVars() { + return { + __interval: { text: this.interval, value: this.interval }, + __interval_ms: { text: rangeUtil.intervalToMs(this.interval), value: rangeUtil.intervalToMs(this.interval) }, + }; + } + getRangeScopedVars(range: TimeRange) { const msRange = range.to.diff(range.from); const sRange = Math.round(msRange / 1000); diff --git a/packages/grafana-prometheus/src/language_provider.ts b/packages/grafana-prometheus/src/language_provider.ts index d645c3ba74b..105c354dcae 100644 --- a/packages/grafana-prometheus/src/language_provider.ts +++ b/packages/grafana-prometheus/src/language_provider.ts @@ -442,7 +442,12 @@ export default class PromQlLanguageProvider extends LanguageProvider { [], { labelName, - queries: queries?.map((q) => q.expr), + queries: queries?.map((q) => + this.datasource.interpolateString(q.expr, { + ...this.datasource.getIntervalVars(), + ...this.datasource.getRangeScopedVars(this.timeRange), + }) + ), scopes: scopes?.reduce((acc, scope) => { acc.push(...scope.spec.filters); diff --git a/pkg/promlib/models/query.go b/pkg/promlib/models/query.go index 002102db219..c54e51fea41 100644 --- a/pkg/promlib/models/query.go +++ b/pkg/promlib/models/query.go @@ -207,7 +207,7 @@ func Parse(span trace.Span, query backend.DataQuery, dsScrapeInterval string, in // Interpolate variables in expr timeRange := query.TimeRange.To.Sub(query.TimeRange.From) - expr := interpolateVariables( + expr := InterpolateVariables( model.Expr, query.Interval, calculatedStep, @@ -365,14 +365,14 @@ func calculateRateInterval( return rateInterval } -// interpolateVariables interpolates built-in variables +// InterpolateVariables interpolates built-in variables // expr PromQL query // queryInterval Requested interval in milliseconds. This value may be overridden by MinStep in query options // calculatedStep Calculated final step value. It was calculated in calculatePrometheusInterval // requestedMinStep Requested minimum step value. QueryModel.interval // dsScrapeInterval Data source scrape interval in the config // timeRange Requested time range for query -func interpolateVariables( +func InterpolateVariables( expr string, queryInterval time.Duration, calculatedStep time.Duration, diff --git a/pkg/promlib/resource/resource.go b/pkg/promlib/resource/resource.go index bf880d5564a..66483872972 100644 --- a/pkg/promlib/resource/resource.go +++ b/pkg/promlib/resource/resource.go @@ -8,6 +8,7 @@ import ( "net/http" "net/url" "slices" + "time" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/log" @@ -148,7 +149,17 @@ func (r *Resource) GetSuggestions(ctx context.Context, req *backend.CallResource selectorList := []string{} for _, query := range sugReq.Queries { - s, err := getSelectors(query) + // Since we are only extracting selectors from the metric name, we can use dummy + // time durations. + interpolatedQuery := models.InterpolateVariables( + query, + time.Minute, + time.Minute, + "1m", + "15s", + time.Minute, + ) + s, err := getSelectors(interpolatedQuery) if err != nil { return nil, fmt.Errorf("error parsing selectors: %v", err) }