From 655612561f6a44d9397e171bb6157b8b6569320f Mon Sep 17 00:00:00 2001 From: siddhikhapare Date: Thu, 9 Feb 2023 23:19:47 +0530 Subject: [PATCH 1/5] add absent function Signed-off-by: siddhikhapare --- engine/engine_test.go | 19 +++++++++++++++++++ execution/function/functions.go | 16 ++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/engine/engine_test.go b/engine/engine_test.go index ab11f4bc..13612d9d 100644 --- a/engine/engine_test.go +++ b/engine/engine_test.go @@ -1500,6 +1500,16 @@ func TestQueriesAgainstOldEngine(t *testing.T) { end: time.Unix(3000, 0), step: 2 * time.Second, }, + { + name: "absent", + load: `load 30s + absent{pod="nginx-1", series="1"} 0 + absent{pod="nginx-2", series="1"} 0`, + query: "absent(absent)", + start: time.Unix(0, 0), + end: time.Unix(3000, 0), + step: 2 * time.Second, + }, } disableOptimizerOpts := []bool{true, false} @@ -2431,6 +2441,15 @@ func TestInstantQuery(t *testing.T) { http_requests_total{pod="nginx-2", series="1"} -10+1x50`, query: "sgn(http_requests_total)", }, + { + name: "absent", + load: `load 30s + absent{pod="nginx-1", series="1"} 0 + absent{pod="nginx-2", series="1"} 0`, + query: "absent(absent)", + queryTime: defaultQueryTime, + sortByLabels: true, + }, } disableOptimizerOpts := []bool{true, false} diff --git a/execution/function/functions.go b/execution/function/functions.go index b4dc75e0..6da6e231 100644 --- a/execution/function/functions.go +++ b/execution/function/functions.go @@ -434,6 +434,22 @@ var Funcs = map[string]FunctionCall{ return float64(t.Year()) }) }, + "absent": func(f FunctionArgs) promql.Sample { + if len(f.Points) == 0 { + return promql.Sample{ + Metric: f.Labels, + Point: promql.Point{ + T: f.StepTime, + V: 1, + }, + } + } + + return promql.Sample{ + Metric: f.Labels, + Point: promql.Point{}, + } + }, } func NewFunctionCall(f *parser.Function) (FunctionCall, error) { From bacf1850cbf1350c7fe0885d012d4af2e73431da Mon Sep 17 00:00:00 2001 From: siddhikhapare Date: Sat, 11 Feb 2023 12:03:54 +0530 Subject: [PATCH 2/5] test file modified Signed-off-by: siddhikhapare --- engine/engine_test.go | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/engine/engine_test.go b/engine/engine_test.go index 13612d9d..accb028d 100644 --- a/engine/engine_test.go +++ b/engine/engine_test.go @@ -1502,13 +1502,11 @@ func TestQueriesAgainstOldEngine(t *testing.T) { }, { name: "absent", - load: `load 30s - absent{pod="nginx-1", series="1"} 0 - absent{pod="nginx-2", series="1"} 0`, - query: "absent(absent)", - start: time.Unix(0, 0), - end: time.Unix(3000, 0), - step: 2 * time.Second, + load: "", + query: `absent(metric)`, + start: time.Now().Add(-30 * time.Second), + end: time.Now(), + step: step, }, } @@ -2443,12 +2441,10 @@ func TestInstantQuery(t *testing.T) { }, { name: "absent", - load: `load 30s - absent{pod="nginx-1", series="1"} 0 - absent{pod="nginx-2", series="1"} 0`, - query: "absent(absent)", - queryTime: defaultQueryTime, - sortByLabels: true, + load: "", + query: `absent(metric)`, + queryTime: time.Now(), + sortByLabels: false, }, } From edaa37f31cbcdf546fa7cf1957fdb79cec88bd56 Mon Sep 17 00:00:00 2001 From: siddhikhapare Date: Sat, 11 Feb 2023 23:14:52 +0530 Subject: [PATCH 3/5] add support for functions Signed-off-by: siddhikhapare --- engine/engine_test.go | 41 +++++++++++++++++++++++++++++++++ execution/function/functions.go | 37 +++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/engine/engine_test.go b/engine/engine_test.go index accb028d..c891afd3 100644 --- a/engine/engine_test.go +++ b/engine/engine_test.go @@ -1507,6 +1507,29 @@ func TestQueriesAgainstOldEngine(t *testing.T) { start: time.Now().Add(-30 * time.Second), end: time.Now(), step: step, + }, + { + name: "sort", + load: `load 30s + metric{label="value_1"} 20 + metric{label="value_2"} 30 + metric{label="value_3"} 10 + `, + query: "sort(metric)", + start: time.Unix(0, 0), + end: time.Unix(3000, 0), + step: 10 * time.Second, + }, + { + name: "sort_desc", + load: `load 30s + metric{label="value_1"} 20 + metric{label="value_2"} 30 + metric{label="value_3"} 10`, + query: "sort_desc(metric)", + start: time.Unix(0, 0), + end: time.Unix(3000, 0), + step: 10 * time.Second, }, } @@ -2446,6 +2469,24 @@ func TestInstantQuery(t *testing.T) { queryTime: time.Now(), sortByLabels: false, }, + { + name: "sort", + load: `load 30s + metric{label="value_1"} 20 + metric{label="value_2"} 30 + metric{label="value_3"} 10`, + query: "sort(metric)", + queryTime: defaultQueryTime, + }, + { + name: "sort_desc", + load: `load 30s + metric{label="value_1"} 20 + metric{label="value_2"} 30 + metric{label="value_3"} 10`, + query: "sort_desc(metric)", + queryTime: defaultQueryTime, + }, } disableOptimizerOpts := []bool{true, false} diff --git a/execution/function/functions.go b/execution/function/functions.go index 6da6e231..b2ef3e71 100644 --- a/execution/function/functions.go +++ b/execution/function/functions.go @@ -450,6 +450,43 @@ var Funcs = map[string]FunctionCall{ Point: promql.Point{}, } }, + "sort": func(f FunctionArgs) promql.Sample{ + input := f.Args[0].(*promql.Vector) + + samples := make(promql.Samples, len(input)) + for i, s := range input{ + samples[i] = s + } + + sort.Slice(samples, func(i, j int) bool{ + return samples[i].V < samples[j].V + }) + + // Convert sorted slice of samples back into vector. + result := make(promql.Vector, len(input)) + for i, s := range samples{ + result[i] = s + } + return result + }, + "sort_desc": func(f FunctionArgs) promql.Sample { + input := f.Args[0].(*promql.Vector) + + samples := make(promql.Samples, len(input)) + for i, s := range input{ + samples[i] = s + } + + sort.Slice(samples, func(i, j int) bool { + return samples[i].V > samples[j].V + }) + + result := make(promql.Vector, len(input)) + for i, s := range samples{ + result[i] = s + } + return result + }, } func NewFunctionCall(f *parser.Function) (FunctionCall, error) { From 3443fc80714da13aa01a821afc489a921aa39a2a Mon Sep 17 00:00:00 2001 From: siddhikhapare Date: Sun, 12 Feb 2023 23:32:27 +0530 Subject: [PATCH 4/5] files modified Signed-off-by: siddhikhapare --- engine/engine_test.go | 35 +++++++++++++++++++++++++-------- execution/function/functions.go | 24 ++++++++++++++++++---- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/engine/engine_test.go b/engine/engine_test.go index c891afd3..abf4ec20 100644 --- a/engine/engine_test.go +++ b/engine/engine_test.go @@ -1501,13 +1501,23 @@ func TestQueriesAgainstOldEngine(t *testing.T) { step: 2 * time.Second, }, { - name: "absent", + name: "absent with present series", + load: `load 30s + absent{pod="nginx-1", series="1"} 0 + absent{pod="nginx-2", series="1"} 0`, + query: "absent(metric)", + start: time.Unix(0, 0), + end: time.Unix(3000, 0), + step: 10 * time.Second, + }, + { + name: "absent with non-present series", load: "", - query: `absent(metric)`, - start: time.Now().Add(-30 * time.Second), - end: time.Now(), - step: step, - }, + query: "absent(non_existent_metric)", + start: time.Unix(0, 0), + end: time.Unix(3000, 0), + step: 10 * time.Second, + }, { name: "sort", load: `load 30s @@ -2463,9 +2473,18 @@ func TestInstantQuery(t *testing.T) { query: "sgn(http_requests_total)", }, { - name: "absent", + name: "absent with present series", + load: `load 30s + absent{pod="nginx-1", series="1"} 0 + absent{pod="nginx-2", series="1"} 0`, + query: "absent(metric)", + queryTime: time.Now(), + sortByLabels: true, + }, + { + name: "absent with non-present series", load: "", - query: `absent(metric)`, + query: "absent(non_existent_metric)", queryTime: time.Now(), sortByLabels: false, }, diff --git a/execution/function/functions.go b/execution/function/functions.go index b2ef3e71..2ebeb04c 100644 --- a/execution/function/functions.go +++ b/execution/function/functions.go @@ -7,6 +7,7 @@ import ( "fmt" "math" "time" + "sort" "github.com/efficientgo/core/errors" "github.com/prometheus/prometheus/model/histogram" @@ -26,6 +27,7 @@ type FunctionArgs struct { SelectRange int64 ScalarPoints []float64 Offset int64 + Args []interface{} } // FunctionCall represents functions as defined in https://prometheus.io/docs/prometheus/latest/querying/functions/ @@ -453,7 +455,7 @@ var Funcs = map[string]FunctionCall{ "sort": func(f FunctionArgs) promql.Sample{ input := f.Args[0].(*promql.Vector) - samples := make(promql.Samples, len(input)) + samples := make(promql.Sample, len(input)) for i, s := range input{ samples[i] = s } @@ -467,12 +469,20 @@ var Funcs = map[string]FunctionCall{ for i, s := range samples{ result[i] = s } - return result + + // Return a sample with the sorted vector as its value + return promql.Sample{ + Metric: promql.Metric{}, + Point: promql.Point{ + T: f.StepTime, + V: result, + }, + } }, "sort_desc": func(f FunctionArgs) promql.Sample { input := f.Args[0].(*promql.Vector) - samples := make(promql.Samples, len(input)) + samples := make(promql.Sample, len(input)) for i, s := range input{ samples[i] = s } @@ -485,7 +495,13 @@ var Funcs = map[string]FunctionCall{ for i, s := range samples{ result[i] = s } - return result + return promql.Sample{ + Metric: promql.Metric{}, + Point: promql.Point{ + T: f.StepTime, + V: result, + }, + } }, } From 75adcb2bbc7720e5b02d6c9a2e7801a9ad91e85c Mon Sep 17 00:00:00 2001 From: siddhikhapare Date: Thu, 16 Feb 2023 14:37:16 +0530 Subject: [PATCH 5/5] absent function added Signed-off-by: siddhikhapare --- engine/engine_test.go | 41 ------------------------ execution/function/functions.go | 57 ++------------------------------- 2 files changed, 2 insertions(+), 96 deletions(-) diff --git a/engine/engine_test.go b/engine/engine_test.go index abf4ec20..4324c670 100644 --- a/engine/engine_test.go +++ b/engine/engine_test.go @@ -1518,29 +1518,6 @@ func TestQueriesAgainstOldEngine(t *testing.T) { end: time.Unix(3000, 0), step: 10 * time.Second, }, - { - name: "sort", - load: `load 30s - metric{label="value_1"} 20 - metric{label="value_2"} 30 - metric{label="value_3"} 10 - `, - query: "sort(metric)", - start: time.Unix(0, 0), - end: time.Unix(3000, 0), - step: 10 * time.Second, - }, - { - name: "sort_desc", - load: `load 30s - metric{label="value_1"} 20 - metric{label="value_2"} 30 - metric{label="value_3"} 10`, - query: "sort_desc(metric)", - start: time.Unix(0, 0), - end: time.Unix(3000, 0), - step: 10 * time.Second, - }, } disableOptimizerOpts := []bool{true, false} @@ -2488,24 +2465,6 @@ func TestInstantQuery(t *testing.T) { queryTime: time.Now(), sortByLabels: false, }, - { - name: "sort", - load: `load 30s - metric{label="value_1"} 20 - metric{label="value_2"} 30 - metric{label="value_3"} 10`, - query: "sort(metric)", - queryTime: defaultQueryTime, - }, - { - name: "sort_desc", - load: `load 30s - metric{label="value_1"} 20 - metric{label="value_2"} 30 - metric{label="value_3"} 10`, - query: "sort_desc(metric)", - queryTime: defaultQueryTime, - }, } disableOptimizerOpts := []bool{true, false} diff --git a/execution/function/functions.go b/execution/function/functions.go index 2ebeb04c..53c69999 100644 --- a/execution/function/functions.go +++ b/execution/function/functions.go @@ -7,9 +7,8 @@ import ( "fmt" "math" "time" - "sort" - - "github.com/efficientgo/core/errors" + + "github.com/efficientgo/core/errors" "github.com/prometheus/prometheus/model/histogram" "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/promql" @@ -27,7 +26,6 @@ type FunctionArgs struct { SelectRange int64 ScalarPoints []float64 Offset int64 - Args []interface{} } // FunctionCall represents functions as defined in https://prometheus.io/docs/prometheus/latest/querying/functions/ @@ -452,57 +450,6 @@ var Funcs = map[string]FunctionCall{ Point: promql.Point{}, } }, - "sort": func(f FunctionArgs) promql.Sample{ - input := f.Args[0].(*promql.Vector) - - samples := make(promql.Sample, len(input)) - for i, s := range input{ - samples[i] = s - } - - sort.Slice(samples, func(i, j int) bool{ - return samples[i].V < samples[j].V - }) - - // Convert sorted slice of samples back into vector. - result := make(promql.Vector, len(input)) - for i, s := range samples{ - result[i] = s - } - - // Return a sample with the sorted vector as its value - return promql.Sample{ - Metric: promql.Metric{}, - Point: promql.Point{ - T: f.StepTime, - V: result, - }, - } - }, - "sort_desc": func(f FunctionArgs) promql.Sample { - input := f.Args[0].(*promql.Vector) - - samples := make(promql.Sample, len(input)) - for i, s := range input{ - samples[i] = s - } - - sort.Slice(samples, func(i, j int) bool { - return samples[i].V > samples[j].V - }) - - result := make(promql.Vector, len(input)) - for i, s := range samples{ - result[i] = s - } - return promql.Sample{ - Metric: promql.Metric{}, - Point: promql.Point{ - T: f.StepTime, - V: result, - }, - } - }, } func NewFunctionCall(f *parser.Function) (FunctionCall, error) {