From fc9dc72028f0edd03fb7784e21758024d59ec41d Mon Sep 17 00:00:00 2001 From: Jeanette Tan Date: Thu, 20 Jun 2024 22:49:00 +0800 Subject: [PATCH] remove eval_with_nhcb Signed-off-by: Jeanette Tan --- promql/promqltest/README.md | 11 ---- promql/promqltest/test.go | 68 +++---------------- promql/promqltest/testdata/histograms.test | 76 +++++++++++----------- 3 files changed, 46 insertions(+), 109 deletions(-) diff --git a/promql/promqltest/README.md b/promql/promqltest/README.md index 05ead6a72c..af34354241 100644 --- a/promql/promqltest/README.md +++ b/promql/promqltest/README.md @@ -130,14 +130,3 @@ eval_fail instant at 1m ceil({__name__=~'testmetric1|testmetric2'}) eval_fail instant at 1m ceil({__name__=~'testmetric1|testmetric2'}) expected_fail_regexp (vector cannot contain metrics .*|something else went wrong) ``` - -### Native histograms with custom buckets (NHCB) - -For native histogram with custom buckets (NHCB) series that have been loaded with `load_with_nhcb`, you can use `eval_with_nhcb` instead on the queries of the classic histogram float bucket series to run additional queries on the -NHCB version. We use best effort heuristics to convert the query to its NHCB equivalent, and raise an error if it looks like the conversion was not effective. - -For example, `eval_with_nhcb instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le, job))` is shorthand for running these queries: -``` -eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le, job)) # Classic histogram -eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds[5m])) by (job)) # NHCB -``` diff --git a/promql/promqltest/test.go b/promql/promqltest/test.go index 4ce4b9bcbd..f3a773be8d 100644 --- a/promql/promqltest/test.go +++ b/promql/promqltest/test.go @@ -44,38 +44,10 @@ import ( ) var ( - patSpace = regexp.MustCompile("[\t ]+") - patLoad = regexp.MustCompile(`^load(?:_(with_nhcb))?\s+(.+?)$`) - patEvalInstant = regexp.MustCompile(`^eval(?:_(with_nhcb))?(?:_(fail|warn|ordered))?\s+instant\s+(?:at\s+(.+?))?\s+(.+)$`) - patEvalRange = regexp.MustCompile(`^eval(?:_(fail|warn))?\s+range\s+from\s+(.+)\s+to\s+(.+)\s+step\s+(.+?)\s+(.+)$`) - patWhitespace = regexp.MustCompile(`\s+`) - patBucket = regexp.MustCompile(`_bucket\b`) - patLE = regexp.MustCompile(`\ble\b`) - histogramBucketReplacements = []struct { - pattern *regexp.Regexp - repl string - }{ - { - pattern: regexp.MustCompile(`_bucket\b`), - repl: "", - }, - { - pattern: regexp.MustCompile(`\s+by\s+\(\s*le\s*\)`), - repl: "", - }, - { - pattern: regexp.MustCompile(`\(\s*le\s*,\s*`), - repl: "(", - }, - { - pattern: regexp.MustCompile(`,\s*le\s*,\s*`), - repl: ", ", - }, - { - pattern: regexp.MustCompile(`,\s*le\s*\)`), - repl: ")", - }, - } + patSpace = regexp.MustCompile("[\t ]+") + patLoad = regexp.MustCompile(`^load(?:_(with_nhcb))?\s+(.+?)$`) + patEvalInstant = regexp.MustCompile(`^eval(?:_(fail|warn|ordered))?\s+instant\s+(?:at\s+(.+?))?\s+(.+)$`) + patEvalRange = regexp.MustCompile(`^eval(?:_(fail|warn))?\s+range\s+from\s+(.+)\s+to\s+(.+)\s+step\s+(.+?)\s+(.+)$`) ) const ( @@ -251,19 +223,17 @@ func (t *test) parseEval(lines []string, i int) (int, *evalCmd, error) { rangeParts := patEvalRange.FindStringSubmatch(lines[i]) if instantParts == nil && rangeParts == nil { - return i, nil, raise(i, "invalid evaluation command. Must be either 'eval[_with_nhcb][_fail|_warn|_ordered] instant [at ] ' or 'eval[_fail|_warn] range from to step '") + return i, nil, raise(i, "invalid evaluation command. Must be either 'eval[_fail|_warn|_ordered] instant [at ] ' or 'eval[_fail|_warn] range from to step '") } isInstant := instantParts != nil - var withNHCB bool var mod string var expr string if isInstant { - withNHCB = instantParts[1] == "with_nhcb" - mod = instantParts[2] - expr = instantParts[4] + mod = instantParts[1] + expr = instantParts[3] } else { mod = rangeParts[1] expr = rangeParts[5] @@ -291,7 +261,7 @@ func (t *test) parseEval(lines []string, i int) (int, *evalCmd, error) { var cmd *evalCmd if isInstant { - at := instantParts[3] + at := instantParts[2] offset, err := model.ParseDuration(at) if err != nil { return i, nil, formatErr("invalid timestamp definition %q: %s", at, err) @@ -335,7 +305,6 @@ func (t *test) parseEval(lines []string, i int) (int, *evalCmd, error) { case "warn": cmd.warn = true } - cmd.withNHCB = withNHCB for j := 1; i+1 < len(lines); j++ { i++ @@ -673,7 +642,6 @@ type evalCmd struct { isRange bool // if false, instant query fail, warn, ordered bool - withNHCB bool expectedFailMessage string expectedFailRegexp *regexp.Regexp @@ -1066,26 +1034,6 @@ func (t *test) execInstantEval(cmd *evalCmd, engine promql.QueryEngine) error { if err := t.runInstantQuery(iq, cmd, engine); err != nil { return err } - if cmd.withNHCB { - if !strings.Contains(iq.expr, "_bucket") { - return fmt.Errorf("expected '_bucket' in the expression '%q'", iq.expr) - } - origExpr := iq.expr - for _, rep := range histogramBucketReplacements { - iq.expr = rep.pattern.ReplaceAllString(iq.expr, rep.repl) - } - switch { - case patWhitespace.ReplaceAllString(iq.expr, "") == patWhitespace.ReplaceAllString(origExpr, ""): - return fmt.Errorf("query rewrite of '%q' had no effect", iq.expr) - case patBucket.MatchString(iq.expr): - return fmt.Errorf("rewritten query '%q' still has '_bucket'", iq.expr) - case patLE.MatchString(iq.expr): - return fmt.Errorf("rewritten query '%q' still has 'le'", iq.expr) - } - if err := t.runInstantQuery(iq, cmd, engine); err != nil { - return err - } - } } return nil } diff --git a/promql/promqltest/testdata/histograms.test b/promql/promqltest/testdata/histograms.test index 9abdaa7f64..e1fb1d85ac 100644 --- a/promql/promqltest/testdata/histograms.test +++ b/promql/promqltest/testdata/histograms.test @@ -105,149 +105,149 @@ eval instant at 50m histogram_fraction(0, 0.2, rate(testhistogram3[5m])) # Test histogram_quantile. -eval_with_nhcb instant at 50m histogram_quantile(0, testhistogram3_bucket) +eval instant at 50m histogram_quantile(0, testhistogram3_bucket) {start="positive"} 0 {start="negative"} -0.25 -eval_with_nhcb instant at 50m histogram_quantile(0.25, testhistogram3_bucket) +eval instant at 50m histogram_quantile(0.25, testhistogram3_bucket) {start="positive"} 0.055 {start="negative"} -0.225 -eval_with_nhcb instant at 50m histogram_quantile(0.5, testhistogram3_bucket) +eval instant at 50m histogram_quantile(0.5, testhistogram3_bucket) {start="positive"} 0.125 {start="negative"} -0.2 -eval_with_nhcb instant at 50m histogram_quantile(0.75, testhistogram3_bucket) +eval instant at 50m histogram_quantile(0.75, testhistogram3_bucket) {start="positive"} 0.45 {start="negative"} -0.15 -eval_with_nhcb instant at 50m histogram_quantile(1, testhistogram3_bucket) +eval instant at 50m histogram_quantile(1, testhistogram3_bucket) {start="positive"} 1 {start="negative"} -0.1 # Quantile too low. -eval_with_nhcb_warn instant at 50m histogram_quantile(-0.1, testhistogram_bucket) +eval_warn instant at 50m histogram_quantile(-0.1, testhistogram_bucket) {start="positive"} -Inf {start="negative"} -Inf # Quantile too high. -eval_with_nhcb_warn instant at 50m histogram_quantile(1.01, testhistogram_bucket) +eval_warn instant at 50m histogram_quantile(1.01, testhistogram_bucket) {start="positive"} +Inf {start="negative"} +Inf # Quantile invalid. -eval_with_nhcb_warn instant at 50m histogram_quantile(NaN, testhistogram_bucket) +eval_warn instant at 50m histogram_quantile(NaN, testhistogram_bucket) {start="positive"} NaN {start="negative"} NaN # Quantile value in lowest bucket. -eval_with_nhcb instant at 50m histogram_quantile(0, testhistogram_bucket) +eval instant at 50m histogram_quantile(0, testhistogram_bucket) {start="positive"} 0 {start="negative"} -0.2 # Quantile value in highest bucket. -eval_with_nhcb instant at 50m histogram_quantile(1, testhistogram_bucket) +eval instant at 50m histogram_quantile(1, testhistogram_bucket) {start="positive"} 1 {start="negative"} 0.3 # Finally some useful quantiles. -eval_with_nhcb instant at 50m histogram_quantile(0.2, testhistogram_bucket) +eval instant at 50m histogram_quantile(0.2, testhistogram_bucket) {start="positive"} 0.048 {start="negative"} -0.2 -eval_with_nhcb instant at 50m histogram_quantile(0.5, testhistogram_bucket) +eval instant at 50m histogram_quantile(0.5, testhistogram_bucket) {start="positive"} 0.15 {start="negative"} -0.15 -eval_with_nhcb instant at 50m histogram_quantile(0.8, testhistogram_bucket) +eval instant at 50m histogram_quantile(0.8, testhistogram_bucket) {start="positive"} 0.72 {start="negative"} 0.3 # More realistic with rates. -eval_with_nhcb instant at 50m histogram_quantile(0.2, rate(testhistogram_bucket[5m])) +eval instant at 50m histogram_quantile(0.2, rate(testhistogram_bucket[5m])) {start="positive"} 0.048 {start="negative"} -0.2 -eval_with_nhcb instant at 50m histogram_quantile(0.5, rate(testhistogram_bucket[5m])) +eval instant at 50m histogram_quantile(0.5, rate(testhistogram_bucket[5m])) {start="positive"} 0.15 {start="negative"} -0.15 -eval_with_nhcb instant at 50m histogram_quantile(0.8, rate(testhistogram_bucket[5m])) +eval instant at 50m histogram_quantile(0.8, rate(testhistogram_bucket[5m])) {start="positive"} 0.72 {start="negative"} 0.3 # Want results exactly in the middle of the bucket. -eval_with_nhcb instant at 7m histogram_quantile(1./6., testhistogram2_bucket) +eval instant at 7m histogram_quantile(1./6., testhistogram2_bucket) {} 1 -eval_with_nhcb instant at 7m histogram_quantile(0.5, testhistogram2_bucket) +eval instant at 7m histogram_quantile(0.5, testhistogram2_bucket) {} 3 -eval_with_nhcb instant at 7m histogram_quantile(5./6., testhistogram2_bucket) +eval instant at 7m histogram_quantile(5./6., testhistogram2_bucket) {} 5 -eval_with_nhcb instant at 47m histogram_quantile(1./6., rate(testhistogram2_bucket[15m])) +eval instant at 47m histogram_quantile(1./6., rate(testhistogram2_bucket[15m])) {} 1 -eval_with_nhcb instant at 47m histogram_quantile(0.5, rate(testhistogram2_bucket[15m])) +eval instant at 47m histogram_quantile(0.5, rate(testhistogram2_bucket[15m])) {} 3 -eval_with_nhcb instant at 47m histogram_quantile(5./6., rate(testhistogram2_bucket[15m])) +eval instant at 47m histogram_quantile(5./6., rate(testhistogram2_bucket[15m])) {} 5 # Aggregated histogram: Everything in one. -eval_with_nhcb instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le)) +eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le)) {} 0.075 -eval_with_nhcb instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le)) +eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le)) {} 0.1277777777777778 # Aggregated histogram: Everything in one. Now with avg, which does not change anything. -eval_with_nhcb instant at 50m histogram_quantile(0.3, avg(rate(request_duration_seconds_bucket[5m])) by (le)) +eval instant at 50m histogram_quantile(0.3, avg(rate(request_duration_seconds_bucket[5m])) by (le)) {} 0.075 -eval_with_nhcb instant at 50m histogram_quantile(0.5, avg(rate(request_duration_seconds_bucket[5m])) by (le)) +eval instant at 50m histogram_quantile(0.5, avg(rate(request_duration_seconds_bucket[5m])) by (le)) {} 0.12777777777777778 # Aggregated histogram: By instance. -eval_with_nhcb instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le, instance)) +eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le, instance)) {instance="ins1"} 0.075 {instance="ins2"} 0.075 -eval_with_nhcb instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le, instance)) +eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le, instance)) {instance="ins1"} 0.1333333333 {instance="ins2"} 0.125 # Aggregated histogram: By job. -eval_with_nhcb instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le, job)) +eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le, job)) {job="job1"} 0.1 {job="job2"} 0.0642857142857143 -eval_with_nhcb instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le, job)) +eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le, job)) {job="job1"} 0.14 {job="job2"} 0.1125 # Aggregated histogram: By job and instance. -eval_with_nhcb instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le, job, instance)) +eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le, job, instance)) {instance="ins1", job="job1"} 0.11 {instance="ins2", job="job1"} 0.09 {instance="ins1", job="job2"} 0.06 {instance="ins2", job="job2"} 0.0675 -eval_with_nhcb instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le, job, instance)) +eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le, job, instance)) {instance="ins1", job="job1"} 0.15 {instance="ins2", job="job1"} 0.1333333333333333 {instance="ins1", job="job2"} 0.1 {instance="ins2", job="job2"} 0.1166666666666667 # The unaggregated histogram for comparison. Same result as the previous one. -eval_with_nhcb instant at 50m histogram_quantile(0.3, rate(request_duration_seconds_bucket[5m])) +eval instant at 50m histogram_quantile(0.3, rate(request_duration_seconds_bucket[5m])) {instance="ins1", job="job1"} 0.11 {instance="ins2", job="job1"} 0.09 {instance="ins1", job="job2"} 0.06 {instance="ins2", job="job2"} 0.0675 -eval_with_nhcb instant at 50m histogram_quantile(0.5, rate(request_duration_seconds_bucket[5m])) +eval instant at 50m histogram_quantile(0.5, rate(request_duration_seconds_bucket[5m])) {instance="ins1", job="job1"} 0.15 {instance="ins2", job="job1"} 0.13333333333333333 {instance="ins1", job="job2"} 0.1 @@ -287,11 +287,11 @@ eval instant at 50m histogram_quantile(0.5, rate(mixed[5m])) {instance="ins1", job="job1"} 0.2 {instance="ins2", job="job1"} NaN -eval_with_nhcb instant at 50m histogram_quantile(0.75, rate(mixed_bucket[5m])) +eval instant at 50m histogram_quantile(0.75, rate(mixed_bucket[5m])) {instance="ins1", job="job1"} 0.2 {instance="ins2", job="job1"} NaN -eval_with_nhcb instant at 50m histogram_quantile(1, rate(mixed_bucket[5m])) +eval instant at 50m histogram_quantile(1, rate(mixed_bucket[5m])) {instance="ins1", job="job1"} 0.2 {instance="ins2", job="job1"} NaN @@ -300,7 +300,7 @@ load_with_nhcb 5m empty_bucket{le="0.2", job="job1", instance="ins1"} 0x10 empty_bucket{le="+Inf", job="job1", instance="ins1"} 0x10 -eval_with_nhcb instant at 50m histogram_quantile(0.2, rate(empty_bucket[5m])) +eval instant at 50m histogram_quantile(0.2, rate(empty_bucket[5m])) {instance="ins1", job="job1"} NaN # Load a duplicate histogram with a different name to test failure scenario on multiple histograms with the same label set @@ -310,4 +310,4 @@ load_with_nhcb 5m request_duration_seconds2_bucket{job="job1", instance="ins1", le="0.2"} 0+3x10 request_duration_seconds2_bucket{job="job1", instance="ins1", le="+Inf"} 0+4x10 -eval_with_nhcb_fail instant at 50m histogram_quantile(0.99, {__name__=~"request_duration_seconds\\d*_bucket$"}) +eval_fail instant at 50m histogram_quantile(0.99, {__name__=~"request_duration_seconds\\d*_bucket$"})