From fc8fe38a82e87914aeb128a5e306d8217304bfb1 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Fri, 17 Jul 2020 15:16:01 +0300 Subject: [PATCH] app/vmselect/promql: add `group()` aggregate function to MetricsQL This function has been added in Prometheus 2.20. See https://github.com/prometheus/prometheus/pull/7480 --- app/vmselect/promql/aggr.go | 22 ++++++++++ app/vmselect/promql/exec_test.go | 41 +++++++++++++++++++ go.mod | 2 +- go.sum | 4 +- .../VictoriaMetrics/metricsql/aggr.go | 1 + vendor/modules.txt | 2 +- 6 files changed, 68 insertions(+), 4 deletions(-) diff --git a/app/vmselect/promql/aggr.go b/app/vmselect/promql/aggr.go index 4ddb96c60..4cf01c5ff 100644 --- a/app/vmselect/promql/aggr.go +++ b/app/vmselect/promql/aggr.go @@ -27,6 +27,7 @@ var aggrFuncs = map[string]aggrFunc{ "bottomk": newAggrFuncTopK(true), "topk": newAggrFuncTopK(false), "quantile": aggrFuncQuantile, + "group": aggrFuncGroup, // PromQL extension funcs "median": aggrFuncMedian, @@ -138,6 +139,27 @@ func aggrFuncAny(afa *aggrFuncArg) ([]*timeseries, error) { return aggrFuncExt(afe, args[0], &afa.ae.Modifier, limit, true) } +func aggrFuncGroup(afa *aggrFuncArg) ([]*timeseries, error) { + args := afa.args + if err := expectTransformArgsNum(args, 1); err != nil { + return nil, err + } + afe := func(tss []*timeseries) []*timeseries { + // See https://github.com/prometheus/prometheus/commit/72425d4e3d14d209cc3f3f6e10e3240411303399 + values := tss[0].Values + for j := range values { + values[j] = 1 + } + return tss[:1] + } + limit := afa.ae.Limit + if limit > 1 { + // Only a single time series per group must be returned + limit = 1 + } + return aggrFuncExt(afe, args[0], &afa.ae.Modifier, limit, false) +} + func aggrFuncSum(tss []*timeseries) []*timeseries { if len(tss) == 1 { // Fast path - nothing to sum. diff --git a/app/vmselect/promql/exec_test.go b/app/vmselect/promql/exec_test.go index 432fef6b1..f026f595c 100644 --- a/app/vmselect/promql/exec_test.go +++ b/app/vmselect/promql/exec_test.go @@ -3842,6 +3842,46 @@ func TestExecSuccess(t *testing.T) { resultExpected := []netstorage.Result{r} f(q, resultExpected) }) + t.Run(`group() by (test)`, func(t *testing.T) { + t.Parallel() + q := `group(( + label_set(5, "__name__", "data", "test", "three samples", "point", "a"), + label_set(6, "__name__", "data", "test", "three samples", "point", "b"), + label_set(7, "__name__", "data", "test", "three samples", "point", "c"), + )) by (test)` + r := netstorage.Result{ + MetricName: metricNameExpected, + Values: []float64{1, 1, 1, 1, 1, 1}, + Timestamps: timestampsExpected, + } + r.MetricName.MetricGroup = nil + r.MetricName.Tags = []storage.Tag{{ + Key: []byte("test"), + Value: []byte("three samples"), + }} + resultExpected := []netstorage.Result{r} + f(q, resultExpected) + }) + t.Run(`group() without (point)`, func(t *testing.T) { + t.Parallel() + q := `group(( + label_set(5, "__name__", "data", "test", "three samples", "point", "a"), + label_set(6, "__name__", "data", "test", "three samples", "point", "b"), + label_set(7, "__name__", "data", "test", "three samples", "point", "c"), + )) without (point)` + r := netstorage.Result{ + MetricName: metricNameExpected, + Values: []float64{1, 1, 1, 1, 1, 1}, + Timestamps: timestampsExpected, + } + r.MetricName.MetricGroup = nil + r.MetricName.Tags = []storage.Tag{{ + Key: []byte("test"), + Value: []byte("three samples"), + }} + resultExpected := []netstorage.Result{r} + f(q, resultExpected) + }) t.Run(`topk(-1)`, func(t *testing.T) { t.Parallel() q := `sort(topk(-1, label_set(10, "foo", "bar") or label_set(time()/150, "baz", "sss")))` @@ -5632,6 +5672,7 @@ func TestExecError(t *testing.T) { f(`count_values()`) f(`quantile()`) f(`any()`) + f(`group()`) f(`topk()`) f(`topk_min()`) f(`topk_max()`) diff --git a/go.mod b/go.mod index 4a6e2aa1d..6bcf99a39 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( // like https://github.com/valyala/fasthttp/commit/996610f021ff45fdc98c2ce7884d5fa4e7f9199b github.com/VictoriaMetrics/fasthttp v1.0.1 github.com/VictoriaMetrics/metrics v1.11.3 - github.com/VictoriaMetrics/metricsql v0.2.4 + github.com/VictoriaMetrics/metricsql v0.2.5 github.com/aws/aws-sdk-go v1.33.5 github.com/cespare/xxhash/v2 v2.1.1 github.com/golang/snappy v0.0.1 diff --git a/go.sum b/go.sum index 1c0eb1f7a..6952dfdd7 100644 --- a/go.sum +++ b/go.sum @@ -53,8 +53,8 @@ github.com/VictoriaMetrics/metrics v1.11.2 h1:t/ceLP6SvagUqypCKU7cI7+tQn54+TIV/t github.com/VictoriaMetrics/metrics v1.11.2/go.mod h1:LU2j9qq7xqZYXz8tF3/RQnB2z2MbZms5TDiIg9/NHiQ= github.com/VictoriaMetrics/metrics v1.11.3 h1:eSfXc0CrquKa1VTNUvhP+dhNjLUZHQGTFfp19mYCQWE= github.com/VictoriaMetrics/metrics v1.11.3/go.mod h1:LU2j9qq7xqZYXz8tF3/RQnB2z2MbZms5TDiIg9/NHiQ= -github.com/VictoriaMetrics/metricsql v0.2.4 h1:240YwT8B4KITVFE7EOrf1rVvsY+5fYsAzyb+bI6/q50= -github.com/VictoriaMetrics/metricsql v0.2.4/go.mod h1:UIjd9S0W1UnTWlJdM0wLS+2pfuPqjwqKoK8yTos+WyE= +github.com/VictoriaMetrics/metricsql v0.2.5 h1:9kL+RA2yuPfMpYdqycRbKOJ9WKdDmPmV6hAju5L6ti0= +github.com/VictoriaMetrics/metricsql v0.2.5/go.mod h1:UIjd9S0W1UnTWlJdM0wLS+2pfuPqjwqKoK8yTos+WyE= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/aws/aws-sdk-go v1.33.5 h1:p2fr1ryvNTU6avUWLI+/H7FGv0TBIjzVM5WDgXBBv4U= diff --git a/vendor/github.com/VictoriaMetrics/metricsql/aggr.go b/vendor/github.com/VictoriaMetrics/metricsql/aggr.go index a6dddbabc..8d8e7a6d8 100644 --- a/vendor/github.com/VictoriaMetrics/metricsql/aggr.go +++ b/vendor/github.com/VictoriaMetrics/metricsql/aggr.go @@ -17,6 +17,7 @@ var aggrFuncs = map[string]bool{ "bottomk": true, "topk": true, "quantile": true, + "group": true, // MetricsQL extension funcs "median": true, diff --git a/vendor/modules.txt b/vendor/modules.txt index 666581eff..06fc63f38 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -16,7 +16,7 @@ github.com/VictoriaMetrics/fasthttp/fasthttputil github.com/VictoriaMetrics/fasthttp/stackless # github.com/VictoriaMetrics/metrics v1.11.3 github.com/VictoriaMetrics/metrics -# github.com/VictoriaMetrics/metricsql v0.2.4 +# github.com/VictoriaMetrics/metricsql v0.2.5 github.com/VictoriaMetrics/metricsql github.com/VictoriaMetrics/metricsql/binaryop # github.com/aws/aws-sdk-go v1.33.5