loki: simplify interval calculation (#41857)

This commit is contained in:
Gábor Farkas
2021-11-19 17:20:32 +01:00
committed by GitHub
parent ce4490cbba
commit 2fbc6b1d2f
2 changed files with 29 additions and 52 deletions
+7 -17
View File
@@ -18,7 +18,6 @@ import (
"github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
"github.com/grafana/grafana/pkg/tsdb/intervalv2"
"github.com/grafana/loki/pkg/logcli/client" "github.com/grafana/loki/pkg/logcli/client"
"github.com/grafana/loki/pkg/loghttp" "github.com/grafana/loki/pkg/loghttp"
"github.com/grafana/loki/pkg/logproto" "github.com/grafana/loki/pkg/logproto"
@@ -29,17 +28,15 @@ import (
) )
type Service struct { type Service struct {
intervalCalculator intervalv2.Calculator im instancemgmt.InstanceManager
im instancemgmt.InstanceManager plog log.Logger
plog log.Logger
} }
func ProvideService(httpClientProvider httpclient.Provider, registrar plugins.CoreBackendRegistrar) (*Service, error) { func ProvideService(httpClientProvider httpclient.Provider, registrar plugins.CoreBackendRegistrar) (*Service, error) {
im := datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)) im := datasource.NewInstanceManager(newInstanceSettings(httpClientProvider))
s := &Service{ s := &Service{
im: im, im: im,
intervalCalculator: intervalv2.NewCalculator(), plog: log.New("tsdb.loki"),
plog: log.New("tsdb.loki"),
} }
factory := coreplugin.New(backend.ServeOpts{ factory := coreplugin.New(backend.ServeOpts{
@@ -131,7 +128,7 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest)
}, },
} }
queries, err := s.parseQuery(dsInfo, req) queries, err := parseQuery(dsInfo, req)
if err != nil { if err != nil {
return result, err return result, err
} }
@@ -183,7 +180,7 @@ func formatLegend(metric model.Metric, query *lokiQuery) string {
return string(result) return string(result)
} }
func (s *Service) parseQuery(dsInfo *datasourceInfo, queryContext *backend.QueryDataRequest) ([]*lokiQuery, error) { func parseQuery(dsInfo *datasourceInfo, queryContext *backend.QueryDataRequest) ([]*lokiQuery, error) {
qs := []*lokiQuery{} qs := []*lokiQuery{}
for _, query := range queryContext.Queries { for _, query := range queryContext.Queries {
model := &ResponseModel{} model := &ResponseModel{}
@@ -195,19 +192,12 @@ func (s *Service) parseQuery(dsInfo *datasourceInfo, queryContext *backend.Query
start := query.TimeRange.From start := query.TimeRange.From
end := query.TimeRange.To end := query.TimeRange.To
dsInterval, err := intervalv2.GetIntervalFrom(dsInfo.TimeInterval, model.Interval, int64(model.IntervalMS), time.Second)
if err != nil {
return nil, fmt.Errorf("failed to parse Interval: %v", err)
}
interval := s.intervalCalculator.Calculate(query.TimeRange, dsInterval, query.MaxDataPoints)
var resolution int64 = 1 var resolution int64 = 1
if model.Resolution >= 1 && model.Resolution <= 5 || model.Resolution == 10 { if model.Resolution >= 1 && model.Resolution <= 5 || model.Resolution == 10 {
resolution = model.Resolution resolution = model.Resolution
} }
step := time.Duration(int64(interval.Value) * resolution) step := time.Duration(int64(query.Interval) * resolution)
qs = append(qs, &lokiQuery{ qs = append(qs, &lokiQuery{
Expr: model.Expr, Expr: model.Expr,
+22 -35
View File
@@ -8,7 +8,6 @@ import (
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/tsdb/intervalv2"
"github.com/grafana/loki/pkg/loghttp" "github.com/grafana/loki/pkg/loghttp"
p "github.com/prometheus/common/model" p "github.com/prometheus/common/model"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@@ -57,24 +56,18 @@ func TestLoki(t *testing.T) {
From: time.Now().Add(-30 * time.Second), From: time.Now().Add(-30 * time.Second),
To: time.Now(), To: time.Now(),
}, },
}, Interval: time.Second * 30,
},
}
service := &Service{
intervalCalculator: mockCalculator{
interval: intervalv2.Interval{
Value: time.Second * 30,
}, },
}, },
} }
dsInfo := &datasourceInfo{} dsInfo := &datasourceInfo{}
models, err := service.parseQuery(dsInfo, queryContext) models, err := parseQuery(dsInfo, queryContext)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, time.Second*30, models[0].Step) require.Equal(t, time.Second*30, models[0].Step)
}) })
t.Run("parsing query model without step parameter", func(t *testing.T) { t.Run("parsing query model without step parameter", func(t *testing.T) {
queryContext := &backend.QueryDataRequest{ queryContext1 := &backend.QueryDataRequest{
Queries: []backend.DataQuery{ Queries: []backend.DataQuery{
{ {
JSON: []byte(` JSON: []byte(`
@@ -88,29 +81,35 @@ func TestLoki(t *testing.T) {
From: time.Now().Add(-48 * time.Hour), From: time.Now().Add(-48 * time.Hour),
To: time.Now(), To: time.Now(),
}, },
}, Interval: time.Minute * 2,
},
}
service := &Service{
intervalCalculator: mockCalculator{
interval: intervalv2.Interval{
Value: time.Minute * 2,
}, },
}, },
} }
dsInfo := &datasourceInfo{} dsInfo := &datasourceInfo{}
models, err := service.parseQuery(dsInfo, queryContext) models, err := parseQuery(dsInfo, queryContext1)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, time.Minute*2, models[0].Step) require.Equal(t, time.Minute*2, models[0].Step)
service = &Service{ queryContext2 := &backend.QueryDataRequest{
intervalCalculator: mockCalculator{ Queries: []backend.DataQuery{
interval: intervalv2.Interval{ {
Value: time.Second * 2, JSON: []byte(`
{
"expr": "go_goroutines",
"format": "time_series",
"refId": "A"
}`,
),
TimeRange: backend.TimeRange{
From: time.Now().Add(-48 * time.Hour),
To: time.Now(),
},
Interval: time.Second * 2,
}, },
}, },
} }
models, err = service.parseQuery(dsInfo, queryContext)
models, err = parseQuery(dsInfo, queryContext2)
require.NoError(t, err) require.NoError(t, err)
fmt.Println(models) fmt.Println(models)
require.Equal(t, time.Second*2, models[0].Step) require.Equal(t, time.Second*2, models[0].Step)
@@ -173,15 +172,3 @@ func TestParseResponse(t *testing.T) {
} }
}) })
} }
type mockCalculator struct {
interval intervalv2.Interval
}
func (m mockCalculator) Calculate(timerange backend.TimeRange, minInterval time.Duration, maxDataPoints int64) intervalv2.Interval {
return m.interval
}
func (m mockCalculator) CalculateSafeInterval(timerange backend.TimeRange, resolution int64) intervalv2.Interval {
return m.interval
}