From 4afa74232f23afe1559d5df324e6c84ed37bbdf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Farkas?= Date: Wed, 11 Aug 2021 20:34:51 +0200 Subject: [PATCH] prometheus: alerting: respect datasource.scrapeInterval (#37799) --- pkg/tsdb/prometheus/prometheus.go | 15 +++++++++---- pkg/tsdb/prometheus/prometheus_test.go | 31 ++++++++++++++++++-------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/pkg/tsdb/prometheus/prometheus.go b/pkg/tsdb/prometheus/prometheus.go index 5ab3edf2185..14ede6f57d6 100644 --- a/pkg/tsdb/prometheus/prometheus.go +++ b/pkg/tsdb/prometheus/prometheus.go @@ -38,6 +38,7 @@ type DatasourceInfo struct { HTTPClientOpts sdkhttpclient.Options URL string HTTPMethod string + TimeInterval string } func init() { @@ -84,11 +85,17 @@ func newInstanceSettings() datasource.InstanceFactoryFunc { return nil, errors.New("no http method provided") } + timeInterval, ok := jsonData["timeInterval"].(string) + if !ok { + return nil, errors.New("invalid time-interval provided") + } + mdl := DatasourceInfo{ ID: settings.ID, URL: settings.URL, HTTPClientOpts: httpCliOpts, HTTPMethod: httpMethod, + TimeInterval: timeInterval, } return mdl, nil } @@ -123,7 +130,7 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) Responses: backend.Responses{}, } - queries, err := s.parseQuery(req.Queries) + queries, err := s.parseQuery(req.Queries, dsInfo) if err != nil { return &result, err } @@ -217,7 +224,7 @@ func formatLegend(metric model.Metric, query *PrometheusQuery) string { return string(result) } -func (s *Service) parseQuery(queries []backend.DataQuery) ( +func (s *Service) parseQuery(queries []backend.DataQuery, dsInfo *DatasourceInfo) ( []*PrometheusQuery, error) { var intervalMode string var adjustedInterval time.Duration @@ -239,7 +246,7 @@ func (s *Service) parseQuery(queries []backend.DataQuery) ( end := queryModel.TimeRange.To queryInterval := jsonModel.Get("interval").MustString("") - dsInterval, err := tsdb.GetIntervalFrom(queryInterval, "", 0, 15*time.Second) + foundInterval, err := tsdb.GetIntervalFrom(dsInfo.TimeInterval, queryInterval, 0, 15*time.Second) hasQueryInterval := queryInterval != "" // Only use stepMode if we have interval in query, otherwise use "min" if hasQueryInterval { @@ -253,7 +260,7 @@ func (s *Service) parseQuery(queries []backend.DataQuery) ( return nil, err } - calculatedInterval, err := s.intervalCalculator.Calculate(queries[0].TimeRange, dsInterval, tsdb.IntervalMode(intervalMode)) + calculatedInterval, err := s.intervalCalculator.Calculate(queries[0].TimeRange, foundInterval, tsdb.IntervalMode(intervalMode)) if err != nil { return nil, err } diff --git a/pkg/tsdb/prometheus/prometheus_test.go b/pkg/tsdb/prometheus/prometheus_test.go index e1fb259f0ed..2518e9c8c2c 100644 --- a/pkg/tsdb/prometheus/prometheus_test.go +++ b/pkg/tsdb/prometheus/prometheus_test.go @@ -56,7 +56,7 @@ func TestPrometheus(t *testing.T) { To: now.Add(12 * time.Hour), } query.TimeRange = timeRange - models, err := service.parseQuery([]backend.DataQuery{query}) + models, err := service.parseQuery([]backend.DataQuery{query}, &DatasourceInfo{}) require.NoError(t, err) require.Equal(t, time.Second*30, models[0].Step) }) @@ -74,7 +74,7 @@ func TestPrometheus(t *testing.T) { To: now.Add(12 * time.Hour), } query.TimeRange = timeRange - models, err := service.parseQuery([]backend.DataQuery{query}) + models, err := service.parseQuery([]backend.DataQuery{query}, &DatasourceInfo{}) require.NoError(t, err) require.Equal(t, time.Second*7, models[0].Step) }) @@ -92,7 +92,7 @@ func TestPrometheus(t *testing.T) { To: now.Add(12 * time.Hour), } query.TimeRange = timeRange - models, err := service.parseQuery([]backend.DataQuery{query}) + models, err := service.parseQuery([]backend.DataQuery{query}, &DatasourceInfo{}) require.NoError(t, err) require.Equal(t, time.Second*6, models[0].Step) }) @@ -110,7 +110,7 @@ func TestPrometheus(t *testing.T) { To: now.Add(12 * time.Hour), } query.TimeRange = timeRange - models, err := service.parseQuery([]backend.DataQuery{query}) + models, err := service.parseQuery([]backend.DataQuery{query}, &DatasourceInfo{}) require.NoError(t, err) require.Equal(t, time.Second*30, models[0].Step) }) @@ -128,7 +128,7 @@ func TestPrometheus(t *testing.T) { To: now.Add(12 * time.Hour), } query.TimeRange = timeRange - models, err := service.parseQuery([]backend.DataQuery{query}) + models, err := service.parseQuery([]backend.DataQuery{query}, &DatasourceInfo{}) require.NoError(t, err) require.Equal(t, time.Second*5, models[0].Step) }) @@ -140,7 +140,7 @@ func TestPrometheus(t *testing.T) { "intervalFactor": 1, "refId": "A" }`) - models, err := service.parseQuery([]backend.DataQuery{query}) + models, err := service.parseQuery([]backend.DataQuery{query}, &DatasourceInfo{}) require.NoError(t, err) require.Equal(t, time.Minute*2, models[0].Step) @@ -149,7 +149,7 @@ func TestPrometheus(t *testing.T) { To: now.Add(1 * time.Hour), } query.TimeRange = timeRange - models, err = service.parseQuery([]backend.DataQuery{query}) + models, err = service.parseQuery([]backend.DataQuery{query}, &DatasourceInfo{}) require.NoError(t, err) require.Equal(t, time.Second*15, models[0].Step) }) @@ -160,7 +160,7 @@ func TestPrometheus(t *testing.T) { "format": "time_series", "intervalFactor": 10, "refId": "A" - }`)}) + }`)}, &DatasourceInfo{}) require.NoError(t, err) require.Equal(t, time.Minute*20, models[0].Step) }) @@ -171,10 +171,23 @@ func TestPrometheus(t *testing.T) { "format": "time_series", "intervalFactor": 1, "refId": "A" - }`)}) + }`)}, &DatasourceInfo{}) require.NoError(t, err) require.Equal(t, time.Minute*2, models[0].Step) }) + + t.Run("parsing query model specified scrape-interval in the data source", func(t *testing.T) { + models, err := service.parseQuery([]backend.DataQuery{queryContext(`{ + "expr": "go_goroutines", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + }`)}, &DatasourceInfo{ + TimeInterval: "240s", + }) + require.NoError(t, err) + require.Equal(t, time.Minute*4, models[0].Step) + }) } func queryContext(json string) backend.DataQuery {