Loki: Introduce $__auto range variable for metric queries (#72690)
* Loki: Add interpolation to backend * Loki: Replace default variable with in frontend * Loki: Update docs in query builder fro __auto * Loki: Update test for change default __auto * Loki: Remove and from suggestions as should be used * Update docs * Update pkg/tsdb/loki/parse_query.go * Fix backend lint * Fix lint and test * Update * Update docs/sources/datasources/loki/template-variables/index.md Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com> * Update public/app/plugins/datasource/loki/querybuilder/operationUtils.ts Co-authored-by: Matias Chomicki <matyax@gmail.com> --------- Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com> Co-authored-by: Matias Chomicki <matyax@gmail.com>
This commit is contained in:
co-authored by
lwandz13
Matias Chomicki
parent
b1fd399c10
commit
7bb0ff7055
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
|
||||
"github.com/grafana/grafana/pkg/tsdb/intervalv2"
|
||||
"github.com/grafana/grafana/pkg/tsdb/loki/kinds/dataquery"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -18,6 +19,7 @@ const (
|
||||
varRange = "$__range"
|
||||
varRangeS = "$__range_s"
|
||||
varRangeMs = "$__range_ms"
|
||||
varAuto = "$__auto"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -26,10 +28,12 @@ const (
|
||||
varRangeAlt = "${__range}"
|
||||
varRangeSAlt = "${__range_s}"
|
||||
varRangeMsAlt = "${__range_ms}"
|
||||
// $__auto is a new variable and we don't want to support this templating format
|
||||
)
|
||||
|
||||
func interpolateVariables(expr string, interval time.Duration, timeRange time.Duration) string {
|
||||
func interpolateVariables(expr string, interval time.Duration, timeRange time.Duration, queryType dataquery.LokiQueryType, step time.Duration) string {
|
||||
intervalText := intervalv2.FormatDuration(interval)
|
||||
stepText := intervalv2.FormatDuration(step)
|
||||
intervalMsText := strconv.FormatInt(int64(interval/time.Millisecond), 10)
|
||||
|
||||
rangeMs := timeRange.Milliseconds()
|
||||
@@ -42,6 +46,13 @@ func interpolateVariables(expr string, interval time.Duration, timeRange time.Du
|
||||
expr = strings.ReplaceAll(expr, varRangeMs, rangeMsText)
|
||||
expr = strings.ReplaceAll(expr, varRangeS, rangeSText)
|
||||
expr = strings.ReplaceAll(expr, varRange, rangeSText+"s")
|
||||
if queryType == dataquery.LokiQueryTypeInstant {
|
||||
expr = strings.ReplaceAll(expr, varAuto, rangeSText+"s")
|
||||
}
|
||||
|
||||
if queryType == dataquery.LokiQueryTypeRange {
|
||||
expr = strings.ReplaceAll(expr, varAuto, stepText)
|
||||
}
|
||||
|
||||
// this is duplicated code, hopefully this can be handled in a nicer way when
|
||||
// https://github.com/grafana/grafana/issues/42928 is done.
|
||||
@@ -131,13 +142,13 @@ func parseQuery(queryContext *backend.QueryDataRequest) ([]*lokiQuery, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
expr := interpolateVariables(model.Expr, interval, timeRange)
|
||||
|
||||
queryType, err := parseQueryType(model.QueryType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
expr := interpolateVariables(model.Expr, interval, timeRange, queryType, step)
|
||||
|
||||
direction, err := parseDirection(model.Direction)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana/pkg/tsdb/loki/kinds/dataquery"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@@ -36,26 +37,59 @@ func TestParseQuery(t *testing.T) {
|
||||
})
|
||||
t.Run("interpolate variables, range between 1s and 0.5s", func(t *testing.T) {
|
||||
expr := "go_goroutines $__interval $__interval_ms $__range $__range_s $__range_ms"
|
||||
|
||||
queryType := dataquery.LokiQueryTypeRange
|
||||
interval := time.Millisecond * 50
|
||||
step := time.Millisecond * 100
|
||||
timeRange := time.Millisecond * 750
|
||||
|
||||
require.Equal(t, "go_goroutines 50ms 50 1s 1 750", interpolateVariables(expr, interval, timeRange))
|
||||
require.Equal(t, "go_goroutines 50ms 50 1s 1 750", interpolateVariables(expr, interval, timeRange, queryType, step))
|
||||
})
|
||||
t.Run("parsing query model, range below 0.5s", func(t *testing.T) {
|
||||
expr := "go_goroutines $__interval $__interval_ms $__range $__range_s $__range_ms"
|
||||
|
||||
queryType := dataquery.LokiQueryTypeRange
|
||||
interval := time.Millisecond * 50
|
||||
step := time.Millisecond * 100
|
||||
timeRange := time.Millisecond * 250
|
||||
|
||||
require.Equal(t, "go_goroutines 50ms 50 0s 0 250", interpolateVariables(expr, interval, timeRange))
|
||||
require.Equal(t, "go_goroutines 50ms 50 0s 0 250", interpolateVariables(expr, interval, timeRange, queryType, step))
|
||||
})
|
||||
t.Run("interpolate variables, curly-braces syntax", func(t *testing.T) {
|
||||
expr := "go_goroutines ${__interval} ${__interval_ms} ${__range} ${__range_s} ${__range_ms}"
|
||||
|
||||
queryType := dataquery.LokiQueryTypeRange
|
||||
interval := time.Second * 2
|
||||
step := time.Millisecond * 100
|
||||
timeRange := time.Second * 50
|
||||
|
||||
require.Equal(t, "go_goroutines 2s 2000 50s 50 50000", interpolateVariables(expr, interval, timeRange))
|
||||
require.Equal(t, "go_goroutines 2s 2000 50s 50 50000", interpolateVariables(expr, interval, timeRange, queryType, step))
|
||||
})
|
||||
|
||||
t.Run("interpolate variables should work with $__auto and instant query type", func(t *testing.T) {
|
||||
expr := "rate({compose_project=\"docker-compose\"}[$__auto])"
|
||||
queryType := dataquery.LokiQueryTypeInstant
|
||||
interval := time.Second * 2
|
||||
step := time.Millisecond * 100
|
||||
timeRange := time.Second * 50
|
||||
|
||||
require.Equal(t, "rate({compose_project=\"docker-compose\"}[50s])", interpolateVariables(expr, interval, timeRange, queryType, step))
|
||||
})
|
||||
|
||||
t.Run("interpolate variables should work with $__auto and range query type", func(t *testing.T) {
|
||||
expr := "rate({compose_project=\"docker-compose\"}[$__auto])"
|
||||
queryType := dataquery.LokiQueryTypeRange
|
||||
interval := time.Second * 2
|
||||
step := time.Millisecond * 100
|
||||
timeRange := time.Second * 50
|
||||
|
||||
require.Equal(t, "rate({compose_project=\"docker-compose\"}[100ms])", interpolateVariables(expr, interval, timeRange, queryType, step))
|
||||
})
|
||||
|
||||
t.Run("interpolate variables should return original query if no variables", func(t *testing.T) {
|
||||
expr := "rate({compose_project=\"docker-compose\"}[10s])"
|
||||
queryType := dataquery.LokiQueryTypeRange
|
||||
interval := time.Second * 2
|
||||
step := time.Millisecond * 100
|
||||
timeRange := time.Second * 50
|
||||
|
||||
require.Equal(t, "rate({compose_project=\"docker-compose\"}[10s])", interpolateVariables(expr, interval, timeRange, queryType, step))
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user