mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
prom: removes limitation of one query per tsdb call
This commit is contained in:
parent
cd92d219cd
commit
e234cf5b18
@ -83,41 +83,48 @@ func (e *PrometheusExecutor) getClient(dsInfo *models.DataSource) (apiv1.API, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *PrometheusExecutor) Query(ctx context.Context, dsInfo *models.DataSource, tsdbQuery *tsdb.TsdbQuery) (*tsdb.Response, error) {
|
func (e *PrometheusExecutor) Query(ctx context.Context, dsInfo *models.DataSource, tsdbQuery *tsdb.TsdbQuery) (*tsdb.Response, error) {
|
||||||
result := &tsdb.Response{}
|
result := &tsdb.Response{
|
||||||
|
Results: map[string]*tsdb.QueryResult{},
|
||||||
|
}
|
||||||
|
|
||||||
client, err := e.getClient(dsInfo)
|
client, err := e.getClient(dsInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
query, err := parseQuery(dsInfo, tsdbQuery.Queries, tsdbQuery)
|
querys, err := parseQuery(dsInfo, tsdbQuery.Queries, tsdbQuery)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
timeRange := apiv1.Range{
|
for _, query := range querys {
|
||||||
Start: query.Start,
|
timeRange := apiv1.Range{
|
||||||
End: query.End,
|
Start: query.Start,
|
||||||
Step: query.Step,
|
End: query.End,
|
||||||
|
Step: query.Step,
|
||||||
|
}
|
||||||
|
|
||||||
|
plog.Debug("Sending query", "start", timeRange.Start, "end", timeRange.End, "step", timeRange.Step, "query", query.Expr)
|
||||||
|
|
||||||
|
span, ctx := opentracing.StartSpanFromContext(ctx, "alerting.prometheus")
|
||||||
|
span.SetTag("expr", query.Expr)
|
||||||
|
span.SetTag("start_unixnano", int64(query.Start.UnixNano()))
|
||||||
|
span.SetTag("stop_unixnano", int64(query.End.UnixNano()))
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
value, err := client.QueryRange(ctx, query.Expr, timeRange)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
queryResult, err := parseResponse(value, query)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result.Results[query.RefId] = queryResult
|
||||||
}
|
}
|
||||||
|
|
||||||
span, ctx := opentracing.StartSpanFromContext(ctx, "alerting.prometheus")
|
|
||||||
span.SetTag("expr", query.Expr)
|
|
||||||
span.SetTag("start_unixnano", int64(query.Start.UnixNano()))
|
|
||||||
span.SetTag("stop_unixnano", int64(query.End.UnixNano()))
|
|
||||||
defer span.Finish()
|
|
||||||
|
|
||||||
value, err := client.QueryRange(ctx, query.Expr, timeRange)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
queryResult, err := parseResponse(value, query)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
result.Results = queryResult
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,51 +147,54 @@ func formatLegend(metric model.Metric, query *PrometheusQuery) string {
|
|||||||
return string(result)
|
return string(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseQuery(dsInfo *models.DataSource, queries []*tsdb.Query, queryContext *tsdb.TsdbQuery) (*PrometheusQuery, error) {
|
func parseQuery(dsInfo *models.DataSource, queries []*tsdb.Query, queryContext *tsdb.TsdbQuery) ([]*PrometheusQuery, error) {
|
||||||
queryModel := queries[0]
|
qs := []*PrometheusQuery{}
|
||||||
|
for _, queryModel := range queries {
|
||||||
|
expr, err := queryModel.Model.Get("expr").String()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
expr, err := queryModel.Model.Get("expr").String()
|
format := queryModel.Model.Get("legendFormat").MustString("")
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
start, err := queryContext.TimeRange.ParseFrom()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
end, err := queryContext.TimeRange.ParseTo()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
dsInterval, err := tsdb.GetIntervalFrom(dsInfo, queryModel.Model, time.Second*15)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
intervalFactor := queryModel.Model.Get("intervalFactor").MustInt64(1)
|
||||||
|
interval := intervalCalculator.Calculate(queryContext.TimeRange, dsInterval)
|
||||||
|
step := time.Duration(int64(interval.Value) * intervalFactor)
|
||||||
|
|
||||||
|
qs = append(qs, &PrometheusQuery{
|
||||||
|
Expr: expr,
|
||||||
|
Step: step,
|
||||||
|
LegendFormat: format,
|
||||||
|
Start: start,
|
||||||
|
End: end,
|
||||||
|
RefId: queryModel.RefId,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
format := queryModel.Model.Get("legendFormat").MustString("")
|
return qs, nil
|
||||||
|
|
||||||
start, err := queryContext.TimeRange.ParseFrom()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
end, err := queryContext.TimeRange.ParseTo()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
dsInterval, err := tsdb.GetIntervalFrom(dsInfo, queryModel.Model, time.Second*15)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
intervalFactor := queryModel.Model.Get("intervalFactor").MustInt64(1)
|
|
||||||
interval := intervalCalculator.Calculate(queryContext.TimeRange, dsInterval)
|
|
||||||
step := time.Duration(int64(interval.Value) * intervalFactor)
|
|
||||||
|
|
||||||
return &PrometheusQuery{
|
|
||||||
Expr: expr,
|
|
||||||
Step: step,
|
|
||||||
LegendFormat: format,
|
|
||||||
Start: start,
|
|
||||||
End: end,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseResponse(value model.Value, query *PrometheusQuery) (map[string]*tsdb.QueryResult, error) {
|
func parseResponse(value model.Value, query *PrometheusQuery) (*tsdb.QueryResult, error) {
|
||||||
queryResults := make(map[string]*tsdb.QueryResult)
|
|
||||||
queryRes := tsdb.NewQueryResult()
|
queryRes := tsdb.NewQueryResult()
|
||||||
|
|
||||||
data, ok := value.(model.Matrix)
|
data, ok := value.(model.Matrix)
|
||||||
if !ok {
|
if !ok {
|
||||||
return queryResults, fmt.Errorf("Unsupported result format: %s", value.Type().String())
|
return queryRes, fmt.Errorf("Unsupported result format: %s", value.Type().String())
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range data {
|
for _, v := range data {
|
||||||
@ -204,6 +214,5 @@ func parseResponse(value model.Value, query *PrometheusQuery) (map[string]*tsdb.
|
|||||||
queryRes.Series = append(queryRes.Series, &series)
|
queryRes.Series = append(queryRes.Series, &series)
|
||||||
}
|
}
|
||||||
|
|
||||||
queryResults["A"] = queryRes
|
return queryRes, nil
|
||||||
return queryResults, nil
|
|
||||||
}
|
}
|
||||||
|
@ -60,9 +60,10 @@ func TestPrometheus(t *testing.T) {
|
|||||||
Convey("with 48h time range", func() {
|
Convey("with 48h time range", func() {
|
||||||
queryContext.TimeRange = tsdb.NewTimeRange("12h", "now")
|
queryContext.TimeRange = tsdb.NewTimeRange("12h", "now")
|
||||||
|
|
||||||
model, err := parseQuery(dsInfo, queryModels, queryContext)
|
models, err := parseQuery(dsInfo, queryModels, queryContext)
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
model := models[0]
|
||||||
So(model.Step, ShouldEqual, time.Second*30)
|
So(model.Step, ShouldEqual, time.Second*30)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -83,18 +84,22 @@ func TestPrometheus(t *testing.T) {
|
|||||||
Convey("with 48h time range", func() {
|
Convey("with 48h time range", func() {
|
||||||
queryContext.TimeRange = tsdb.NewTimeRange("48h", "now")
|
queryContext.TimeRange = tsdb.NewTimeRange("48h", "now")
|
||||||
|
|
||||||
model, err := parseQuery(dsInfo, queryModels, queryContext)
|
models, err := parseQuery(dsInfo, queryModels, queryContext)
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
model := models[0]
|
||||||
So(model.Step, ShouldEqual, time.Minute*2)
|
So(model.Step, ShouldEqual, time.Minute*2)
|
||||||
})
|
})
|
||||||
|
|
||||||
Convey("with 1h time range", func() {
|
Convey("with 1h time range", func() {
|
||||||
queryContext.TimeRange = tsdb.NewTimeRange("1h", "now")
|
queryContext.TimeRange = tsdb.NewTimeRange("1h", "now")
|
||||||
|
|
||||||
model, err := parseQuery(dsInfo, queryModels, queryContext)
|
models, err := parseQuery(dsInfo, queryModels, queryContext)
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
model := models[0]
|
||||||
So(model.Step, ShouldEqual, time.Second*15)
|
So(model.Step, ShouldEqual, time.Second*15)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -116,9 +121,11 @@ func TestPrometheus(t *testing.T) {
|
|||||||
Convey("with 48h time range", func() {
|
Convey("with 48h time range", func() {
|
||||||
queryContext.TimeRange = tsdb.NewTimeRange("48h", "now")
|
queryContext.TimeRange = tsdb.NewTimeRange("48h", "now")
|
||||||
|
|
||||||
model, err := parseQuery(dsInfo, queryModels, queryContext)
|
models, err := parseQuery(dsInfo, queryModels, queryContext)
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
model := models[0]
|
||||||
So(model.Step, ShouldEqual, time.Minute*20)
|
So(model.Step, ShouldEqual, time.Minute*20)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -139,9 +146,11 @@ func TestPrometheus(t *testing.T) {
|
|||||||
Convey("with 48h time range", func() {
|
Convey("with 48h time range", func() {
|
||||||
queryContext.TimeRange = tsdb.NewTimeRange("48h", "now")
|
queryContext.TimeRange = tsdb.NewTimeRange("48h", "now")
|
||||||
|
|
||||||
model, err := parseQuery(dsInfo, queryModels, queryContext)
|
models, err := parseQuery(dsInfo, queryModels, queryContext)
|
||||||
|
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
model := models[0]
|
||||||
So(model.Step, ShouldEqual, time.Minute*2)
|
So(model.Step, ShouldEqual, time.Minute*2)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -8,4 +8,5 @@ type PrometheusQuery struct {
|
|||||||
LegendFormat string
|
LegendFormat string
|
||||||
Start time.Time
|
Start time.Time
|
||||||
End time.Time
|
End time.Time
|
||||||
|
RefId string
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user