mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-15 00:13:30 +01:00
app/vmselect/promql: allow passing inf
arg into functions, which accept numeric limit on the number of output time series
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3461
This commit is contained in:
parent
afa232eebb
commit
808ce815e4
@ -748,7 +748,7 @@ func getIntK(k float64, kMax int) int {
|
|||||||
if math.IsNaN(k) {
|
if math.IsNaN(k) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
kn := int(k)
|
kn := floatToIntBounded(k)
|
||||||
if kn < 0 {
|
if kn < 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@ -999,14 +999,10 @@ func aggrFuncLimitK(afa *aggrFuncArg) ([]*timeseries, error) {
|
|||||||
if err := expectTransformArgsNum(args, 2); err != nil {
|
if err := expectTransformArgsNum(args, 2); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
limits, err := getScalar(args[0], 0)
|
limit, err := getIntNumber(args[0], 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot obtain limit arg: %w", err)
|
return nil, fmt.Errorf("cannot obtain limit arg: %w", err)
|
||||||
}
|
}
|
||||||
limit := 0
|
|
||||||
if len(limits) > 0 {
|
|
||||||
limit = int(limits[0])
|
|
||||||
}
|
|
||||||
if limit < 0 {
|
if limit < 0 {
|
||||||
limit = 0
|
limit = 0
|
||||||
}
|
}
|
||||||
@ -1155,3 +1151,13 @@ func lessWithNaNs(a, b float64) bool {
|
|||||||
}
|
}
|
||||||
return a < b
|
return a < b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func floatToIntBounded(f float64) int {
|
||||||
|
if f > math.MaxInt {
|
||||||
|
return math.MaxInt
|
||||||
|
}
|
||||||
|
if f < math.MinInt {
|
||||||
|
return math.MinInt
|
||||||
|
}
|
||||||
|
return int(f)
|
||||||
|
}
|
||||||
|
@ -5559,6 +5559,30 @@ func TestExecSuccess(t *testing.T) {
|
|||||||
resultExpected := []netstorage.Result{r1, r2}
|
resultExpected := []netstorage.Result{r1, r2}
|
||||||
f(q, resultExpected)
|
f(q, resultExpected)
|
||||||
})
|
})
|
||||||
|
t.Run(`limitk(inf)`, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
q := `sort(limitk(inf, label_set(10, "foo", "bar") or label_set(time()/150, "baz", "sss")))`
|
||||||
|
r1 := netstorage.Result{
|
||||||
|
MetricName: metricNameExpected,
|
||||||
|
Values: []float64{10, 10, 10, 10, 10, 10},
|
||||||
|
Timestamps: timestampsExpected,
|
||||||
|
}
|
||||||
|
r1.MetricName.Tags = []storage.Tag{{
|
||||||
|
Key: []byte("foo"),
|
||||||
|
Value: []byte("bar"),
|
||||||
|
}}
|
||||||
|
r2 := netstorage.Result{
|
||||||
|
MetricName: metricNameExpected,
|
||||||
|
Values: []float64{6.666666666666667, 8, 9.333333333333334, 10.666666666666666, 12, 13.333333333333334},
|
||||||
|
Timestamps: timestampsExpected,
|
||||||
|
}
|
||||||
|
r2.MetricName.Tags = []storage.Tag{{
|
||||||
|
Key: []byte("baz"),
|
||||||
|
Value: []byte("sss"),
|
||||||
|
}}
|
||||||
|
resultExpected := []netstorage.Result{r1, r2}
|
||||||
|
f(q, resultExpected)
|
||||||
|
})
|
||||||
t.Run(`any()`, func(t *testing.T) {
|
t.Run(`any()`, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
q := `any(label_set(10, "__name__", "x", "foo", "bar") or label_set(time()/150, "__name__", "y", "baz", "sss"))`
|
q := `any(label_set(10, "__name__", "x", "foo", "bar") or label_set(time()/150, "__name__", "y", "baz", "sss"))`
|
||||||
|
@ -2127,7 +2127,7 @@ func getIntNumber(arg interface{}, argNum int) (int, error) {
|
|||||||
}
|
}
|
||||||
n := 0
|
n := 0
|
||||||
if len(v) > 0 {
|
if len(v) > 0 {
|
||||||
n = int(v[0])
|
n = floatToIntBounded(v[0])
|
||||||
}
|
}
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
@ -371,14 +371,10 @@ func transformBucketsLimit(tfa *transformFuncArg) ([]*timeseries, error) {
|
|||||||
if err := expectTransformArgsNum(args, 2); err != nil {
|
if err := expectTransformArgsNum(args, 2); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
limits, err := getScalar(args[0], 1)
|
limit, err := getIntNumber(args[0], 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
limit := 0
|
|
||||||
if len(limits) > 0 {
|
|
||||||
limit = int(limits[0])
|
|
||||||
}
|
|
||||||
if limit <= 0 {
|
if limit <= 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@ -390,6 +386,7 @@ func transformBucketsLimit(tfa *transformFuncArg) ([]*timeseries, error) {
|
|||||||
if len(tss) == 0 {
|
if len(tss) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
pointsCount := len(tss[0].Values)
|
||||||
|
|
||||||
// Group timeseries by all MetricGroup+tags excluding `le` tag.
|
// Group timeseries by all MetricGroup+tags excluding `le` tag.
|
||||||
type x struct {
|
type x struct {
|
||||||
@ -437,7 +434,7 @@ func transformBucketsLimit(tfa *transformFuncArg) ([]*timeseries, error) {
|
|||||||
sort.Slice(leGroup, func(i, j int) bool {
|
sort.Slice(leGroup, func(i, j int) bool {
|
||||||
return leGroup[i].le < leGroup[j].le
|
return leGroup[i].le < leGroup[j].le
|
||||||
})
|
})
|
||||||
for n := range limits {
|
for n := 0; n < pointsCount; n++ {
|
||||||
prevValue := float64(0)
|
prevValue := float64(0)
|
||||||
for i := range leGroup {
|
for i := range leGroup {
|
||||||
xx := &leGroup[i]
|
xx := &leGroup[i]
|
||||||
|
@ -64,6 +64,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
|
|||||||
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): allow changing timezones for the requested data. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3075).
|
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): allow changing timezones for the requested data. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3075).
|
||||||
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): provide fast path for hiding results for all the queries except the given one by clicking `eye` icon with `ctrl` key pressed. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3446).
|
* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): provide fast path for hiding results for all the queries except the given one by clicking `eye` icon with `ctrl` key pressed. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3446).
|
||||||
* FEATURE: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): add `range_trim_spikes(phi, q)` function for trimming `phi` percent of the largest spikes per each time series returned by `q`. See [these docs](https://docs.victoriametrics.com/MetricsQL.html#range_trim_spikes).
|
* FEATURE: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): add `range_trim_spikes(phi, q)` function for trimming `phi` percent of the largest spikes per each time series returned by `q`. See [these docs](https://docs.victoriametrics.com/MetricsQL.html#range_trim_spikes).
|
||||||
|
* FEATURE: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): allow passing `inf` arg into [limitk](https://docs.victoriametrics.com/MetricsQL.html#limitk), [topk](https://docs.victoriametrics.com/MetricsQL.html#topk), [bottomk](https://docs.victoriametrics.com/MetricsQL.html) and other functions, which accept numeric arg, which limits the number of output time series. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3461).
|
||||||
* FEATURE: [vmgateway](https://docs.victoriametrics.com/vmgateway.html): add support for JWT token signature verification. See [these docs](https://docs.victoriametrics.com/vmgateway.html#jwt-signature-verification) for details.
|
* FEATURE: [vmgateway](https://docs.victoriametrics.com/vmgateway.html): add support for JWT token signature verification. See [these docs](https://docs.victoriametrics.com/vmgateway.html#jwt-signature-verification) for details.
|
||||||
* FEATURE: put the version of VictoriaMetrics in the first message of [query trace](https://docs.victoriametrics.com/#query-tracing). This should simplify debugging.
|
* FEATURE: put the version of VictoriaMetrics in the first message of [query trace](https://docs.victoriametrics.com/#query-tracing). This should simplify debugging.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user