app/vmselect/promql: add count_le_over_time(m[d], le) and count_gt_over_time(m[d], gt) functions

These functions returns the number of raw samples that don't exceed `le` or are bigger than `gt`.
These functions are complement to already existing `share_le_over_time(m[d], le)` and `share_gt_over_time(m[d], gt)`.
This commit is contained in:
Aliaksandr Valialkin 2020-09-03 15:26:14 +03:00
parent d5b985f086
commit f4e7e5fb90
8 changed files with 102 additions and 6 deletions

View file

@ -3986,6 +3986,28 @@ func TestExecSuccess(t *testing.T) {
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`count_gt_over_time`, func(t *testing.T) {
t.Parallel()
q := `count_gt_over_time(rand(0)[200s:10s], 0.7)`
r := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{7, 6, 10, 6, 6, 5},
Timestamps: timestampsExpected,
}
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`count_le_over_time`, func(t *testing.T) {
t.Parallel()
q := `count_le_over_time(rand(0)[200s:10s], 0.7)`
r := netstorage.Result{
MetricName: metricNameExpected,
Values: []float64{13, 14, 10, 14, 14, 15},
Timestamps: timestampsExpected,
}
resultExpected := []netstorage.Result{r}
f(q, resultExpected)
})
t.Run(`increases_over_time`, func(t *testing.T) {
t.Parallel()
q := `increases_over_time(rand(0)[200s:10s])`
@ -6006,6 +6028,10 @@ func TestExecError(t *testing.T) {
f(`prometheus_buckets()`)
f(`buckets_limit()`)
f(`buckets_limit(1)`)
f(`share_le_over_time()`)
f(`share_gt_over_time()`)
f(`count_le_over_time()`)
f(`count_gt_over_time()`)
// Invalid argument type
f(`median_over_time({}, 2)`)

View file

@ -62,6 +62,8 @@ var rollupFuncs = map[string]newRollupFunc{
"tmax_over_time": newRollupFuncOneArg(rollupTmax),
"share_le_over_time": newRollupShareLE,
"share_gt_over_time": newRollupShareGT,
"count_le_over_time": newRollupCountLE,
"count_gt_over_time": newRollupCountGT,
"histogram_over_time": newRollupFuncOneArg(rollupHistogram),
"rollup": newRollupFuncOneArg(rollupFake),
"rollup_rate": newRollupFuncOneArg(rollupFake), // + rollupFuncsRemoveCounterResets
@ -834,6 +836,25 @@ func countFilterGT(values []float64, gt float64) int {
}
func newRollupShareFilter(args []interface{}, countFilter func(values []float64, limit float64) int) (rollupFunc, error) {
rf, err := newRollupCountFilter(args, countFilter)
if err != nil {
return nil, err
}
return func(rfa *rollupFuncArg) float64 {
n := rf(rfa)
return n / float64(len(rfa.values))
}, nil
}
func newRollupCountLE(args []interface{}) (rollupFunc, error) {
return newRollupCountFilter(args, countFilterLE)
}
func newRollupCountGT(args []interface{}) (rollupFunc, error) {
return newRollupCountFilter(args, countFilterGT)
}
func newRollupCountFilter(args []interface{}, countFilter func(values []float64, limit float64) int) (rollupFunc, error) {
if err := expectRollupArgsNum(args, 2); err != nil {
return nil, err
}
@ -849,8 +870,7 @@ func newRollupShareFilter(args []interface{}, countFilter func(values []float64,
return nan
}
limit := limits[rfa.idx]
n := countFilter(values, limit)
return float64(n) / float64(len(values))
return float64(countFilter(values, limit))
}
return rf, nil
}

View file

@ -239,6 +239,52 @@ func TestRollupShareGTOverTime(t *testing.T) {
f(1000, 0)
}
func TestRollupCountLEOverTime(t *testing.T) {
f := func(le, vExpected float64) {
t.Helper()
les := []*timeseries{{
Values: []float64{le},
Timestamps: []int64{123},
}}
var me metricsql.MetricExpr
args := []interface{}{&metricsql.RollupExpr{Expr: &me}, les}
testRollupFunc(t, "count_le_over_time", args, &me, vExpected)
}
f(-123, 0)
f(0, 0)
f(10, 0)
f(12, 1)
f(30, 2)
f(50, 9)
f(100, 11)
f(123, 12)
f(1000, 12)
}
func TestRollupCountGTOverTime(t *testing.T) {
f := func(gt, vExpected float64) {
t.Helper()
gts := []*timeseries{{
Values: []float64{gt},
Timestamps: []int64{123},
}}
var me metricsql.MetricExpr
args := []interface{}{&metricsql.RollupExpr{Expr: &me}, gts}
testRollupFunc(t, "count_gt_over_time", args, &me, vExpected)
}
f(-123, 12)
f(0, 12)
f(10, 12)
f(12, 11)
f(30, 10)
f(50, 3)
f(100, 1)
f(123, 0)
f(1000, 0)
}
func TestRollupQuantileOverTime(t *testing.T) {
f := func(phi, vExpected float64) {
t.Helper()

View file

@ -115,6 +115,8 @@ This functionality can be tried at [an editable Grafana dashboard](http://play-g
Example: `share_le_over_time(memory_usage_bytes[24h], 100*1024*1024)` returns the share of time series values for the last 24 hours when memory usage was below or equal to 100MB.
- `share_gt_over_time(m[d], gt)` - returns share (in the range 0..1) of values in `m` over `d`, which are bigger than `gt`. Useful for calculating SLI and SLO.
Example: `share_gt_over_time(up[24h], 0)` - returns service availability for the last 24 hours.
- `count_le_over_time(m[d], le)` - returns the number of raw samples for `m` over `d`, which don't exceed `le`.
- `count_gt_over_time(m[d], gt)` - returns the number of raw samples for `m` over `d`, which are bigger than `gt`.
- `tmin_over_time(m[d])` - returns timestamp for the minimum value for `m` over `d` time range.
- `tmax_over_time(m[d])` - returns timestamp for the maximum value for `m` over `d` time range.
- `aggr_over_time(("aggr_func1", "aggr_func2", ...), m[d])` - simultaneously calculates all the listed `aggr_func*` for `m` over `d` time range.

2
go.mod
View file

@ -8,7 +8,7 @@ require (
// like https://github.com/valyala/fasthttp/commit/996610f021ff45fdc98c2ce7884d5fa4e7f9199b
github.com/VictoriaMetrics/fasthttp v1.0.5
github.com/VictoriaMetrics/metrics v1.12.3
github.com/VictoriaMetrics/metricsql v0.4.2
github.com/VictoriaMetrics/metricsql v0.4.3
github.com/aws/aws-sdk-go v1.34.14
github.com/cespare/xxhash/v2 v2.1.1
github.com/golang/snappy v0.0.1

4
go.sum
View file

@ -58,8 +58,8 @@ github.com/VictoriaMetrics/metrics v1.12.2 h1:SG8iAmqavDNuh7GIdHPoGHUhDL23KeKfvS
github.com/VictoriaMetrics/metrics v1.12.2/go.mod h1:Z1tSfPfngDn12bTfZSCqArT3OPY3u88J12hSoOhuiRE=
github.com/VictoriaMetrics/metrics v1.12.3 h1:Fe6JHC6MSEKa+BtLhPN8WIvS+HKPzMc2evEpNeCGy7I=
github.com/VictoriaMetrics/metrics v1.12.3/go.mod h1:Z1tSfPfngDn12bTfZSCqArT3OPY3u88J12hSoOhuiRE=
github.com/VictoriaMetrics/metricsql v0.4.2 h1:cLrPMK0IASCglRwHBwMAW+ooxG77vxlEkYheVc7gtqs=
github.com/VictoriaMetrics/metricsql v0.4.2/go.mod h1:ylO7YITho/Iw6P71oEaGyHbO94bGoGtzWfLGqFhMIg8=
github.com/VictoriaMetrics/metricsql v0.4.3 h1:4lezcOTMeGOfGtrf+I2YEC98lkx4nRczTiLrL+6E3CE=
github.com/VictoriaMetrics/metricsql v0.4.3/go.mod h1:ylO7YITho/Iw6P71oEaGyHbO94bGoGtzWfLGqFhMIg8=
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/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=

View file

@ -47,6 +47,8 @@ var rollupFuncs = map[string]bool{
"tmax_over_time": true,
"share_le_over_time": true,
"share_gt_over_time": true,
"count_le_over_time": true,
"count_gt_over_time": true,
"histogram_over_time": true,
"rollup": true,
"rollup_rate": true,

2
vendor/modules.txt vendored
View file

@ -16,7 +16,7 @@ github.com/VictoriaMetrics/fasthttp/fasthttputil
github.com/VictoriaMetrics/fasthttp/stackless
# github.com/VictoriaMetrics/metrics v1.12.3
github.com/VictoriaMetrics/metrics
# github.com/VictoriaMetrics/metricsql v0.4.2
# github.com/VictoriaMetrics/metricsql v0.4.3
github.com/VictoriaMetrics/metricsql
github.com/VictoriaMetrics/metricsql/binaryop
# github.com/aws/aws-sdk-go v1.34.14