Commit 4c88db3e by bergquist

feat(prometheus): add support for legend formatting

parent 43d8bd5a
......@@ -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 {
......
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,
})
}
......
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}}")
})
})
}
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));
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment