datasources: querier: better handling of timestamps (#108973)
* query: support query-local timestamps * make it configurable * lint fix * corrected unit test * fixed unit test
This commit is contained in:
+26
-19
@@ -2,7 +2,6 @@ package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@@ -14,7 +13,6 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/gtime"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
data "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
@@ -88,6 +86,7 @@ type ServiceImpl struct {
|
||||
concurrentQueryLimit int
|
||||
mtDatasourceClientBuilder mtdsclient.MTDatasourceClientBuilder
|
||||
headers map[string]string
|
||||
supportLocalTimeRange bool
|
||||
}
|
||||
|
||||
// Run ServiceImpl.
|
||||
@@ -105,7 +104,7 @@ func (s *ServiceImpl) QueryData(ctx context.Context, user identity.Requester, sk
|
||||
}
|
||||
}
|
||||
// Parse the request into parsed queries grouped by datasource uid
|
||||
parsedReq, err := s.parseMetricRequest(ctx, user, skipDSCache, reqDTO)
|
||||
parsedReq, err := s.parseMetricRequest(ctx, user, skipDSCache, reqDTO, s.supportLocalTimeRange)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -224,6 +223,7 @@ func QueryData(ctx context.Context, log log.Logger, dscache datasources.CacheSer
|
||||
mtDatasourceClientBuilder: mtDatasourceClientBuilder,
|
||||
headers: headers,
|
||||
concurrentQueryLimit: 16, // TODO: make it configurable
|
||||
supportLocalTimeRange: true,
|
||||
}
|
||||
return s.QueryData(ctx, nil, false, reqDTO)
|
||||
}
|
||||
@@ -303,32 +303,32 @@ func (s *ServiceImpl) handleQuerySingleDatasource(ctx context.Context, user iden
|
||||
return s.pluginClient.QueryData(ctx, req)
|
||||
} else { // multi tenant flow
|
||||
// transform request from backend.QueryDataRequest to k8s request
|
||||
k8sReq := &data.QueryDataRequest{
|
||||
TimeRange: data.TimeRange{
|
||||
From: req.Queries[0].TimeRange.From.Format(time.RFC3339),
|
||||
To: req.Queries[0].TimeRange.To.Format(time.RFC3339),
|
||||
},
|
||||
}
|
||||
for _, q := range req.Queries {
|
||||
var dataQuery data.DataQuery
|
||||
err := json.Unmarshal(q.JSON, &dataQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k8sReq.Queries = append(k8sReq.Queries, dataQuery)
|
||||
k8sReq, err := expr.ConvertBackendRequestToDataRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mtDsClient.QueryData(ctx, *k8sReq)
|
||||
}
|
||||
}
|
||||
|
||||
func getTimeRange(query *simplejson.Json, globalFrom string, globalTo string) gtime.TimeRange {
|
||||
from := query.Get("timeRange").Get("from").MustString("")
|
||||
to := query.Get("timeRange").Get("to").MustString("")
|
||||
|
||||
if (from == "") && (to == "") {
|
||||
from = globalFrom
|
||||
to = globalTo
|
||||
}
|
||||
|
||||
return gtime.NewTimeRange(from, to)
|
||||
}
|
||||
|
||||
// parseRequest parses a request into parsed queries grouped by datasource uid
|
||||
func (s *ServiceImpl) parseMetricRequest(ctx context.Context, user identity.Requester, skipDSCache bool, reqDTO dtos.MetricRequest) (*parsedRequest, error) {
|
||||
func (s *ServiceImpl) parseMetricRequest(ctx context.Context, user identity.Requester, skipDSCache bool, reqDTO dtos.MetricRequest, supportLocalTimeRange bool) (*parsedRequest, error) {
|
||||
if len(reqDTO.Queries) == 0 {
|
||||
return nil, ErrNoQueriesFound
|
||||
}
|
||||
|
||||
timeRange := gtime.NewTimeRange(reqDTO.From, reqDTO.To)
|
||||
req := &parsedRequest{
|
||||
hasExpression: false,
|
||||
parsedQueries: make(map[string][]parsedQuery),
|
||||
@@ -357,6 +357,13 @@ func (s *ServiceImpl) parseMetricRequest(ctx context.Context, user identity.Requ
|
||||
req.parsedQueries[ds.UID] = []parsedQuery{}
|
||||
}
|
||||
|
||||
var timeRange gtime.TimeRange
|
||||
if supportLocalTimeRange {
|
||||
timeRange = getTimeRange(query, reqDTO.From, reqDTO.To)
|
||||
} else {
|
||||
timeRange = gtime.NewTimeRange(reqDTO.From, reqDTO.To)
|
||||
}
|
||||
|
||||
modelJSON, err := query.MarshalJSON()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user