InfluxDB: Flux: make $__interval and $__interval_ms work in alerting (#38889)

* influxdb: flux: handle $__interval and $__interval_ms in alert-queries

* influxdb: flux: do not handle interval-variable in the frontend

* $__interval should be rounded

* added comment
This commit is contained in:
Gábor Farkas
2021-09-27 12:03:04 +02:00
committed by GitHub
parent 24475cfdda
commit 9f027e32b7
4 changed files with 35 additions and 18 deletions

View File

@@ -18,11 +18,7 @@ const maxPointsEnforceFactor float64 = 10
func executeQuery(ctx context.Context, query queryModel, runner queryRunner, maxSeries int) (dr backend.DataResponse) {
dr = backend.DataResponse{}
flux, err := interpolate(query)
if err != nil {
dr.Error = err
return
}
flux := interpolate(query)
glog.Debug("Executing Flux query", "flux", flux)

View File

@@ -2,18 +2,32 @@ package flux
import (
"regexp"
"strconv"
"strings"
"time"
"github.com/grafana/grafana/pkg/tsdb/intervalv2"
)
const variableFilter = `(?m)([a-zA-Z]+)\.([a-zA-Z]+)`
// $__interval_ms is the exact value in milliseconds
// $__interval is rounded to nice whole values
// v.windowPeriod is the exact value string-formatted
// interpolate processes macros
func interpolate(query queryModel) (string, error) {
func interpolateInterval(flux string, interval time.Duration) string {
intervalMs := int64(interval / time.Millisecond)
intervalText := intervalv2.FormatDuration(interval)
flux = strings.ReplaceAll(flux, "$__interval_ms", strconv.FormatInt(intervalMs, 10))
flux = strings.ReplaceAll(flux, "$__interval", intervalText)
return flux
}
var fluxVariableFilterExp = regexp.MustCompile(`(?m)([a-zA-Z]+)\.([a-zA-Z]+)`)
func interpolateFluxSpecificVariables(query queryModel) string {
flux := query.RawQuery
variableFilterExp, err := regexp.Compile(variableFilter)
matches := variableFilterExp.FindAllStringSubmatch(flux, -1)
matches := fluxVariableFilterExp.FindAllStringSubmatch(flux, -1)
if matches != nil {
timeRange := query.TimeRange
from := timeRange.From.UTC().Format(time.RFC3339Nano)
@@ -35,5 +49,11 @@ func interpolate(query queryModel) (string, error) {
}
}
}
return flux, err
return flux
}
func interpolate(query queryModel) string {
flux := interpolateFluxSpecificVariables(query)
flux = interpolateInterval(flux, query.Interval)
return flux
}

View File

@@ -7,7 +7,6 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestInterpolate(t *testing.T) {
@@ -29,8 +28,8 @@ func TestInterpolate(t *testing.T) {
}{
{
name: "interpolate flux variables",
before: `v.timeRangeStart, something.timeRangeStop, XYZ.bucket, uuUUu.defaultBucket, aBcDefG.organization, window.windowPeriod, a91{}.bucket`,
after: `2021-09-22T10:12:51.310985041Z, 2021-09-22T11:12:51.310985042Z, "grafana2", "grafana3", "grafana1", 1s, a91{}.bucket`,
before: `v.timeRangeStart, something.timeRangeStop, XYZ.bucket, uuUUu.defaultBucket, aBcDefG.organization, window.windowPeriod, a91{}.bucket, $__interval, $__interval_ms`,
after: `2021-09-22T10:12:51.310985041Z, 2021-09-22T11:12:51.310985042Z, "grafana2", "grafana3", "grafana1", 1m1.258s, a91{}.bucket, 1m, 61258`,
},
}
for _, tt := range tests {
@@ -40,10 +39,9 @@ func TestInterpolate(t *testing.T) {
Options: options,
TimeRange: timeRange,
MaxDataPoints: 1,
Interval: 1000 * 1000 * 1000,
Interval: 61258 * 1000 * 1000,
}
interpolatedQuery, err := interpolate(query)
require.NoError(t, err)
interpolatedQuery := interpolate(query)
diff := cmp.Diff(tt.after, interpolatedQuery)
assert.Equal(t, "", diff)
})

View File

@@ -188,9 +188,12 @@ export default class InfluxDatasource extends DataSourceWithBackend<InfluxQuery,
throw new Error('applyTemplateVariables called in influxql-mode. this should never happen');
}
// We want to interpolate these variables on backend
const { __interval, __interval_ms, ...rest } = scopedVars;
return {
...query,
query: this.templateSrv.replace(query.query ?? '', scopedVars), // The raw query text
query: this.templateSrv.replace(query.query ?? '', rest), // The raw query text
};
}