InfluxDB: InfluxQL: handle new-alerting better (#37588)

* influxdb: influxql: alert: use already-computed interval-value when available

* reverted by-mistake changed import

* simplify code

now we can rely on DataQuery.Interval always being good

* removed unnecessary test

* fix lint-error
This commit is contained in:
Gábor Farkas
2021-09-06 09:33:07 +02:00
committed by GitHub
parent 01f1c550bf
commit 6cab44d73a
4 changed files with 33 additions and 38 deletions

View File

@ -13,7 +13,6 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/datasource"
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/httpclient"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/plugins/backendplugin"
@ -150,17 +149,17 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest)
}
func (s *Service) getQuery(dsInfo *models.DatasourceInfo, query *backend.QueryDataRequest) (*Query, error) {
if len(query.Queries) == 0 {
return nil, fmt.Errorf("query request contains no queries")
}
queryCount := len(query.Queries)
// The model supports multiple queries, but right now this is only used from
// alerting so we only needed to support batch executing 1 query at a time.
model, err := simplejson.NewJson(query.Queries[0].JSON)
if err != nil {
return nil, fmt.Errorf("couldn't unmarshal query")
if queryCount != 1 {
return nil, fmt.Errorf("query request should contain exactly 1 query, it contains: %d", queryCount)
}
return s.QueryParser.Parse(model, dsInfo)
q := query.Queries[0]
return s.QueryParser.Parse(q)
}
func (s *Service) createRequest(ctx context.Context, dsInfo *models.DatasourceInfo, query string) (*http.Request, error) {

View File

@ -1,17 +1,21 @@
package influxdb
import (
"fmt"
"strconv"
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/tsdb"
"github.com/grafana/grafana/pkg/tsdb/influxdb/models"
)
type InfluxdbQueryParser struct{}
func (qp *InfluxdbQueryParser) Parse(model *simplejson.Json, dsInfo *models.DatasourceInfo) (*Query, error) {
func (qp *InfluxdbQueryParser) Parse(query backend.DataQuery) (*Query, error) {
model, err := simplejson.NewJson(query.JSON)
if err != nil {
return nil, fmt.Errorf("couldn't unmarshal query")
}
policy := model.Get("policy").MustString("default")
rawQuery := model.Get("query").MustString("")
useRawQuery := model.Get("rawQuery").MustBool(false)
@ -40,13 +44,6 @@ func (qp *InfluxdbQueryParser) Parse(model *simplejson.Json, dsInfo *models.Data
return nil, err
}
queryInterval := model.Get("interval").MustString("")
intervalMS := model.Get("intervalMs").MustInt(0)
parsedInterval, err := tsdb.GetIntervalFrom(dsInfo.TimeInterval, queryInterval, int64(intervalMS), time.Millisecond*1)
if err != nil {
return nil, err
}
return &Query{
Measurement: measurement,
Policy: policy,
@ -55,7 +52,7 @@ func (qp *InfluxdbQueryParser) Parse(model *simplejson.Json, dsInfo *models.Data
Tags: tags,
Selects: selects,
RawQuery: rawQuery,
Interval: parsedInterval,
Interval: query.Interval,
Alias: alias,
UseRawQuery: useRawQuery,
Tz: tz,

View File

@ -4,14 +4,12 @@ import (
"testing"
"time"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/tsdb/influxdb/models"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/stretchr/testify/require"
)
func TestInfluxdbQueryParser_Parse(t *testing.T) {
parser := &InfluxdbQueryParser{}
dsInfo := &models.DatasourceInfo{}
t.Run("can parse influxdb json model", func(t *testing.T) {
json := `
@ -103,11 +101,13 @@ func TestInfluxdbQueryParser_Parse(t *testing.T) {
]
}
`
dsInfo.TimeInterval = ">20s"
modelJSON, err := simplejson.NewJson([]byte(json))
require.NoError(t, err)
res, err := parser.Parse(modelJSON, dsInfo)
query := backend.DataQuery{
JSON: []byte(json),
Interval: time.Second * 20,
}
res, err := parser.Parse(query)
require.NoError(t, err)
require.Len(t, res.GroupBy, 3)
require.Len(t, res.Selects, 3)
@ -162,10 +162,12 @@ func TestInfluxdbQueryParser_Parse(t *testing.T) {
}
`
modelJSON, err := simplejson.NewJson([]byte(json))
require.NoError(t, err)
query := backend.DataQuery{
JSON: []byte(json),
Interval: time.Second * 10,
}
res, err := parser.Parse(modelJSON, dsInfo)
res, err := parser.Parse(query)
require.NoError(t, err)
require.Equal(t, "RawDummyQuery", res.RawQuery)
require.Len(t, res.GroupBy, 2)

View File

@ -29,16 +29,13 @@ func (query *Query) Build(queryContext *backend.QueryDataRequest) (string, error
res += query.renderTz()
}
calculator := tsdb.NewCalculator(tsdb.CalculatorOptions{})
i, err := calculator.Calculate(queryContext.Queries[0].TimeRange, query.Interval, tsdb.Min)
if err != nil {
return "", err
}
intervalText := tsdb.FormatDuration(query.Interval)
intervalMs := int64(query.Interval / time.Millisecond)
res = strings.ReplaceAll(res, "$timeFilter", query.renderTimeFilter(queryContext))
res = strings.ReplaceAll(res, "$interval", i.Text)
res = strings.ReplaceAll(res, "$__interval_ms", strconv.FormatInt(i.Milliseconds(), 10))
res = strings.ReplaceAll(res, "$__interval", i.Text)
res = strings.ReplaceAll(res, "$interval", intervalText)
res = strings.ReplaceAll(res, "$__interval_ms", strconv.FormatInt(intervalMs, 10))
res = strings.ReplaceAll(res, "$__interval", intervalText)
return res, nil
}