mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(prometheus): add support for legend formatting
This commit is contained in:
@@ -111,7 +111,7 @@ func (c *QueryCondition) getRequestForAlertRule(datasource *m.DataSource, timera
|
||||
Queries: []*tsdb.Query{
|
||||
{
|
||||
RefId: "A",
|
||||
Query: c.Query.Model.Get("target").MustString(),
|
||||
Model: c.Query.Model,
|
||||
DataSource: &tsdb.DataSourceInfo{
|
||||
Id: datasource.Id,
|
||||
Name: datasource.Name,
|
||||
|
||||
@@ -54,7 +54,7 @@ func (e *GraphiteExecutor) Execute(queries tsdb.QuerySlice, context *tsdb.QueryC
|
||||
}
|
||||
|
||||
for _, query := range queries {
|
||||
formData["target"] = []string{query.Query}
|
||||
formData["target"] = []string{query.Model.Get("target").MustString()}
|
||||
}
|
||||
|
||||
if setting.Env == setting.DEV {
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package tsdb
|
||||
|
||||
import "github.com/grafana/grafana/pkg/components/simplejson"
|
||||
|
||||
type Query struct {
|
||||
RefId string
|
||||
Query string
|
||||
Model *simplejson.Json
|
||||
Depends []string
|
||||
DataSource *DataSourceInfo
|
||||
Results []*TimeSeries
|
||||
|
||||
@@ -3,6 +3,8 @@ package prometheus
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
@@ -53,25 +55,52 @@ func (e *PrometheusExecutor) Execute(queries tsdb.QuerySlice, queryContext *tsdb
|
||||
|
||||
from, _ := queryContext.TimeRange.FromTime()
|
||||
to, _ := queryContext.TimeRange.ToTime()
|
||||
|
||||
query := parseQuery(queries)
|
||||
|
||||
timeRange := prometheus.Range{
|
||||
Start: from,
|
||||
End: to,
|
||||
Step: time.Second,
|
||||
Step: query.Step,
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
value, err := client.QueryRange(ctx, "counters_logins", timeRange)
|
||||
value, err := client.QueryRange(context.Background(), query.Expr, timeRange)
|
||||
|
||||
if err != nil {
|
||||
result.Error = err
|
||||
return result
|
||||
}
|
||||
|
||||
result.QueryResults = parseResponse(value)
|
||||
result.QueryResults = parseResponse(value, query)
|
||||
return result
|
||||
}
|
||||
|
||||
func parseResponse(value pmodel.Value) map[string]*tsdb.QueryResult {
|
||||
func formatLegend(metric pmodel.Metric, query PrometheusQuery) string {
|
||||
r, _ := regexp.Compile(`\{\{\s*(.+?)\s*\}\}`)
|
||||
|
||||
result := r.ReplaceAllFunc([]byte(query.LegendFormat), func(in []byte) []byte {
|
||||
ind := strings.Replace(strings.Replace(string(in), "{{", "", 1), "}}", "", 1)
|
||||
if val, exists := metric[pmodel.LabelName(ind)]; exists {
|
||||
return []byte(val)
|
||||
}
|
||||
|
||||
return in
|
||||
})
|
||||
|
||||
return string(result)
|
||||
}
|
||||
|
||||
func parseQuery(queries tsdb.QuerySlice) PrometheusQuery {
|
||||
queryModel := queries[0]
|
||||
|
||||
return PrometheusQuery{
|
||||
Expr: queryModel.Model.Get("expr").MustString(),
|
||||
Step: time.Second * time.Duration(queryModel.Model.Get("step").MustInt64(1)),
|
||||
LegendFormat: queryModel.Model.Get("legendFormat").MustString(),
|
||||
}
|
||||
}
|
||||
|
||||
func parseResponse(value pmodel.Value, query PrometheusQuery) map[string]*tsdb.QueryResult {
|
||||
queryResults := make(map[string]*tsdb.QueryResult)
|
||||
queryRes := &tsdb.QueryResult{}
|
||||
|
||||
@@ -86,7 +115,7 @@ func parseResponse(value pmodel.Value) map[string]*tsdb.QueryResult {
|
||||
}
|
||||
|
||||
queryRes.Series = append(queryRes.Series, &tsdb.TimeSeries{
|
||||
Name: v.Metric.String(),
|
||||
Name: formatLegend(v.Metric, query),
|
||||
Points: points,
|
||||
})
|
||||
}
|
||||
|
||||
26
pkg/tsdb/prometheus/prometheus_test.go
Normal file
26
pkg/tsdb/prometheus/prometheus_test.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
p "github.com/prometheus/common/model"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestPrometheus(t *testing.T) {
|
||||
Convey("Prometheus", t, func() {
|
||||
|
||||
Convey("converting metric name", func() {
|
||||
metric := map[p.LabelName]p.LabelValue{
|
||||
p.LabelName("app"): p.LabelValue("backend"),
|
||||
p.LabelName("device"): p.LabelValue("mobile"),
|
||||
}
|
||||
|
||||
query := PrometheusQuery{
|
||||
LegendFormat: "legend {{app}} {{device}} {{broken}}",
|
||||
}
|
||||
|
||||
So(formatLegend(metric, query), ShouldEqual, "legend backend mobile {{broken}}")
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1 +1,9 @@
|
||||
package prometheus
|
||||
|
||||
import "time"
|
||||
|
||||
type PrometheusQuery struct {
|
||||
Expr string
|
||||
Step time.Duration
|
||||
LegendFormat string
|
||||
}
|
||||
|
||||
@@ -113,7 +113,6 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS
|
||||
throw response.error;
|
||||
}
|
||||
delete self.lastErrors.query;
|
||||
|
||||
_.each(response.data.data.result, function(metricData) {
|
||||
result.push(self.transformMetricData(metricData, activeTargets[index], start, end));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user