Prometheus: Interpolate vars in adhoc filters request (#94087)

* Interpolate vars in adhoc filters request

* interpolate variables on BE

---------

Co-authored-by: Kyle Brandt <kyle@grafana.com>
This commit is contained in:
Bogdan Matei 2024-10-01 18:33:06 +03:00 committed by GitHub
parent cbf8e7e679
commit a87df0528b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 29 additions and 7 deletions

View File

@ -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);

View File

@ -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<ScopeSpecFilter[]>((acc, scope) => {
acc.push(...scope.spec.filters);

View File

@ -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,

View File

@ -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)
}