diff --git a/promql/lex.go b/promql/lex.go index 90f82f3736..5d390ca11e 100644 --- a/promql/lex.go +++ b/promql/lex.go @@ -163,11 +163,6 @@ const ( itemGroupLeft itemGroupRight itemBool - // Old alerting syntax - itemWith - itemSummary - itemRunbook - itemDescription keywordsEnd ) @@ -200,12 +195,6 @@ var key = map[string]itemType{ "group_left": itemGroupLeft, "group_right": itemGroupRight, "bool": itemBool, - - // Old alerting syntax. - "with": itemWith, - "summary": itemSummary, - "runbook": itemRunbook, - "description": itemDescription, } // These are the default string representations for common items. It does not diff --git a/promql/lex_test.go b/promql/lex_test.go index 9ff8e44201..d516c3d935 100644 --- a/promql/lex_test.go +++ b/promql/lex_test.go @@ -263,18 +263,6 @@ var tests = []struct { }, { input: "annotations", expected: []item{{itemAnnotations, 0, "annotations"}}, - }, { - input: "description", - expected: []item{{itemDescription, 0, "description"}}, - }, { - input: "summary", - expected: []item{{itemSummary, 0, "summary"}}, - }, { - input: "runbook", - expected: []item{{itemRunbook, 0, "runbook"}}, - }, { - input: "with", - expected: []item{{itemWith, 0, "with"}}, }, { input: "offset", expected: []item{{itemOffset, 0, "offset"}}, diff --git a/promql/parse.go b/promql/parse.go index 758d879229..c91df6fb36 100644 --- a/promql/parse.go +++ b/promql/parse.go @@ -384,57 +384,17 @@ func (p *parser) alertStmt() *AlertStmt { } } - // Accepting WITH instead of LABELS is temporary compatibility - // with the old alerting syntax. var ( - hasLabels bool - oldSyntax bool labels = model.LabelSet{} annotations = model.LabelSet{} ) - if t := p.peek().typ; t == itemLabels { + if p.peek().typ == itemLabels { p.expect(itemLabels, ctx) labels = p.labelSet() - hasLabels = true - } else if t == itemWith { - p.expect(itemWith, ctx) - labels = p.labelSet() - oldSyntax = true } - - // Only allow old annotation syntax if new label syntax isn't used. - if !hasLabels { - Loop: - for { - switch p.next().typ { - case itemSummary: - annotations["summary"] = model.LabelValue(p.unquoteString(p.expect(itemString, ctx).val)) - - case itemDescription: - annotations["description"] = model.LabelValue(p.unquoteString(p.expect(itemString, ctx).val)) - - case itemRunbook: - annotations["runbook"] = model.LabelValue(p.unquoteString(p.expect(itemString, ctx).val)) - - default: - p.backup() - break Loop - } - } - if len(annotations) > 0 { - oldSyntax = true - } - } - - // Only allow new annotation syntax if WITH or old annotation - // syntax weren't used. - if !oldSyntax { - if p.peek().typ == itemAnnotations { - p.expect(itemAnnotations, ctx) - annotations = p.labelSet() - } - } else { - log.Warnf("Alerting rule with old syntax found. Support for this syntax will be removed with 0.18. Please update to the new syntax.") + if p.peek().typ == itemAnnotations { + p.expect(itemAnnotations, ctx) + annotations = p.labelSet() } return &AlertStmt{ diff --git a/promql/parse_test.go b/promql/parse_test.go index 28a12a6777..b438d2ec87 100644 --- a/promql/parse_test.go +++ b/promql/parse_test.go @@ -1311,32 +1311,6 @@ var testStatement = []struct { Labels: model.LabelSet{"x": "", "a": "z"}, }, }, - }, { - input: `ALERT SomeName IF some_metric > 1 - WITH {} - SUMMARY "Global request rate low" - DESCRIPTION "The global request rate is low" - `, - expected: Statements{ - &AlertStmt{ - Name: "SomeName", - Expr: &BinaryExpr{ - Op: itemGTR, - LHS: &VectorSelector{ - Name: "some_metric", - LabelMatchers: metric.LabelMatchers{ - {Type: metric.Equal, Name: model.MetricNameLabel, Value: "some_metric"}, - }, - }, - RHS: &NumberLiteral{1}, - }, - Labels: model.LabelSet{}, - Annotations: model.LabelSet{ - "summary": "Global request rate low", - "description": "The global request rate is low", - }, - }, - }, }, { input: `ALERT SomeName IF some_metric > 1 LABELS {} diff --git a/promql/testdata/comparison.test b/promql/testdata/comparison.test deleted file mode 100644 index 012d5891ab..0000000000 --- a/promql/testdata/comparison.test +++ /dev/null @@ -1,47 +0,0 @@ -load 5m - http_requests{job="api-server", instance="0", group="production"} 0+10x10 - http_requests{job="api-server", instance="1", group="production"} 0+20x10 - http_requests{job="api-server", instance="0", group="canary"} 0+30x10 - http_requests{job="api-server", instance="1", group="canary"} 0+40x10 - http_requests{job="app-server", instance="0", group="production"} 0+50x10 - http_requests{job="app-server", instance="1", group="production"} 0+60x10 - http_requests{job="app-server", instance="0", group="canary"} 0+70x10 - http_requests{job="app-server", instance="1", group="canary"} 0+80x10 - -eval instant at 50m SUM(http_requests) BY (job) > 1000 - {job="app-server"} 2600 - - -eval instant at 50m 1000 < SUM(http_requests) BY (job) - {job="app-server"} 1000 - - -eval instant at 50m SUM(http_requests) BY (job) <= 1000 - {job="api-server"} 1000 - - -eval instant at 50m SUM(http_requests) BY (job) != 1000 - {job="app-server"} 2600 - - -eval instant at 50m SUM(http_requests) BY (job) == 1000 - {job="api-server"} 1000 - -eval instant at 50m SUM(http_requests) BY (job) == bool 1000 - {job="api-server"} 1 - {job="app-server"} 0 - -eval instant at 50m SUM(http_requests) BY (job) == bool SUM(http_requests) BY (job) - {job="api-server"} 1 - {job="app-server"} 1 - -eval instant at 50m SUM(http_requests) BY (job) != bool SUM(http_requests) BY (job) - {job="api-server"} 0 - {job="app-server"} 0 - - -eval instant at 50m 0 == bool 1 - 0 - -eval instant at 50m 1 == bool 1 - 1 diff --git a/promql/testdata/legacy.test b/promql/testdata/legacy.test index c4c8111075..3b8088b677 100644 --- a/promql/testdata/legacy.test +++ b/promql/testdata/legacy.test @@ -86,62 +86,6 @@ eval instant at 50m MAX(http_requests) BY (job) {job="app-server"} 800 -eval instant at 50m SUM(http_requests) BY (job) - COUNT(http_requests) BY (job) - {job="api-server"} 996 - {job="app-server"} 2596 - - -eval instant at 50m 2 - SUM(http_requests) BY (job) - {job="api-server"} -998 - {job="app-server"} -2598 - - -eval instant at 50m 1000 / SUM(http_requests) BY (job) - {job="api-server"} 1 - {job="app-server"} 0.38461538461538464 - - -eval instant at 50m SUM(http_requests) BY (job) - 2 - {job="api-server"} 998 - {job="app-server"} 2598 - - -eval instant at 50m SUM(http_requests) BY (job) % 3 - {job="api-server"} 1 - {job="app-server"} 2 - - -eval instant at 50m SUM(http_requests) BY (job) / 0 - {job="api-server"} +Inf - {job="app-server"} +Inf - - -eval instant at 50m SUM(http_requests) BY (job) + SUM(http_requests) BY (job) - {job="api-server"} 2000 - {job="app-server"} 5200 - - -eval instant at 50m http_requests{job="api-server", group="canary"} - http_requests{group="canary", instance="0", job="api-server"} 300 - http_requests{group="canary", instance="1", job="api-server"} 400 - - -eval instant at 50m http_requests{job="api-server", group="canary"} + rate(http_requests{job="api-server"}[5m]) * 5 * 60 - {group="canary", instance="0", job="api-server"} 330 - {group="canary", instance="1", job="api-server"} 440 - - -eval instant at 50m rate(http_requests[25m]) * 25 * 60 - {group="canary", instance="0", job="api-server"} 150 - {group="canary", instance="0", job="app-server"} 350 - {group="canary", instance="1", job="api-server"} 200 - {group="canary", instance="1", job="app-server"} 400 - {group="production", instance="0", job="api-server"} 50 - {group="production", instance="0", job="app-server"} 249.99999999999997 - {group="production", instance="1", job="api-server"} 100 - {group="production", instance="1", job="app-server"} 300 - - # Single-letter label names and values. eval instant at 50m x{y="testvalue"} x{y="testvalue"} 100 @@ -337,110 +281,6 @@ eval instant at 50m {job=~".+-server", job!~"api-.+"} http_requests{group="production", instance="0", job="app-server"} 500 http_requests{group="production", instance="1", job="app-server"} 600 -eval instant at 50m http_requests{group="canary"} and http_requests{instance="0"} - http_requests{group="canary", instance="0", job="api-server"} 300 - http_requests{group="canary", instance="0", job="app-server"} 700 - -eval instant at 50m (http_requests{group="canary"} + 1) and http_requests{instance="0"} - {group="canary", instance="0", job="api-server"} 301 - {group="canary", instance="0", job="app-server"} 701 - -eval instant at 50m (http_requests{group="canary"} + 1) and on(instance, job) http_requests{instance="0", group="production"} - {group="canary", instance="0", job="api-server"} 301 - {group="canary", instance="0", job="app-server"} 701 - -eval instant at 50m (http_requests{group="canary"} + 1) and on(instance) http_requests{instance="0", group="production"} - {group="canary", instance="0", job="api-server"} 301 - {group="canary", instance="0", job="app-server"} 701 - -eval instant at 50m http_requests{group="canary"} or http_requests{group="production"} - http_requests{group="canary", instance="0", job="api-server"} 300 - http_requests{group="canary", instance="0", job="app-server"} 700 - http_requests{group="canary", instance="1", job="api-server"} 400 - http_requests{group="canary", instance="1", job="app-server"} 800 - http_requests{group="production", instance="0", job="api-server"} 100 - http_requests{group="production", instance="0", job="app-server"} 500 - http_requests{group="production", instance="1", job="api-server"} 200 - http_requests{group="production", instance="1", job="app-server"} 600 - -# On overlap the rhs samples must be dropped. -eval instant at 50m (http_requests{group="canary"} + 1) or http_requests{instance="1"} - {group="canary", instance="0", job="api-server"} 301 - {group="canary", instance="0", job="app-server"} 701 - {group="canary", instance="1", job="api-server"} 401 - {group="canary", instance="1", job="app-server"} 801 - http_requests{group="production", instance="1", job="api-server"} 200 - http_requests{group="production", instance="1", job="app-server"} 600 - -# Matching only on instance excludes everything that has instance=0/1 but includes -# entries without the instance label. -eval instant at 50m (http_requests{group="canary"} + 1) or on(instance) (http_requests or cpu_count or vector_matching_a) - {group="canary", instance="0", job="api-server"} 301 - {group="canary", instance="0", job="app-server"} 701 - {group="canary", instance="1", job="api-server"} 401 - {group="canary", instance="1", job="app-server"} 801 - vector_matching_a{l="x"} 10 - vector_matching_a{l="y"} 20 - -eval instant at 50m http_requests{group="canary"} / on(instance,job) http_requests{group="production"} - {instance="0", job="api-server"} 3 - {instance="0", job="app-server"} 1.4 - {instance="1", job="api-server"} 2 - {instance="1", job="app-server"} 1.3333333333333333 - -# Include labels must guarantee uniquely identifiable time series. -eval_fail instant at 50m http_requests{group="production"} / on(instance) group_left(group) cpu_count{type="smp"} - -# Many-to-many matching is not allowed. -eval_fail instant at 50m http_requests{group="production"} / on(instance) group_left(job,type) cpu_count - -# Many-to-one matching must be explicit. -eval_fail instant at 50m http_requests{group="production"} / on(instance) cpu_count{type="smp"} - -eval instant at 50m http_requests{group="production"} / on(instance) group_left(job) cpu_count{type="smp"} - {instance="1", job="api-server"} 1 - {instance="0", job="app-server"} 5 - {instance="1", job="app-server"} 3 - {instance="0", job="api-server"} 1 - -# Ensure sidedness of grouping preserves operand sides. -eval instant at 50m cpu_count{type="smp"} / on(instance) group_right(job) http_requests{group="production"} - {instance="1", job="app-server"} 0.3333333333333333 - {instance="0", job="app-server"} 0.2 - {instance="1", job="api-server"} 1 - {instance="0", job="api-server"} 1 - -# Include labels from both sides. -eval instant at 50m http_requests{group="production"} / on(instance) group_left(job) cpu_count{type="smp"} - {instance="1", job="api-server"} 1 - {instance="0", job="app-server"} 5 - {instance="1", job="app-server"} 3 - {instance="0", job="api-server"} 1 - -eval instant at 50m http_requests{group="production"} < on(instance,job) http_requests{group="canary"} - {instance="1", job="app-server"} 600 - {instance="0", job="app-server"} 500 - {instance="1", job="api-server"} 200 - {instance="0", job="api-server"} 100 - - -eval instant at 50m http_requests{group="production"} > on(instance,job) http_requests{group="canary"} - # no output - -eval instant at 50m http_requests{group="production"} == on(instance,job) http_requests{group="canary"} - # no output - -eval instant at 50m http_requests > on(instance) group_left(group,job) cpu_count{type="smp"} - {group="canary", instance="0", job="app-server"} 700 - {group="canary", instance="1", job="app-server"} 800 - {group="canary", instance="0", job="api-server"} 300 - {group="canary", instance="1", job="api-server"} 400 - {group="production", instance="0", job="app-server"} 500 - {group="production", instance="1", job="app-server"} 600 - -eval instant at 50m {l="x"} + on(__name__) {l="y"} - vector_matching_a 30 - eval instant at 50m absent(nonexistent) {} 1 diff --git a/promql/testdata/operators.test b/promql/testdata/operators.test new file mode 100644 index 0000000000..ccb019c597 --- /dev/null +++ b/promql/testdata/operators.test @@ -0,0 +1,162 @@ +load 5m + http_requests{job="api-server", instance="0", group="production"} 0+10x10 + http_requests{job="api-server", instance="1", group="production"} 0+20x10 + http_requests{job="api-server", instance="0", group="canary"} 0+30x10 + http_requests{job="api-server", instance="1", group="canary"} 0+40x10 + http_requests{job="app-server", instance="0", group="production"} 0+50x10 + http_requests{job="app-server", instance="1", group="production"} 0+60x10 + http_requests{job="app-server", instance="0", group="canary"} 0+70x10 + http_requests{job="app-server", instance="1", group="canary"} 0+80x10 + + +load 5m + vector_matching_a{l="x"} 0+1x100 + vector_matching_a{l="y"} 0+2x50 + vector_matching_b{l="x"} 0+4x25 + + +eval instant at 50m SUM(http_requests) BY (job) - COUNT(http_requests) BY (job) + {job="api-server"} 996 + {job="app-server"} 2596 + +eval instant at 50m 2 - SUM(http_requests) BY (job) + {job="api-server"} -998 + {job="app-server"} -2598 + +eval instant at 50m 1000 / SUM(http_requests) BY (job) + {job="api-server"} 1 + {job="app-server"} 0.38461538461538464 + +eval instant at 50m SUM(http_requests) BY (job) - 2 + {job="api-server"} 998 + {job="app-server"} 2598 + +eval instant at 50m SUM(http_requests) BY (job) % 3 + {job="api-server"} 1 + {job="app-server"} 2 + +eval instant at 50m SUM(http_requests) BY (job) / 0 + {job="api-server"} +Inf + {job="app-server"} +Inf + +eval instant at 50m SUM(http_requests) BY (job) + SUM(http_requests) BY (job) + {job="api-server"} 2000 + {job="app-server"} 5200 + + +eval instant at 50m http_requests{job="api-server", group="canary"} + http_requests{group="canary", instance="0", job="api-server"} 300 + http_requests{group="canary", instance="1", job="api-server"} 400 + +eval instant at 50m http_requests{job="api-server", group="canary"} + rate(http_requests{job="api-server"}[5m]) * 5 * 60 + {group="canary", instance="0", job="api-server"} 330 + {group="canary", instance="1", job="api-server"} 440 + +eval instant at 50m rate(http_requests[25m]) * 25 * 60 + {group="canary", instance="0", job="api-server"} 150 + {group="canary", instance="0", job="app-server"} 350 + {group="canary", instance="1", job="api-server"} 200 + {group="canary", instance="1", job="app-server"} 400 + {group="production", instance="0", job="api-server"} 50 + {group="production", instance="0", job="app-server"} 249.99999999999997 + {group="production", instance="1", job="api-server"} 100 + {group="production", instance="1", job="app-server"} 300 + + +eval instant at 50m http_requests{group="canary"} and http_requests{instance="0"} + http_requests{group="canary", instance="0", job="api-server"} 300 + http_requests{group="canary", instance="0", job="app-server"} 700 + +eval instant at 50m (http_requests{group="canary"} + 1) and http_requests{instance="0"} + {group="canary", instance="0", job="api-server"} 301 + {group="canary", instance="0", job="app-server"} 701 + +eval instant at 50m (http_requests{group="canary"} + 1) and on(instance, job) http_requests{instance="0", group="production"} + {group="canary", instance="0", job="api-server"} 301 + {group="canary", instance="0", job="app-server"} 701 + +eval instant at 50m (http_requests{group="canary"} + 1) and on(instance) http_requests{instance="0", group="production"} + {group="canary", instance="0", job="api-server"} 301 + {group="canary", instance="0", job="app-server"} 701 + +eval instant at 50m http_requests{group="canary"} or http_requests{group="production"} + http_requests{group="canary", instance="0", job="api-server"} 300 + http_requests{group="canary", instance="0", job="app-server"} 700 + http_requests{group="canary", instance="1", job="api-server"} 400 + http_requests{group="canary", instance="1", job="app-server"} 800 + http_requests{group="production", instance="0", job="api-server"} 100 + http_requests{group="production", instance="0", job="app-server"} 500 + http_requests{group="production", instance="1", job="api-server"} 200 + http_requests{group="production", instance="1", job="app-server"} 600 + +# On overlap the rhs samples must be dropped. +eval instant at 50m (http_requests{group="canary"} + 1) or http_requests{instance="1"} + {group="canary", instance="0", job="api-server"} 301 + {group="canary", instance="0", job="app-server"} 701 + {group="canary", instance="1", job="api-server"} 401 + {group="canary", instance="1", job="app-server"} 801 + http_requests{group="production", instance="1", job="api-server"} 200 + http_requests{group="production", instance="1", job="app-server"} 600 + + +# Matching only on instance excludes everything that has instance=0/1 but includes +# entries without the instance label. +eval instant at 50m (http_requests{group="canary"} + 1) or on(instance) (http_requests or cpu_count or vector_matching_a) + {group="canary", instance="0", job="api-server"} 301 + {group="canary", instance="0", job="app-server"} 701 + {group="canary", instance="1", job="api-server"} 401 + {group="canary", instance="1", job="app-server"} 801 + vector_matching_a{l="x"} 10 + vector_matching_a{l="y"} 20 + +eval instant at 50m http_requests{group="canary"} / on(instance,job) http_requests{group="production"} + {instance="0", job="api-server"} 3 + {instance="0", job="app-server"} 1.4 + {instance="1", job="api-server"} 2 + {instance="1", job="app-server"} 1.3333333333333333 + +# https://github.com/prometheus/prometheus/issues/1489 +eval instant at 50m http_requests AND ON (dummy) vector(1) + http_requests{group="canary", instance="0", job="api-server"} 300 + http_requests{group="canary", instance="0", job="app-server"} 700 + http_requests{group="canary", instance="1", job="api-server"} 400 + http_requests{group="canary", instance="1", job="app-server"} 800 + http_requests{group="production", instance="0", job="api-server"} 100 + http_requests{group="production", instance="0", job="app-server"} 500 + http_requests{group="production", instance="1", job="api-server"} 200 + http_requests{group="production", instance="1", job="app-server"} 600 + + +# Comparisons. +eval instant at 50m SUM(http_requests) BY (job) > 1000 + {job="app-server"} 2600 + +eval instant at 50m 1000 < SUM(http_requests) BY (job) + {job="app-server"} 1000 + +eval instant at 50m SUM(http_requests) BY (job) <= 1000 + {job="api-server"} 1000 + +eval instant at 50m SUM(http_requests) BY (job) != 1000 + {job="app-server"} 2600 + +eval instant at 50m SUM(http_requests) BY (job) == 1000 + {job="api-server"} 1000 + +eval instant at 50m SUM(http_requests) BY (job) == bool 1000 + {job="api-server"} 1 + {job="app-server"} 0 + +eval instant at 50m SUM(http_requests) BY (job) == bool SUM(http_requests) BY (job) + {job="api-server"} 1 + {job="app-server"} 1 + +eval instant at 50m SUM(http_requests) BY (job) != bool SUM(http_requests) BY (job) + {job="api-server"} 0 + {job="app-server"} 0 + +eval instant at 50m 0 == bool 1 + 0 + +eval instant at 50m 1 == bool 1 + 1 diff --git a/storage/remote/graphite/client.go b/storage/remote/graphite/client.go index 61a1413a70..0e7ee28afc 100644 --- a/storage/remote/graphite/client.go +++ b/storage/remote/graphite/client.go @@ -56,7 +56,7 @@ func pathFromMetric(m model.Metric, prefix string) string { } sort.Sort(labels) - // For each label, in order, add ".