diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index e39207d3..3bfc4361 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -48,6 +48,7 @@ jobs: if: startsWith(github.ref, 'refs/tags/') uses: goreleaser/goreleaser-action@v5 with: + version: v1.21.2 args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/cmd/pint/lint.go b/cmd/pint/lint.go index a828e3d9..94691980 100644 --- a/cmd/pint/lint.go +++ b/cmd/pint/lint.go @@ -148,7 +148,7 @@ func verifyOwners(entries []discovery.Entry, allowedOwners []*regexp.Regexp) (re Problem: checks.Problem{ Lines: entry.Rule.Lines(), Reporter: discovery.RuleOwnerComment, - Text: fmt.Sprintf(`%s comments are required in all files, please add a "# pint %s $owner" somewhere in this file and/or "# pint %s $owner" on top of each rule`, + Text: fmt.Sprintf("`%s` comments are required in all files, please add a `# pint %s $owner` somewhere in this file and/or `# pint %s $owner` on top of each rule.", discovery.RuleOwnerComment, discovery.FileOwnerComment, discovery.RuleOwnerComment), Severity: checks.Bug, }, @@ -168,7 +168,7 @@ func verifyOwners(entries []discovery.Entry, allowedOwners []*regexp.Regexp) (re Problem: checks.Problem{ Lines: entry.Rule.Lines(), Reporter: discovery.RuleOwnerComment, - Text: fmt.Sprintf("this rule is set as owned by %q but %q doesn't match any of the allowed owner values", entry.Owner, entry.Owner), + Text: fmt.Sprintf("This rule is set as owned by `%s` but `%s` doesn't match any of the allowed owner values.", entry.Owner, entry.Owner), Severity: checks.Bug, }, }) diff --git a/cmd/pint/scan.go b/cmd/pint/scan.go index cbeecf41..f7bb6ffc 100644 --- a/cmd/pint/scan.go +++ b/cmd/pint/scan.go @@ -3,6 +3,7 @@ package main import ( "context" "errors" + "fmt" "log/slog" "regexp" "strconv" @@ -183,7 +184,7 @@ func scanWorker(ctx context.Context, jobs <-chan scanJob, results chan<- reporte Problem: checks.Problem{ Lines: job.entry.ModifiedLines, Reporter: ignoreFileReporter, - Text: "This file was excluded from pint checks", + Text: "This file was excluded from pint checks.", Severity: checks.Information, }, Owner: job.entry.Owner, @@ -197,7 +198,11 @@ func scanWorker(ctx context.Context, jobs <-chan scanJob, results chan<- reporte Problem: checks.Problem{ Lines: []int{line}, Reporter: yamlParseReporter, - Text: e, + Text: fmt.Sprintf("YAML parser returned an error when reading this file: `%s`.", e), + Details: `pint cannot read this file because YAML parser returned an error. +This usually means that you have an indention error or the file doesn't have the YAML structure required by Prometheus for [recording](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/) and [alerting](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) rules. +If this file is a template that will be rendered into valid YAML then you can instruct pint to ignore some lines using comments, see [pint docs](https://cloudflare.github.io/pint/ignoring.html). +`, Severity: checks.Fatal, }, Owner: job.entry.Owner, @@ -212,7 +217,9 @@ func scanWorker(ctx context.Context, jobs <-chan scanJob, results chan<- reporte Fragment: job.entry.Rule.Error.Fragment, Lines: []int{job.entry.Rule.Error.Line}, Reporter: yamlParseReporter, - Text: job.entry.Rule.Error.Err.Error(), + Text: fmt.Sprintf("This rule is not a valid Prometheus rule: `%s`.", job.entry.Rule.Error.Err.Error()), + Details: `This Prometheus rule is not valid. +This usually means that it's missing some required fields.`, Severity: checks.Fatal, }, Owner: job.entry.Owner, diff --git a/cmd/pint/tests/0001_match_path.txt b/cmd/pint/tests/0001_match_path.txt index 0f979abd..92deeb65 100644 --- a/cmd/pint/tests/0001_match_path.txt +++ b/cmd/pint/tests/0001_match_path.txt @@ -5,7 +5,7 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/0002.yml:2 Bug: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0002.yml:2 Bug: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 2 | expr: sum(foo) without(job) level=INFO msg="Problems found" Bug=1 diff --git a/cmd/pint/tests/0003_lint_workdir.txt b/cmd/pint/tests/0003_lint_workdir.txt index bdc8200a..c063db31 100644 --- a/cmd/pint/tests/0003_lint_workdir.txt +++ b/cmd/pint/tests/0003_lint_workdir.txt @@ -6,58 +6,58 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/0001.yml:2 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0001.yml:2 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 2 | expr: sum(rate(fl_cf_html_bytes_in[10m])) WITHOUT (colo_id, instance, node_type, region, node_status, job, colo_name) -rules/0001.yml:6 Warning: instance label should be removed when aggregating "^colo(?:_.+)?:.+$" rules, use without(instance, ...) (promql/aggregate) +rules/0001.yml:6 Warning: `instance` label should be removed when aggregating `^colo(?:_.+)?:.+$` rules, use `without(instance, ...)`. (promql/aggregate) 6 | expr: sum(irate(foo[3m])) WITHOUT (colo_id) -rules/0002.yaml:2 Bug: unnecessary regexp match on static string job=~"foo", use job="foo" instead (promql/regexp) +rules/0002.yaml:2 Bug: Unnecessary regexp match on static string `job=~"foo"`, use `job="foo"` instead. (promql/regexp) 2 | expr: up{job=~"foo"} == 0 -rules/0002.yaml:5 Bug: unnecessary regexp match on static string job!~"foo", use job!="foo" instead (promql/regexp) +rules/0002.yaml:5 Bug: Unnecessary regexp match on static string `job!~"foo"`, use `job!="foo"` instead. (promql/regexp) 5 | expr: up{job!~"foo"} == 0 -rules/0003.yaml:11 Warning: instance label should be removed when aggregating "^colo(?:_.+)?:.+$" rules, use without(instance, ...) (promql/aggregate) +rules/0003.yaml:11 Warning: `instance` label should be removed when aggregating `^colo(?:_.+)?:.+$` rules, use `without(instance, ...)`. (promql/aggregate) 11 | expr: sum(foo) without(job) -rules/0003.yaml:11 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0003.yaml:11 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 11 | expr: sum(foo) without(job) -rules/0003.yaml:14 Fatal: syntax error: unexpected right parenthesis ')' (promql/syntax) +rules/0003.yaml:14 Fatal: Prometheus failed to parse the query with this PromQL error: unexpected right parenthesis ')'. (promql/syntax) 14 | expr: sum(foo) by ()) -rules/0003.yaml:22-25 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0003.yaml:22-25 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 22 | expr: | 23 | sum( 24 | multiline 25 | ) without(job, instance) -rules/0003.yaml:28-31 Warning: instance label should be removed when aggregating "^colo(?:_.+)?:.+$" rules, use without(instance, ...) (promql/aggregate) +rules/0003.yaml:28-31 Warning: `instance` label should be removed when aggregating `^colo(?:_.+)?:.+$` rules, use `without(instance, ...)`. (promql/aggregate) 28 | expr: | 29 | sum(sum) without(job) 30 | + 31 | sum(sum) without(job) -rules/0003.yaml:28-31 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0003.yaml:28-31 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 28 | expr: | 29 | sum(sum) without(job) 30 | + 31 | sum(sum) without(job) -rules/0003.yaml:34-37 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0003.yaml:34-37 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 34 | expr: >- 35 | sum( 36 | multiline2 37 | ) without(job, instance) -rules/0003.yaml:40 Warning: instance label should be removed when aggregating "^colo(?:_.+)?:.+$" rules, remove instance from by() (promql/aggregate) +rules/0003.yaml:40 Warning: `instance` label should be removed when aggregating `^colo(?:_.+)?:.+$` rules, remove instance from `by()`. (promql/aggregate) 40 | expr: sum(byinstance) by(instance) -rules/0003.yaml:40 Warning: job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...) (promql/aggregate) +rules/0003.yaml:40 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`. (promql/aggregate) 40 | expr: sum(byinstance) by(instance) -rules/0003.yaml:58-61 Information: using the value of rate(errors[5m]) inside this annotation might be hard to read, consider using one of humanize template functions to make it more human friendly (alerts/template) +rules/0003.yaml:58-61 Information: Using the value of `rate(errors[5m])` inside this annotation might be hard to read, consider using one of humanize template functions to make it more human friendly. (alerts/template) 58 | expr: sum(rate(errors[5m])) > 0.5 .. 61 | summary: 'error rate: {{ $value }}' diff --git a/cmd/pint/tests/0004_fail_invalid_yaml.txt b/cmd/pint/tests/0004_fail_invalid_yaml.txt index 2ff38c44..e10d8088 100644 --- a/cmd/pint/tests/0004_fail_invalid_yaml.txt +++ b/cmd/pint/tests/0004_fail_invalid_yaml.txt @@ -6,10 +6,10 @@ cmp stderr stderr.txt level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] level=ERROR msg="Failed to parse file content" err="yaml: line 4: did not find expected key" path=rules/bad.yaml lines=1-7 -rules/bad.yaml:4 Fatal: did not find expected key (yaml/parse) +rules/bad.yaml:4 Fatal: YAML parser returned an error when reading this file: `did not find expected key`. (yaml/parse) 4 | -rules/ok.yml:5 Fatal: syntax error: unclosed left bracket (promql/syntax) +rules/ok.yml:5 Fatal: Prometheus failed to parse the query with this PromQL error: unclosed left bracket. (promql/syntax) 5 | expr: sum(foo[5m) level=INFO msg="Problems found" Fatal=2 diff --git a/cmd/pint/tests/0006_rr_labels.txt b/cmd/pint/tests/0006_rr_labels.txt index 4ec1e513..4bab8c73 100644 --- a/cmd/pint/tests/0006_rr_labels.txt +++ b/cmd/pint/tests/0006_rr_labels.txt @@ -5,7 +5,7 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/0001.yml:8 Fatal: incomplete rule, no alert or record key (yaml/parse) +rules/0001.yml:8 Fatal: This rule is not a valid Prometheus rule: `incomplete rule, no alert or record key`. (yaml/parse) 8 | - expr: sum(foo) level=INFO msg="Problems found" Fatal=1 diff --git a/cmd/pint/tests/0007_alerts.txt b/cmd/pint/tests/0007_alerts.txt index a1a1ef57..97347d44 100644 --- a/cmd/pint/tests/0007_alerts.txt +++ b/cmd/pint/tests/0007_alerts.txt @@ -5,47 +5,47 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/0001.yml:1-2 Bug: url annotation is required (alerts/annotation) +rules/0001.yml:1-2 Bug: `url` annotation is required. (alerts/annotation) 1 | - alert: Always 2 | expr: up -rules/0001.yml:1-2 Warning: severity label is required (rule/label) +rules/0001.yml:1-2 Warning: `severity` label is required. (rule/label) 1 | - alert: Always 2 | expr: up -rules/0001.yml:2 Warning: alert query doesn't have any condition, it will always fire if the metric exists (alerts/comparison) +rules/0001.yml:2 Warning: Alert query doesn't have any condition, it will always fire if the metric exists. (alerts/comparison) 2 | expr: up -rules/0001.yml:9-10 Bug: url annotation is required (alerts/annotation) +rules/0001.yml:9-10 Bug: `url` annotation is required. (alerts/annotation) 9 | - alert: ServiceIsDown 10 | expr: up == 0 -rules/0001.yml:9-10 Warning: severity label is required (rule/label) +rules/0001.yml:9-10 Warning: `severity` label is required. (rule/label) 9 | - alert: ServiceIsDown 10 | expr: up == 0 -rules/0001.yml:14 Warning: severity label value must match "^critical|warning|info$" (rule/label) +rules/0001.yml:14 Warning: `severity` label value must match `^critical|warning|info$`. (rule/label) 14 | severity: bad -rules/0001.yml:16 Bug: url annotation value must match "^https://wiki.example.com/page/(.+).html$" (alerts/annotation) +rules/0001.yml:16 Bug: `url` annotation value must match `^https://wiki.example.com/page/(.+).html$`. (alerts/annotation) 16 | url: bad -rules/0002.yml:5 Fatal: template parse error: undefined variable "$label" (alerts/template) +rules/0002.yml:5 Fatal: Template failed to parse with this error: `undefined variable "$label"`. (alerts/template) 5 | summary: 'Instance {{ $label.instance }} down' -rules/0002.yml:6 Fatal: template parse error: undefined variable "$valuexx" (alerts/template) +rules/0002.yml:6 Fatal: Template failed to parse with this error: `undefined variable "$valuexx"`. (alerts/template) 6 | func: '{{ $valuexx | xxx }}' -rules/0002.yml:9 Fatal: template parse error: undefined variable "$label" (alerts/template) +rules/0002.yml:9 Fatal: Template failed to parse with this error: `undefined variable "$label"`. (alerts/template) 9 | summary: 'Instance {{ $label.instance }} down' -rules/0002.yml:10 Fatal: template parse error: function "xxx" not defined (alerts/template) +rules/0002.yml:10 Fatal: Template failed to parse with this error: `function "xxx" not defined`. (alerts/template) 10 | func: '{{ $value | xxx }}' -rules/0002.yml:11 Bug: using $value in labels will generate a new alert on every value change, move it to annotations (alerts/template) +rules/0002.yml:11 Bug: Using `$value` in labels will generate a new alert on every value change, move it to annotations. (alerts/template) 11 | bar: 'Some {{$value}} value' -rules/0002.yml:12 Bug: using .Value in labels will generate a new alert on every value change, move it to annotations (alerts/template) +rules/0002.yml:12 Bug: Using `.Value` in labels will generate a new alert on every value change, move it to annotations. (alerts/template) 12 | val: '{{ .Value|humanizeDuration }}' level=INFO msg="Problems found" Fatal=4 Bug=5 Warning=4 diff --git a/cmd/pint/tests/0008_recording_rule_prometheus.txt b/cmd/pint/tests/0008_recording_rule_prometheus.txt index 7b93f403..b8547ceb 100644 --- a/cmd/pint/tests/0008_recording_rule_prometheus.txt +++ b/cmd/pint/tests/0008_recording_rule_prometheus.txt @@ -5,10 +5,10 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/0001.yml:5 Bug: instance label should be removed when aggregating "^colo(?:_.+)?:.+$" rules, remove instance from by() (promql/aggregate) +rules/0001.yml:5 Bug: `instance` label should be removed when aggregating `^colo(?:_.+)?:.+$` rules, remove instance from `by()`. (promql/aggregate) 5 | expr: sum by (instance) (http_inprogress_requests) -rules/0001.yml:5 Warning: job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...) (promql/aggregate) +rules/0001.yml:5 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`. (promql/aggregate) 5 | expr: sum by (instance) (http_inprogress_requests) level=INFO msg="Problems found" Bug=1 Warning=1 diff --git a/cmd/pint/tests/0009_alerting_rule_prometheus.txt b/cmd/pint/tests/0009_alerting_rule_prometheus.txt index adcaa8de..49879f12 100644 --- a/cmd/pint/tests/0009_alerting_rule_prometheus.txt +++ b/cmd/pint/tests/0009_alerting_rule_prometheus.txt @@ -5,15 +5,15 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/0001.yml:11-13 Bug: link annotation is required (alerts/annotation) +rules/0001.yml:11-13 Bug: `link` annotation is required. (alerts/annotation) 11 | annotations: 12 | summary: "Instance {{ $labels.instance }} down" 13 | description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes." -rules/0001.yml:17 Warning: job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...) (promql/aggregate) +rules/0001.yml:17 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`. (promql/aggregate) 17 | expr: sum by (instance) (http_inprogress_requests) > 0 -rules/0001.yml:19-21 Bug: link annotation is required (alerts/annotation) +rules/0001.yml:19-21 Bug: `link` annotation is required. (alerts/annotation) 19 | annotations: 20 | summary: "High request latency on {{ $labels.instance }}" 21 | description: "{{ $labels.instance }} has a median request latency above 1s (current value: {{ $value }}s)" diff --git a/cmd/pint/tests/0010_syntax_check.txt b/cmd/pint/tests/0010_syntax_check.txt index ffbd98f4..65344f3c 100644 --- a/cmd/pint/tests/0010_syntax_check.txt +++ b/cmd/pint/tests/0010_syntax_check.txt @@ -6,7 +6,7 @@ cmp stderr stderr.txt level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] level=ERROR msg="Failed to parse file content" err="yaml: line 6: did not find expected '-' indicator" path=rules/1.yaml lines=1-12 -rules/1.yaml:6 Fatal: did not find expected '-' indicator (yaml/parse) +rules/1.yaml:6 Fatal: YAML parser returned an error when reading this file: `did not find expected '-' indicator`. (yaml/parse) 6 | level=INFO msg="Problems found" Fatal=1 diff --git a/cmd/pint/tests/0011_ignore_rules.txt b/cmd/pint/tests/0011_ignore_rules.txt index c5c037e7..de940fde 100644 --- a/cmd/pint/tests/0011_ignore_rules.txt +++ b/cmd/pint/tests/0011_ignore_rules.txt @@ -5,19 +5,19 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/1.yaml:5 Fatal: syntax error: unexpected right parenthesis ')' (promql/syntax) +rules/1.yaml:5 Fatal: Prometheus failed to parse the query with this PromQL error: unexpected right parenthesis ')'. (promql/syntax) 5 | expr: sum(errors_total) by ) -rules/1.yaml:16 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/1.yaml:16 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 16 | expr: sum(errors_total) without(job) -rules/1.yaml:22 Fatal: syntax error: unexpected right parenthesis ')' (promql/syntax) +rules/1.yaml:22 Fatal: Prometheus failed to parse the query with this PromQL error: unexpected right parenthesis ')'. (promql/syntax) 22 | expr: sum(errors_total) by ) -rules/1.yaml:33 Warning: alert query doesn't have any condition, it will always fire if the metric exists (alerts/comparison) +rules/1.yaml:33 Warning: Alert query doesn't have any condition, it will always fire if the metric exists. (alerts/comparison) 33 | expr: sum(errors_total) without(job) -rules/1.yaml:33 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/1.yaml:33 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 33 | expr: sum(errors_total) without(job) level=INFO msg="Problems found" Fatal=2 Warning=3 diff --git a/cmd/pint/tests/0012_issue_20.txt b/cmd/pint/tests/0012_issue_20.txt index 8b6444ce..4ff1f23e 100644 --- a/cmd/pint/tests/0012_issue_20.txt +++ b/cmd/pint/tests/0012_issue_20.txt @@ -7,7 +7,7 @@ level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] level=WARN msg="Tried to read more lines than present in the source file, this is likely due to ' ' usage in some rules, see https://github.com/cloudflare/pint/issues/20 for details" path=rules/1.yaml -rules/1.yaml:9-13 Warning: runbook_url annotation is required (alerts/annotation) +rules/1.yaml:9-13 Warning: `runbook_url` annotation is required. (alerts/annotation) 9 | annotations: 10 | summary: "HAProxy server healthcheck failure (instance {{ $labels.instance }})" 11 | description: "Some server healthcheck are failing on {{ $labels.server }}\n VALUE = {{ $value }}\n LABELS: {{ $labels }}" diff --git a/cmd/pint/tests/0017_issue69.txt b/cmd/pint/tests/0017_issue69.txt index f564bfec..91141249 100644 --- a/cmd/pint/tests/0017_issue69.txt +++ b/cmd/pint/tests/0017_issue69.txt @@ -6,4227 +6,4227 @@ pint.error --no-color -l error lint rules cmp stderr stderr.txt -- stderr.txt -- -rules/1.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/1.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/1.yml:1-2 Bug: severity label is required (rule/label) +rules/1.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/1.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/1.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/1.yml:4-5 Bug: severity label is required (rule/label) +rules/1.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/10.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/10.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/10.yml:1-2 Bug: severity label is required (rule/label) +rules/10.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/10.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/10.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/10.yml:4-5 Bug: severity label is required (rule/label) +rules/10.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/100.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/100.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/100.yml:1-2 Bug: severity label is required (rule/label) +rules/100.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/100.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/100.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/100.yml:4-5 Bug: severity label is required (rule/label) +rules/100.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/101.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/101.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/101.yml:1-2 Bug: severity label is required (rule/label) +rules/101.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/101.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/101.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/101.yml:4-5 Bug: severity label is required (rule/label) +rules/101.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/102.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/102.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/102.yml:1-2 Bug: severity label is required (rule/label) +rules/102.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/102.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/102.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/102.yml:4-5 Bug: severity label is required (rule/label) +rules/102.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/103.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/103.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/103.yml:1-2 Bug: severity label is required (rule/label) +rules/103.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/103.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/103.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/103.yml:4-5 Bug: severity label is required (rule/label) +rules/103.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/104.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/104.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/104.yml:1-2 Bug: severity label is required (rule/label) +rules/104.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/104.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/104.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/104.yml:4-5 Bug: severity label is required (rule/label) +rules/104.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/105.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/105.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/105.yml:1-2 Bug: severity label is required (rule/label) +rules/105.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/105.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/105.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/105.yml:4-5 Bug: severity label is required (rule/label) +rules/105.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/106.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/106.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/106.yml:1-2 Bug: severity label is required (rule/label) +rules/106.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/106.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/106.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/106.yml:4-5 Bug: severity label is required (rule/label) +rules/106.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/107.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/107.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/107.yml:1-2 Bug: severity label is required (rule/label) +rules/107.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/107.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/107.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/107.yml:4-5 Bug: severity label is required (rule/label) +rules/107.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/108.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/108.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/108.yml:1-2 Bug: severity label is required (rule/label) +rules/108.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/108.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/108.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/108.yml:4-5 Bug: severity label is required (rule/label) +rules/108.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/109.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/109.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/109.yml:1-2 Bug: severity label is required (rule/label) +rules/109.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/109.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/109.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/109.yml:4-5 Bug: severity label is required (rule/label) +rules/109.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/11.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/11.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/11.yml:1-2 Bug: severity label is required (rule/label) +rules/11.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/11.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/11.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/11.yml:4-5 Bug: severity label is required (rule/label) +rules/11.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/110.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/110.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/110.yml:1-2 Bug: severity label is required (rule/label) +rules/110.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/110.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/110.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/110.yml:4-5 Bug: severity label is required (rule/label) +rules/110.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/111.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/111.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/111.yml:1-2 Bug: severity label is required (rule/label) +rules/111.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/111.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/111.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/111.yml:4-5 Bug: severity label is required (rule/label) +rules/111.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/112.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/112.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/112.yml:1-2 Bug: severity label is required (rule/label) +rules/112.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/112.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/112.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/112.yml:4-5 Bug: severity label is required (rule/label) +rules/112.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/113.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/113.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/113.yml:1-2 Bug: severity label is required (rule/label) +rules/113.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/113.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/113.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/113.yml:4-5 Bug: severity label is required (rule/label) +rules/113.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/114.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/114.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/114.yml:1-2 Bug: severity label is required (rule/label) +rules/114.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/114.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/114.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/114.yml:4-5 Bug: severity label is required (rule/label) +rules/114.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/115.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/115.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/115.yml:1-2 Bug: severity label is required (rule/label) +rules/115.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/115.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/115.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/115.yml:4-5 Bug: severity label is required (rule/label) +rules/115.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/116.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/116.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/116.yml:1-2 Bug: severity label is required (rule/label) +rules/116.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/116.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/116.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/116.yml:4-5 Bug: severity label is required (rule/label) +rules/116.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/117.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/117.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/117.yml:1-2 Bug: severity label is required (rule/label) +rules/117.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/117.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/117.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/117.yml:4-5 Bug: severity label is required (rule/label) +rules/117.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/118.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/118.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/118.yml:1-2 Bug: severity label is required (rule/label) +rules/118.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/118.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/118.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/118.yml:4-5 Bug: severity label is required (rule/label) +rules/118.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/119.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/119.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/119.yml:1-2 Bug: severity label is required (rule/label) +rules/119.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/119.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/119.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/119.yml:4-5 Bug: severity label is required (rule/label) +rules/119.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/12.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/12.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/12.yml:1-2 Bug: severity label is required (rule/label) +rules/12.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/12.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/12.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/12.yml:4-5 Bug: severity label is required (rule/label) +rules/12.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/120.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/120.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/120.yml:1-2 Bug: severity label is required (rule/label) +rules/120.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/120.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/120.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/120.yml:4-5 Bug: severity label is required (rule/label) +rules/120.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/121.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/121.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/121.yml:1-2 Bug: severity label is required (rule/label) +rules/121.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/121.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/121.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/121.yml:4-5 Bug: severity label is required (rule/label) +rules/121.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/122.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/122.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/122.yml:1-2 Bug: severity label is required (rule/label) +rules/122.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/122.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/122.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/122.yml:4-5 Bug: severity label is required (rule/label) +rules/122.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/123.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/123.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/123.yml:1-2 Bug: severity label is required (rule/label) +rules/123.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/123.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/123.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/123.yml:4-5 Bug: severity label is required (rule/label) +rules/123.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/124.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/124.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/124.yml:1-2 Bug: severity label is required (rule/label) +rules/124.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/124.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/124.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/124.yml:4-5 Bug: severity label is required (rule/label) +rules/124.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/125.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/125.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/125.yml:1-2 Bug: severity label is required (rule/label) +rules/125.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/125.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/125.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/125.yml:4-5 Bug: severity label is required (rule/label) +rules/125.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/126.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/126.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/126.yml:1-2 Bug: severity label is required (rule/label) +rules/126.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/126.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/126.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/126.yml:4-5 Bug: severity label is required (rule/label) +rules/126.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/127.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/127.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/127.yml:1-2 Bug: severity label is required (rule/label) +rules/127.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/127.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/127.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/127.yml:4-5 Bug: severity label is required (rule/label) +rules/127.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/128.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/128.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/128.yml:1-2 Bug: severity label is required (rule/label) +rules/128.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/128.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/128.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/128.yml:4-5 Bug: severity label is required (rule/label) +rules/128.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/129.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/129.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/129.yml:1-2 Bug: severity label is required (rule/label) +rules/129.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/129.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/129.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/129.yml:4-5 Bug: severity label is required (rule/label) +rules/129.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/13.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/13.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/13.yml:1-2 Bug: severity label is required (rule/label) +rules/13.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/13.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/13.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/13.yml:4-5 Bug: severity label is required (rule/label) +rules/13.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/130.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/130.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/130.yml:1-2 Bug: severity label is required (rule/label) +rules/130.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/130.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/130.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/130.yml:4-5 Bug: severity label is required (rule/label) +rules/130.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/131.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/131.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/131.yml:1-2 Bug: severity label is required (rule/label) +rules/131.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/131.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/131.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/131.yml:4-5 Bug: severity label is required (rule/label) +rules/131.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/132.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/132.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/132.yml:1-2 Bug: severity label is required (rule/label) +rules/132.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/132.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/132.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/132.yml:4-5 Bug: severity label is required (rule/label) +rules/132.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/133.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/133.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/133.yml:1-2 Bug: severity label is required (rule/label) +rules/133.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/133.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/133.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/133.yml:4-5 Bug: severity label is required (rule/label) +rules/133.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/134.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/134.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/134.yml:1-2 Bug: severity label is required (rule/label) +rules/134.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/134.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/134.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/134.yml:4-5 Bug: severity label is required (rule/label) +rules/134.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/135.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/135.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/135.yml:1-2 Bug: severity label is required (rule/label) +rules/135.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/135.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/135.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/135.yml:4-5 Bug: severity label is required (rule/label) +rules/135.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/136.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/136.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/136.yml:1-2 Bug: severity label is required (rule/label) +rules/136.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/136.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/136.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/136.yml:4-5 Bug: severity label is required (rule/label) +rules/136.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/137.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/137.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/137.yml:1-2 Bug: severity label is required (rule/label) +rules/137.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/137.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/137.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/137.yml:4-5 Bug: severity label is required (rule/label) +rules/137.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/138.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/138.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/138.yml:1-2 Bug: severity label is required (rule/label) +rules/138.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/138.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/138.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/138.yml:4-5 Bug: severity label is required (rule/label) +rules/138.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/139.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/139.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/139.yml:1-2 Bug: severity label is required (rule/label) +rules/139.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/139.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/139.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/139.yml:4-5 Bug: severity label is required (rule/label) +rules/139.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/14.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/14.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/14.yml:1-2 Bug: severity label is required (rule/label) +rules/14.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/14.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/14.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/14.yml:4-5 Bug: severity label is required (rule/label) +rules/14.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/140.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/140.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/140.yml:1-2 Bug: severity label is required (rule/label) +rules/140.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/140.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/140.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/140.yml:4-5 Bug: severity label is required (rule/label) +rules/140.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/141.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/141.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/141.yml:1-2 Bug: severity label is required (rule/label) +rules/141.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/141.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/141.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/141.yml:4-5 Bug: severity label is required (rule/label) +rules/141.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/142.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/142.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/142.yml:1-2 Bug: severity label is required (rule/label) +rules/142.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/142.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/142.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/142.yml:4-5 Bug: severity label is required (rule/label) +rules/142.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/143.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/143.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/143.yml:1-2 Bug: severity label is required (rule/label) +rules/143.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/143.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/143.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/143.yml:4-5 Bug: severity label is required (rule/label) +rules/143.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/144.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/144.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/144.yml:1-2 Bug: severity label is required (rule/label) +rules/144.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/144.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/144.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/144.yml:4-5 Bug: severity label is required (rule/label) +rules/144.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/145.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/145.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/145.yml:1-2 Bug: severity label is required (rule/label) +rules/145.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/145.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/145.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/145.yml:4-5 Bug: severity label is required (rule/label) +rules/145.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/146.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/146.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/146.yml:1-2 Bug: severity label is required (rule/label) +rules/146.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/146.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/146.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/146.yml:4-5 Bug: severity label is required (rule/label) +rules/146.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/147.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/147.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/147.yml:1-2 Bug: severity label is required (rule/label) +rules/147.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/147.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/147.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/147.yml:4-5 Bug: severity label is required (rule/label) +rules/147.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/148.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/148.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/148.yml:1-2 Bug: severity label is required (rule/label) +rules/148.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/148.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/148.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/148.yml:4-5 Bug: severity label is required (rule/label) +rules/148.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/149.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/149.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/149.yml:1-2 Bug: severity label is required (rule/label) +rules/149.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/149.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/149.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/149.yml:4-5 Bug: severity label is required (rule/label) +rules/149.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/15.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/15.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/15.yml:1-2 Bug: severity label is required (rule/label) +rules/15.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/15.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/15.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/15.yml:4-5 Bug: severity label is required (rule/label) +rules/15.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/150.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/150.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/150.yml:1-2 Bug: severity label is required (rule/label) +rules/150.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/150.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/150.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/150.yml:4-5 Bug: severity label is required (rule/label) +rules/150.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/151.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/151.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/151.yml:1-2 Bug: severity label is required (rule/label) +rules/151.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/151.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/151.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/151.yml:4-5 Bug: severity label is required (rule/label) +rules/151.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/152.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/152.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/152.yml:1-2 Bug: severity label is required (rule/label) +rules/152.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/152.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/152.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/152.yml:4-5 Bug: severity label is required (rule/label) +rules/152.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/153.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/153.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/153.yml:1-2 Bug: severity label is required (rule/label) +rules/153.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/153.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/153.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/153.yml:4-5 Bug: severity label is required (rule/label) +rules/153.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/154.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/154.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/154.yml:1-2 Bug: severity label is required (rule/label) +rules/154.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/154.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/154.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/154.yml:4-5 Bug: severity label is required (rule/label) +rules/154.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/155.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/155.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/155.yml:1-2 Bug: severity label is required (rule/label) +rules/155.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/155.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/155.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/155.yml:4-5 Bug: severity label is required (rule/label) +rules/155.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/156.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/156.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/156.yml:1-2 Bug: severity label is required (rule/label) +rules/156.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/156.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/156.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/156.yml:4-5 Bug: severity label is required (rule/label) +rules/156.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/157.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/157.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/157.yml:1-2 Bug: severity label is required (rule/label) +rules/157.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/157.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/157.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/157.yml:4-5 Bug: severity label is required (rule/label) +rules/157.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/158.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/158.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/158.yml:1-2 Bug: severity label is required (rule/label) +rules/158.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/158.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/158.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/158.yml:4-5 Bug: severity label is required (rule/label) +rules/158.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/159.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/159.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/159.yml:1-2 Bug: severity label is required (rule/label) +rules/159.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/159.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/159.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/159.yml:4-5 Bug: severity label is required (rule/label) +rules/159.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/16.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/16.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/16.yml:1-2 Bug: severity label is required (rule/label) +rules/16.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/16.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/16.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/16.yml:4-5 Bug: severity label is required (rule/label) +rules/16.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/160.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/160.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/160.yml:1-2 Bug: severity label is required (rule/label) +rules/160.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/160.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/160.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/160.yml:4-5 Bug: severity label is required (rule/label) +rules/160.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/161.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/161.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/161.yml:1-2 Bug: severity label is required (rule/label) +rules/161.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/161.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/161.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/161.yml:4-5 Bug: severity label is required (rule/label) +rules/161.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/162.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/162.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/162.yml:1-2 Bug: severity label is required (rule/label) +rules/162.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/162.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/162.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/162.yml:4-5 Bug: severity label is required (rule/label) +rules/162.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/163.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/163.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/163.yml:1-2 Bug: severity label is required (rule/label) +rules/163.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/163.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/163.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/163.yml:4-5 Bug: severity label is required (rule/label) +rules/163.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/164.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/164.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/164.yml:1-2 Bug: severity label is required (rule/label) +rules/164.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/164.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/164.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/164.yml:4-5 Bug: severity label is required (rule/label) +rules/164.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/165.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/165.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/165.yml:1-2 Bug: severity label is required (rule/label) +rules/165.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/165.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/165.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/165.yml:4-5 Bug: severity label is required (rule/label) +rules/165.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/166.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/166.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/166.yml:1-2 Bug: severity label is required (rule/label) +rules/166.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/166.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/166.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/166.yml:4-5 Bug: severity label is required (rule/label) +rules/166.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/167.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/167.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/167.yml:1-2 Bug: severity label is required (rule/label) +rules/167.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/167.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/167.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/167.yml:4-5 Bug: severity label is required (rule/label) +rules/167.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/168.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/168.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/168.yml:1-2 Bug: severity label is required (rule/label) +rules/168.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/168.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/168.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/168.yml:4-5 Bug: severity label is required (rule/label) +rules/168.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/169.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/169.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/169.yml:1-2 Bug: severity label is required (rule/label) +rules/169.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/169.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/169.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/169.yml:4-5 Bug: severity label is required (rule/label) +rules/169.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/17.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/17.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/17.yml:1-2 Bug: severity label is required (rule/label) +rules/17.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/17.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/17.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/17.yml:4-5 Bug: severity label is required (rule/label) +rules/17.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/170.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/170.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/170.yml:1-2 Bug: severity label is required (rule/label) +rules/170.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/170.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/170.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/170.yml:4-5 Bug: severity label is required (rule/label) +rules/170.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/171.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/171.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/171.yml:1-2 Bug: severity label is required (rule/label) +rules/171.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/171.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/171.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/171.yml:4-5 Bug: severity label is required (rule/label) +rules/171.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/172.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/172.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/172.yml:1-2 Bug: severity label is required (rule/label) +rules/172.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/172.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/172.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/172.yml:4-5 Bug: severity label is required (rule/label) +rules/172.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/173.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/173.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/173.yml:1-2 Bug: severity label is required (rule/label) +rules/173.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/173.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/173.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/173.yml:4-5 Bug: severity label is required (rule/label) +rules/173.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/174.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/174.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/174.yml:1-2 Bug: severity label is required (rule/label) +rules/174.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/174.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/174.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/174.yml:4-5 Bug: severity label is required (rule/label) +rules/174.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/175.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/175.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/175.yml:1-2 Bug: severity label is required (rule/label) +rules/175.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/175.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/175.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/175.yml:4-5 Bug: severity label is required (rule/label) +rules/175.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/176.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/176.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/176.yml:1-2 Bug: severity label is required (rule/label) +rules/176.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/176.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/176.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/176.yml:4-5 Bug: severity label is required (rule/label) +rules/176.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/177.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/177.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/177.yml:1-2 Bug: severity label is required (rule/label) +rules/177.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/177.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/177.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/177.yml:4-5 Bug: severity label is required (rule/label) +rules/177.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/178.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/178.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/178.yml:1-2 Bug: severity label is required (rule/label) +rules/178.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/178.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/178.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/178.yml:4-5 Bug: severity label is required (rule/label) +rules/178.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/179.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/179.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/179.yml:1-2 Bug: severity label is required (rule/label) +rules/179.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/179.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/179.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/179.yml:4-5 Bug: severity label is required (rule/label) +rules/179.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/18.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/18.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/18.yml:1-2 Bug: severity label is required (rule/label) +rules/18.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/18.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/18.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/18.yml:4-5 Bug: severity label is required (rule/label) +rules/18.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/180.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/180.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/180.yml:1-2 Bug: severity label is required (rule/label) +rules/180.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/180.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/180.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/180.yml:4-5 Bug: severity label is required (rule/label) +rules/180.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/181.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/181.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/181.yml:1-2 Bug: severity label is required (rule/label) +rules/181.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/181.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/181.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/181.yml:4-5 Bug: severity label is required (rule/label) +rules/181.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/182.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/182.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/182.yml:1-2 Bug: severity label is required (rule/label) +rules/182.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/182.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/182.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/182.yml:4-5 Bug: severity label is required (rule/label) +rules/182.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/183.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/183.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/183.yml:1-2 Bug: severity label is required (rule/label) +rules/183.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/183.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/183.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/183.yml:4-5 Bug: severity label is required (rule/label) +rules/183.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/184.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/184.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/184.yml:1-2 Bug: severity label is required (rule/label) +rules/184.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/184.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/184.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/184.yml:4-5 Bug: severity label is required (rule/label) +rules/184.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/185.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/185.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/185.yml:1-2 Bug: severity label is required (rule/label) +rules/185.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/185.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/185.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/185.yml:4-5 Bug: severity label is required (rule/label) +rules/185.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/186.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/186.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/186.yml:1-2 Bug: severity label is required (rule/label) +rules/186.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/186.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/186.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/186.yml:4-5 Bug: severity label is required (rule/label) +rules/186.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/187.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/187.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/187.yml:1-2 Bug: severity label is required (rule/label) +rules/187.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/187.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/187.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/187.yml:4-5 Bug: severity label is required (rule/label) +rules/187.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/188.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/188.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/188.yml:1-2 Bug: severity label is required (rule/label) +rules/188.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/188.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/188.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/188.yml:4-5 Bug: severity label is required (rule/label) +rules/188.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/189.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/189.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/189.yml:1-2 Bug: severity label is required (rule/label) +rules/189.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/189.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/189.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/189.yml:4-5 Bug: severity label is required (rule/label) +rules/189.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/19.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/19.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/19.yml:1-2 Bug: severity label is required (rule/label) +rules/19.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/19.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/19.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/19.yml:4-5 Bug: severity label is required (rule/label) +rules/19.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/190.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/190.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/190.yml:1-2 Bug: severity label is required (rule/label) +rules/190.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/190.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/190.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/190.yml:4-5 Bug: severity label is required (rule/label) +rules/190.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/191.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/191.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/191.yml:1-2 Bug: severity label is required (rule/label) +rules/191.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/191.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/191.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/191.yml:4-5 Bug: severity label is required (rule/label) +rules/191.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/192.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/192.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/192.yml:1-2 Bug: severity label is required (rule/label) +rules/192.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/192.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/192.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/192.yml:4-5 Bug: severity label is required (rule/label) +rules/192.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/193.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/193.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/193.yml:1-2 Bug: severity label is required (rule/label) +rules/193.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/193.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/193.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/193.yml:4-5 Bug: severity label is required (rule/label) +rules/193.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/194.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/194.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/194.yml:1-2 Bug: severity label is required (rule/label) +rules/194.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/194.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/194.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/194.yml:4-5 Bug: severity label is required (rule/label) +rules/194.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/195.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/195.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/195.yml:1-2 Bug: severity label is required (rule/label) +rules/195.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/195.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/195.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/195.yml:4-5 Bug: severity label is required (rule/label) +rules/195.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/196.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/196.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/196.yml:1-2 Bug: severity label is required (rule/label) +rules/196.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/196.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/196.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/196.yml:4-5 Bug: severity label is required (rule/label) +rules/196.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/197.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/197.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/197.yml:1-2 Bug: severity label is required (rule/label) +rules/197.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/197.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/197.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/197.yml:4-5 Bug: severity label is required (rule/label) +rules/197.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/198.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/198.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/198.yml:1-2 Bug: severity label is required (rule/label) +rules/198.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/198.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/198.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/198.yml:4-5 Bug: severity label is required (rule/label) +rules/198.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/199.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/199.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/199.yml:1-2 Bug: severity label is required (rule/label) +rules/199.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/199.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/199.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/199.yml:4-5 Bug: severity label is required (rule/label) +rules/199.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/2.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/2.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/2.yml:1-2 Bug: severity label is required (rule/label) +rules/2.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/2.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/2.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/2.yml:4-5 Bug: severity label is required (rule/label) +rules/2.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/20.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/20.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/20.yml:1-2 Bug: severity label is required (rule/label) +rules/20.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/20.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/20.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/20.yml:4-5 Bug: severity label is required (rule/label) +rules/20.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/200.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/200.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/200.yml:1-2 Bug: severity label is required (rule/label) +rules/200.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/200.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/200.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/200.yml:4-5 Bug: severity label is required (rule/label) +rules/200.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/201.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/201.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/201.yml:1-2 Bug: severity label is required (rule/label) +rules/201.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/201.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/201.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/201.yml:4-5 Bug: severity label is required (rule/label) +rules/201.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/202.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/202.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/202.yml:1-2 Bug: severity label is required (rule/label) +rules/202.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/202.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/202.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/202.yml:4-5 Bug: severity label is required (rule/label) +rules/202.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/203.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/203.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/203.yml:1-2 Bug: severity label is required (rule/label) +rules/203.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/203.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/203.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/203.yml:4-5 Bug: severity label is required (rule/label) +rules/203.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/204.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/204.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/204.yml:1-2 Bug: severity label is required (rule/label) +rules/204.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/204.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/204.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/204.yml:4-5 Bug: severity label is required (rule/label) +rules/204.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/205.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/205.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/205.yml:1-2 Bug: severity label is required (rule/label) +rules/205.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/205.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/205.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/205.yml:4-5 Bug: severity label is required (rule/label) +rules/205.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/206.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/206.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/206.yml:1-2 Bug: severity label is required (rule/label) +rules/206.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/206.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/206.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/206.yml:4-5 Bug: severity label is required (rule/label) +rules/206.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/207.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/207.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/207.yml:1-2 Bug: severity label is required (rule/label) +rules/207.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/207.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/207.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/207.yml:4-5 Bug: severity label is required (rule/label) +rules/207.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/208.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/208.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/208.yml:1-2 Bug: severity label is required (rule/label) +rules/208.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/208.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/208.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/208.yml:4-5 Bug: severity label is required (rule/label) +rules/208.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/209.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/209.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/209.yml:1-2 Bug: severity label is required (rule/label) +rules/209.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/209.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/209.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/209.yml:4-5 Bug: severity label is required (rule/label) +rules/209.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/21.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/21.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/21.yml:1-2 Bug: severity label is required (rule/label) +rules/21.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/21.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/21.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/21.yml:4-5 Bug: severity label is required (rule/label) +rules/21.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/210.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/210.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/210.yml:1-2 Bug: severity label is required (rule/label) +rules/210.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/210.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/210.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/210.yml:4-5 Bug: severity label is required (rule/label) +rules/210.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/211.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/211.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/211.yml:1-2 Bug: severity label is required (rule/label) +rules/211.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/211.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/211.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/211.yml:4-5 Bug: severity label is required (rule/label) +rules/211.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/212.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/212.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/212.yml:1-2 Bug: severity label is required (rule/label) +rules/212.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/212.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/212.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/212.yml:4-5 Bug: severity label is required (rule/label) +rules/212.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/213.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/213.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/213.yml:1-2 Bug: severity label is required (rule/label) +rules/213.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/213.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/213.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/213.yml:4-5 Bug: severity label is required (rule/label) +rules/213.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/214.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/214.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/214.yml:1-2 Bug: severity label is required (rule/label) +rules/214.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/214.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/214.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/214.yml:4-5 Bug: severity label is required (rule/label) +rules/214.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/215.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/215.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/215.yml:1-2 Bug: severity label is required (rule/label) +rules/215.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/215.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/215.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/215.yml:4-5 Bug: severity label is required (rule/label) +rules/215.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/216.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/216.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/216.yml:1-2 Bug: severity label is required (rule/label) +rules/216.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/216.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/216.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/216.yml:4-5 Bug: severity label is required (rule/label) +rules/216.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/217.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/217.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/217.yml:1-2 Bug: severity label is required (rule/label) +rules/217.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/217.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/217.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/217.yml:4-5 Bug: severity label is required (rule/label) +rules/217.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/218.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/218.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/218.yml:1-2 Bug: severity label is required (rule/label) +rules/218.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/218.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/218.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/218.yml:4-5 Bug: severity label is required (rule/label) +rules/218.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/219.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/219.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/219.yml:1-2 Bug: severity label is required (rule/label) +rules/219.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/219.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/219.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/219.yml:4-5 Bug: severity label is required (rule/label) +rules/219.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/22.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/22.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/22.yml:1-2 Bug: severity label is required (rule/label) +rules/22.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/22.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/22.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/22.yml:4-5 Bug: severity label is required (rule/label) +rules/22.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/220.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/220.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/220.yml:1-2 Bug: severity label is required (rule/label) +rules/220.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/220.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/220.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/220.yml:4-5 Bug: severity label is required (rule/label) +rules/220.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/221.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/221.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/221.yml:1-2 Bug: severity label is required (rule/label) +rules/221.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/221.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/221.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/221.yml:4-5 Bug: severity label is required (rule/label) +rules/221.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/222.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/222.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/222.yml:1-2 Bug: severity label is required (rule/label) +rules/222.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/222.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/222.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/222.yml:4-5 Bug: severity label is required (rule/label) +rules/222.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/223.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/223.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/223.yml:1-2 Bug: severity label is required (rule/label) +rules/223.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/223.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/223.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/223.yml:4-5 Bug: severity label is required (rule/label) +rules/223.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/224.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/224.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/224.yml:1-2 Bug: severity label is required (rule/label) +rules/224.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/224.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/224.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/224.yml:4-5 Bug: severity label is required (rule/label) +rules/224.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/225.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/225.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/225.yml:1-2 Bug: severity label is required (rule/label) +rules/225.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/225.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/225.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/225.yml:4-5 Bug: severity label is required (rule/label) +rules/225.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/226.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/226.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/226.yml:1-2 Bug: severity label is required (rule/label) +rules/226.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/226.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/226.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/226.yml:4-5 Bug: severity label is required (rule/label) +rules/226.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/227.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/227.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/227.yml:1-2 Bug: severity label is required (rule/label) +rules/227.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/227.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/227.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/227.yml:4-5 Bug: severity label is required (rule/label) +rules/227.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/228.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/228.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/228.yml:1-2 Bug: severity label is required (rule/label) +rules/228.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/228.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/228.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/228.yml:4-5 Bug: severity label is required (rule/label) +rules/228.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/229.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/229.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/229.yml:1-2 Bug: severity label is required (rule/label) +rules/229.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/229.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/229.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/229.yml:4-5 Bug: severity label is required (rule/label) +rules/229.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/23.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/23.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/23.yml:1-2 Bug: severity label is required (rule/label) +rules/23.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/23.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/23.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/23.yml:4-5 Bug: severity label is required (rule/label) +rules/23.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/230.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/230.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/230.yml:1-2 Bug: severity label is required (rule/label) +rules/230.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/230.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/230.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/230.yml:4-5 Bug: severity label is required (rule/label) +rules/230.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/231.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/231.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/231.yml:1-2 Bug: severity label is required (rule/label) +rules/231.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/231.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/231.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/231.yml:4-5 Bug: severity label is required (rule/label) +rules/231.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/232.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/232.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/232.yml:1-2 Bug: severity label is required (rule/label) +rules/232.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/232.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/232.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/232.yml:4-5 Bug: severity label is required (rule/label) +rules/232.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/233.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/233.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/233.yml:1-2 Bug: severity label is required (rule/label) +rules/233.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/233.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/233.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/233.yml:4-5 Bug: severity label is required (rule/label) +rules/233.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/234.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/234.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/234.yml:1-2 Bug: severity label is required (rule/label) +rules/234.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/234.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/234.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/234.yml:4-5 Bug: severity label is required (rule/label) +rules/234.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/235.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/235.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/235.yml:1-2 Bug: severity label is required (rule/label) +rules/235.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/235.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/235.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/235.yml:4-5 Bug: severity label is required (rule/label) +rules/235.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/236.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/236.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/236.yml:1-2 Bug: severity label is required (rule/label) +rules/236.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/236.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/236.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/236.yml:4-5 Bug: severity label is required (rule/label) +rules/236.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/237.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/237.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/237.yml:1-2 Bug: severity label is required (rule/label) +rules/237.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/237.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/237.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/237.yml:4-5 Bug: severity label is required (rule/label) +rules/237.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/238.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/238.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/238.yml:1-2 Bug: severity label is required (rule/label) +rules/238.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/238.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/238.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/238.yml:4-5 Bug: severity label is required (rule/label) +rules/238.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/239.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/239.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/239.yml:1-2 Bug: severity label is required (rule/label) +rules/239.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/239.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/239.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/239.yml:4-5 Bug: severity label is required (rule/label) +rules/239.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/24.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/24.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/24.yml:1-2 Bug: severity label is required (rule/label) +rules/24.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/24.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/24.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/24.yml:4-5 Bug: severity label is required (rule/label) +rules/24.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/240.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/240.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/240.yml:1-2 Bug: severity label is required (rule/label) +rules/240.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/240.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/240.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/240.yml:4-5 Bug: severity label is required (rule/label) +rules/240.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/241.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/241.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/241.yml:1-2 Bug: severity label is required (rule/label) +rules/241.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/241.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/241.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/241.yml:4-5 Bug: severity label is required (rule/label) +rules/241.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/242.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/242.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/242.yml:1-2 Bug: severity label is required (rule/label) +rules/242.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/242.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/242.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/242.yml:4-5 Bug: severity label is required (rule/label) +rules/242.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/243.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/243.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/243.yml:1-2 Bug: severity label is required (rule/label) +rules/243.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/243.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/243.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/243.yml:4-5 Bug: severity label is required (rule/label) +rules/243.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/244.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/244.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/244.yml:1-2 Bug: severity label is required (rule/label) +rules/244.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/244.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/244.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/244.yml:4-5 Bug: severity label is required (rule/label) +rules/244.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/245.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/245.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/245.yml:1-2 Bug: severity label is required (rule/label) +rules/245.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/245.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/245.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/245.yml:4-5 Bug: severity label is required (rule/label) +rules/245.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/246.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/246.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/246.yml:1-2 Bug: severity label is required (rule/label) +rules/246.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/246.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/246.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/246.yml:4-5 Bug: severity label is required (rule/label) +rules/246.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/247.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/247.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/247.yml:1-2 Bug: severity label is required (rule/label) +rules/247.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/247.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/247.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/247.yml:4-5 Bug: severity label is required (rule/label) +rules/247.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/248.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/248.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/248.yml:1-2 Bug: severity label is required (rule/label) +rules/248.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/248.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/248.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/248.yml:4-5 Bug: severity label is required (rule/label) +rules/248.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/249.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/249.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/249.yml:1-2 Bug: severity label is required (rule/label) +rules/249.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/249.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/249.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/249.yml:4-5 Bug: severity label is required (rule/label) +rules/249.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/25.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/25.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/25.yml:1-2 Bug: severity label is required (rule/label) +rules/25.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/25.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/25.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/25.yml:4-5 Bug: severity label is required (rule/label) +rules/25.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/250.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/250.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/250.yml:1-2 Bug: severity label is required (rule/label) +rules/250.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/250.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/250.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/250.yml:4-5 Bug: severity label is required (rule/label) +rules/250.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/251.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/251.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/251.yml:1-2 Bug: severity label is required (rule/label) +rules/251.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/251.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/251.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/251.yml:4-5 Bug: severity label is required (rule/label) +rules/251.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/252.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/252.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/252.yml:1-2 Bug: severity label is required (rule/label) +rules/252.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/252.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/252.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/252.yml:4-5 Bug: severity label is required (rule/label) +rules/252.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/253.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/253.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/253.yml:1-2 Bug: severity label is required (rule/label) +rules/253.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/253.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/253.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/253.yml:4-5 Bug: severity label is required (rule/label) +rules/253.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/254.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/254.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/254.yml:1-2 Bug: severity label is required (rule/label) +rules/254.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/254.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/254.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/254.yml:4-5 Bug: severity label is required (rule/label) +rules/254.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/255.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/255.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/255.yml:1-2 Bug: severity label is required (rule/label) +rules/255.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/255.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/255.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/255.yml:4-5 Bug: severity label is required (rule/label) +rules/255.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/256.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/256.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/256.yml:1-2 Bug: severity label is required (rule/label) +rules/256.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/256.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/256.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/256.yml:4-5 Bug: severity label is required (rule/label) +rules/256.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/257.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/257.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/257.yml:1-2 Bug: severity label is required (rule/label) +rules/257.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/257.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/257.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/257.yml:4-5 Bug: severity label is required (rule/label) +rules/257.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/258.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/258.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/258.yml:1-2 Bug: severity label is required (rule/label) +rules/258.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/258.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/258.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/258.yml:4-5 Bug: severity label is required (rule/label) +rules/258.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/259.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/259.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/259.yml:1-2 Bug: severity label is required (rule/label) +rules/259.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/259.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/259.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/259.yml:4-5 Bug: severity label is required (rule/label) +rules/259.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/26.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/26.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/26.yml:1-2 Bug: severity label is required (rule/label) +rules/26.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/26.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/26.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/26.yml:4-5 Bug: severity label is required (rule/label) +rules/26.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/260.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/260.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/260.yml:1-2 Bug: severity label is required (rule/label) +rules/260.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/260.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/260.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/260.yml:4-5 Bug: severity label is required (rule/label) +rules/260.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/261.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/261.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/261.yml:1-2 Bug: severity label is required (rule/label) +rules/261.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/261.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/261.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/261.yml:4-5 Bug: severity label is required (rule/label) +rules/261.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/262.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/262.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/262.yml:1-2 Bug: severity label is required (rule/label) +rules/262.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/262.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/262.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/262.yml:4-5 Bug: severity label is required (rule/label) +rules/262.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/263.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/263.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/263.yml:1-2 Bug: severity label is required (rule/label) +rules/263.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/263.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/263.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/263.yml:4-5 Bug: severity label is required (rule/label) +rules/263.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/27.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/27.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/27.yml:1-2 Bug: severity label is required (rule/label) +rules/27.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/27.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/27.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/27.yml:4-5 Bug: severity label is required (rule/label) +rules/27.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/28.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/28.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/28.yml:1-2 Bug: severity label is required (rule/label) +rules/28.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/28.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/28.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/28.yml:4-5 Bug: severity label is required (rule/label) +rules/28.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/29.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/29.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/29.yml:1-2 Bug: severity label is required (rule/label) +rules/29.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/29.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/29.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/29.yml:4-5 Bug: severity label is required (rule/label) +rules/29.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/3.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/3.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/3.yml:1-2 Bug: severity label is required (rule/label) +rules/3.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/3.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/3.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/3.yml:4-5 Bug: severity label is required (rule/label) +rules/3.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/30.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/30.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/30.yml:1-2 Bug: severity label is required (rule/label) +rules/30.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/30.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/30.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/30.yml:4-5 Bug: severity label is required (rule/label) +rules/30.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/31.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/31.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/31.yml:1-2 Bug: severity label is required (rule/label) +rules/31.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/31.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/31.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/31.yml:4-5 Bug: severity label is required (rule/label) +rules/31.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/32.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/32.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/32.yml:1-2 Bug: severity label is required (rule/label) +rules/32.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/32.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/32.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/32.yml:4-5 Bug: severity label is required (rule/label) +rules/32.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/33.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/33.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/33.yml:1-2 Bug: severity label is required (rule/label) +rules/33.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/33.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/33.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/33.yml:4-5 Bug: severity label is required (rule/label) +rules/33.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/34.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/34.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/34.yml:1-2 Bug: severity label is required (rule/label) +rules/34.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/34.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/34.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/34.yml:4-5 Bug: severity label is required (rule/label) +rules/34.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/35.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/35.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/35.yml:1-2 Bug: severity label is required (rule/label) +rules/35.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/35.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/35.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/35.yml:4-5 Bug: severity label is required (rule/label) +rules/35.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/36.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/36.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/36.yml:1-2 Bug: severity label is required (rule/label) +rules/36.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/36.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/36.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/36.yml:4-5 Bug: severity label is required (rule/label) +rules/36.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/37.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/37.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/37.yml:1-2 Bug: severity label is required (rule/label) +rules/37.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/37.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/37.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/37.yml:4-5 Bug: severity label is required (rule/label) +rules/37.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/38.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/38.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/38.yml:1-2 Bug: severity label is required (rule/label) +rules/38.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/38.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/38.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/38.yml:4-5 Bug: severity label is required (rule/label) +rules/38.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/39.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/39.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/39.yml:1-2 Bug: severity label is required (rule/label) +rules/39.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/39.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/39.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/39.yml:4-5 Bug: severity label is required (rule/label) +rules/39.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/4.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/4.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/4.yml:1-2 Bug: severity label is required (rule/label) +rules/4.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/4.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/4.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/4.yml:4-5 Bug: severity label is required (rule/label) +rules/4.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/40.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/40.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/40.yml:1-2 Bug: severity label is required (rule/label) +rules/40.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/40.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/40.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/40.yml:4-5 Bug: severity label is required (rule/label) +rules/40.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/41.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/41.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/41.yml:1-2 Bug: severity label is required (rule/label) +rules/41.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/41.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/41.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/41.yml:4-5 Bug: severity label is required (rule/label) +rules/41.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/42.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/42.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/42.yml:1-2 Bug: severity label is required (rule/label) +rules/42.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/42.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/42.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/42.yml:4-5 Bug: severity label is required (rule/label) +rules/42.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/43.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/43.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/43.yml:1-2 Bug: severity label is required (rule/label) +rules/43.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/43.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/43.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/43.yml:4-5 Bug: severity label is required (rule/label) +rules/43.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/44.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/44.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/44.yml:1-2 Bug: severity label is required (rule/label) +rules/44.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/44.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/44.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/44.yml:4-5 Bug: severity label is required (rule/label) +rules/44.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/45.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/45.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/45.yml:1-2 Bug: severity label is required (rule/label) +rules/45.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/45.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/45.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/45.yml:4-5 Bug: severity label is required (rule/label) +rules/45.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/46.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/46.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/46.yml:1-2 Bug: severity label is required (rule/label) +rules/46.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/46.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/46.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/46.yml:4-5 Bug: severity label is required (rule/label) +rules/46.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/47.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/47.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/47.yml:1-2 Bug: severity label is required (rule/label) +rules/47.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/47.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/47.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/47.yml:4-5 Bug: severity label is required (rule/label) +rules/47.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/48.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/48.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/48.yml:1-2 Bug: severity label is required (rule/label) +rules/48.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/48.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/48.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/48.yml:4-5 Bug: severity label is required (rule/label) +rules/48.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/49.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/49.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/49.yml:1-2 Bug: severity label is required (rule/label) +rules/49.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/49.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/49.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/49.yml:4-5 Bug: severity label is required (rule/label) +rules/49.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/5.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/5.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/5.yml:1-2 Bug: severity label is required (rule/label) +rules/5.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/5.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/5.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/5.yml:4-5 Bug: severity label is required (rule/label) +rules/5.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/50.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/50.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/50.yml:1-2 Bug: severity label is required (rule/label) +rules/50.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/50.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/50.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/50.yml:4-5 Bug: severity label is required (rule/label) +rules/50.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/51.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/51.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/51.yml:1-2 Bug: severity label is required (rule/label) +rules/51.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/51.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/51.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/51.yml:4-5 Bug: severity label is required (rule/label) +rules/51.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/52.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/52.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/52.yml:1-2 Bug: severity label is required (rule/label) +rules/52.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/52.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/52.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/52.yml:4-5 Bug: severity label is required (rule/label) +rules/52.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/53.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/53.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/53.yml:1-2 Bug: severity label is required (rule/label) +rules/53.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/53.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/53.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/53.yml:4-5 Bug: severity label is required (rule/label) +rules/53.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/54.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/54.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/54.yml:1-2 Bug: severity label is required (rule/label) +rules/54.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/54.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/54.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/54.yml:4-5 Bug: severity label is required (rule/label) +rules/54.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/55.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/55.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/55.yml:1-2 Bug: severity label is required (rule/label) +rules/55.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/55.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/55.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/55.yml:4-5 Bug: severity label is required (rule/label) +rules/55.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/56.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/56.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/56.yml:1-2 Bug: severity label is required (rule/label) +rules/56.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/56.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/56.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/56.yml:4-5 Bug: severity label is required (rule/label) +rules/56.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/57.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/57.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/57.yml:1-2 Bug: severity label is required (rule/label) +rules/57.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/57.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/57.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/57.yml:4-5 Bug: severity label is required (rule/label) +rules/57.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/58.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/58.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/58.yml:1-2 Bug: severity label is required (rule/label) +rules/58.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/58.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/58.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/58.yml:4-5 Bug: severity label is required (rule/label) +rules/58.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/59.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/59.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/59.yml:1-2 Bug: severity label is required (rule/label) +rules/59.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/59.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/59.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/59.yml:4-5 Bug: severity label is required (rule/label) +rules/59.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/6.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/6.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/6.yml:1-2 Bug: severity label is required (rule/label) +rules/6.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/6.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/6.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/6.yml:4-5 Bug: severity label is required (rule/label) +rules/6.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/60.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/60.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/60.yml:1-2 Bug: severity label is required (rule/label) +rules/60.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/60.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/60.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/60.yml:4-5 Bug: severity label is required (rule/label) +rules/60.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/61.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/61.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/61.yml:1-2 Bug: severity label is required (rule/label) +rules/61.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/61.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/61.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/61.yml:4-5 Bug: severity label is required (rule/label) +rules/61.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/62.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/62.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/62.yml:1-2 Bug: severity label is required (rule/label) +rules/62.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/62.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/62.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/62.yml:4-5 Bug: severity label is required (rule/label) +rules/62.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/63.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/63.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/63.yml:1-2 Bug: severity label is required (rule/label) +rules/63.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/63.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/63.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/63.yml:4-5 Bug: severity label is required (rule/label) +rules/63.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/64.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/64.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/64.yml:1-2 Bug: severity label is required (rule/label) +rules/64.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/64.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/64.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/64.yml:4-5 Bug: severity label is required (rule/label) +rules/64.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/65.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/65.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/65.yml:1-2 Bug: severity label is required (rule/label) +rules/65.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/65.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/65.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/65.yml:4-5 Bug: severity label is required (rule/label) +rules/65.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/66.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/66.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/66.yml:1-2 Bug: severity label is required (rule/label) +rules/66.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/66.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/66.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/66.yml:4-5 Bug: severity label is required (rule/label) +rules/66.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/67.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/67.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/67.yml:1-2 Bug: severity label is required (rule/label) +rules/67.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/67.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/67.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/67.yml:4-5 Bug: severity label is required (rule/label) +rules/67.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/68.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/68.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/68.yml:1-2 Bug: severity label is required (rule/label) +rules/68.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/68.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/68.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/68.yml:4-5 Bug: severity label is required (rule/label) +rules/68.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/69.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/69.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/69.yml:1-2 Bug: severity label is required (rule/label) +rules/69.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/69.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/69.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/69.yml:4-5 Bug: severity label is required (rule/label) +rules/69.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/7.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/7.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/7.yml:1-2 Bug: severity label is required (rule/label) +rules/7.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/7.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/7.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/7.yml:4-5 Bug: severity label is required (rule/label) +rules/7.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/70.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/70.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/70.yml:1-2 Bug: severity label is required (rule/label) +rules/70.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/70.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/70.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/70.yml:4-5 Bug: severity label is required (rule/label) +rules/70.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/71.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/71.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/71.yml:1-2 Bug: severity label is required (rule/label) +rules/71.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/71.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/71.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/71.yml:4-5 Bug: severity label is required (rule/label) +rules/71.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/72.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/72.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/72.yml:1-2 Bug: severity label is required (rule/label) +rules/72.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/72.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/72.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/72.yml:4-5 Bug: severity label is required (rule/label) +rules/72.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/73.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/73.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/73.yml:1-2 Bug: severity label is required (rule/label) +rules/73.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/73.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/73.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/73.yml:4-5 Bug: severity label is required (rule/label) +rules/73.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/74.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/74.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/74.yml:1-2 Bug: severity label is required (rule/label) +rules/74.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/74.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/74.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/74.yml:4-5 Bug: severity label is required (rule/label) +rules/74.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/75.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/75.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/75.yml:1-2 Bug: severity label is required (rule/label) +rules/75.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/75.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/75.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/75.yml:4-5 Bug: severity label is required (rule/label) +rules/75.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/76.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/76.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/76.yml:1-2 Bug: severity label is required (rule/label) +rules/76.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/76.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/76.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/76.yml:4-5 Bug: severity label is required (rule/label) +rules/76.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/77.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/77.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/77.yml:1-2 Bug: severity label is required (rule/label) +rules/77.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/77.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/77.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/77.yml:4-5 Bug: severity label is required (rule/label) +rules/77.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/78.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/78.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/78.yml:1-2 Bug: severity label is required (rule/label) +rules/78.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/78.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/78.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/78.yml:4-5 Bug: severity label is required (rule/label) +rules/78.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/79.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/79.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/79.yml:1-2 Bug: severity label is required (rule/label) +rules/79.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/79.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/79.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/79.yml:4-5 Bug: severity label is required (rule/label) +rules/79.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/8.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/8.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/8.yml:1-2 Bug: severity label is required (rule/label) +rules/8.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/8.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/8.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/8.yml:4-5 Bug: severity label is required (rule/label) +rules/8.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/80.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/80.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/80.yml:1-2 Bug: severity label is required (rule/label) +rules/80.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/80.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/80.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/80.yml:4-5 Bug: severity label is required (rule/label) +rules/80.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/81.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/81.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/81.yml:1-2 Bug: severity label is required (rule/label) +rules/81.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/81.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/81.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/81.yml:4-5 Bug: severity label is required (rule/label) +rules/81.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/82.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/82.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/82.yml:1-2 Bug: severity label is required (rule/label) +rules/82.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/82.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/82.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/82.yml:4-5 Bug: severity label is required (rule/label) +rules/82.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/83.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/83.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/83.yml:1-2 Bug: severity label is required (rule/label) +rules/83.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/83.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/83.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/83.yml:4-5 Bug: severity label is required (rule/label) +rules/83.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/84.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/84.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/84.yml:1-2 Bug: severity label is required (rule/label) +rules/84.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/84.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/84.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/84.yml:4-5 Bug: severity label is required (rule/label) +rules/84.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/85.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/85.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/85.yml:1-2 Bug: severity label is required (rule/label) +rules/85.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/85.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/85.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/85.yml:4-5 Bug: severity label is required (rule/label) +rules/85.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/86.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/86.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/86.yml:1-2 Bug: severity label is required (rule/label) +rules/86.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/86.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/86.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/86.yml:4-5 Bug: severity label is required (rule/label) +rules/86.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/87.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/87.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/87.yml:1-2 Bug: severity label is required (rule/label) +rules/87.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/87.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/87.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/87.yml:4-5 Bug: severity label is required (rule/label) +rules/87.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/88.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/88.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/88.yml:1-2 Bug: severity label is required (rule/label) +rules/88.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/88.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/88.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/88.yml:4-5 Bug: severity label is required (rule/label) +rules/88.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/89.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/89.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/89.yml:1-2 Bug: severity label is required (rule/label) +rules/89.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/89.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/89.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/89.yml:4-5 Bug: severity label is required (rule/label) +rules/89.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/9.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/9.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/9.yml:1-2 Bug: severity label is required (rule/label) +rules/9.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/9.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/9.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/9.yml:4-5 Bug: severity label is required (rule/label) +rules/9.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/90.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/90.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/90.yml:1-2 Bug: severity label is required (rule/label) +rules/90.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/90.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/90.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/90.yml:4-5 Bug: severity label is required (rule/label) +rules/90.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/91.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/91.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/91.yml:1-2 Bug: severity label is required (rule/label) +rules/91.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/91.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/91.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/91.yml:4-5 Bug: severity label is required (rule/label) +rules/91.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/92.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/92.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/92.yml:1-2 Bug: severity label is required (rule/label) +rules/92.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/92.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/92.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/92.yml:4-5 Bug: severity label is required (rule/label) +rules/92.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/93.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/93.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/93.yml:1-2 Bug: severity label is required (rule/label) +rules/93.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/93.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/93.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/93.yml:4-5 Bug: severity label is required (rule/label) +rules/93.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/94.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/94.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/94.yml:1-2 Bug: severity label is required (rule/label) +rules/94.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/94.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/94.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/94.yml:4-5 Bug: severity label is required (rule/label) +rules/94.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/95.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/95.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/95.yml:1-2 Bug: severity label is required (rule/label) +rules/95.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/95.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/95.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/95.yml:4-5 Bug: severity label is required (rule/label) +rules/95.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/96.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/96.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/96.yml:1-2 Bug: severity label is required (rule/label) +rules/96.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/96.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/96.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/96.yml:4-5 Bug: severity label is required (rule/label) +rules/96.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/97.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/97.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/97.yml:1-2 Bug: severity label is required (rule/label) +rules/97.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/97.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/97.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/97.yml:4-5 Bug: severity label is required (rule/label) +rules/97.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/98.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/98.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/98.yml:1-2 Bug: severity label is required (rule/label) +rules/98.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/98.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/98.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/98.yml:4-5 Bug: severity label is required (rule/label) +rules/98.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/99.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/99.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/99.yml:1-2 Bug: severity label is required (rule/label) +rules/99.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/99.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/99.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/99.yml:4-5 Bug: severity label is required (rule/label) +rules/99.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/template.yml:1-2 Warning: runbook_url annotation is required (alerts/annotation) +rules/template.yml:1-2 Warning: `runbook_url` annotation is required. (alerts/annotation) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/template.yml:1-2 Bug: severity label is required (rule/label) +rules/template.yml:1-2 Bug: `severity` label is required. (rule/label) 1 | - alert: Test Alert 1 2 | expr: up == 0 -rules/template.yml:4-5 Warning: runbook_url annotation is required (alerts/annotation) +rules/template.yml:4-5 Warning: `runbook_url` annotation is required. (alerts/annotation) 4 | - alert: Test Alert 2 5 | expr: up == 0 -rules/template.yml:4-5 Bug: severity label is required (rule/label) +rules/template.yml:4-5 Bug: `severity` label is required. (rule/label) 4 | - alert: Test Alert 2 5 | expr: up == 0 diff --git a/cmd/pint/tests/0018_match_alerting.txt b/cmd/pint/tests/0018_match_alerting.txt index 1622463e..a77d4db8 100644 --- a/cmd/pint/tests/0018_match_alerting.txt +++ b/cmd/pint/tests/0018_match_alerting.txt @@ -11,10 +11,10 @@ level=DEBUG msg="Found recording rule" path=rules/0001.yml record=colo:recording level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp"] path=rules/0001.yml rule=colo:recording level=DEBUG msg="Found alerting rule" path=rules/0001.yml alert=colo:alerting lines=4-5 level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/aggregate(job:true)"] path=rules/0001.yml rule=colo:alerting -rules/0001.yml:5 Warning: alert query doesn't have any condition, it will always fire if the metric exists (alerts/comparison) +rules/0001.yml:5 Warning: Alert query doesn't have any condition, it will always fire if the metric exists. (alerts/comparison) 5 | expr: sum(bar) without(job) -rules/0001.yml:5 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0001.yml:5 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 5 | expr: sum(bar) without(job) level=INFO msg="Problems found" Warning=2 diff --git a/cmd/pint/tests/0019_match_recording.txt b/cmd/pint/tests/0019_match_recording.txt index 331cfe00..1a85d705 100644 --- a/cmd/pint/tests/0019_match_recording.txt +++ b/cmd/pint/tests/0019_match_recording.txt @@ -11,7 +11,7 @@ level=DEBUG msg="Found recording rule" path=rules/0001.yml record=colo:recording level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/aggregate(job:true)"] path=rules/0001.yml rule=colo:recording level=DEBUG msg="Found alerting rule" path=rules/0001.yml alert=colo:alerting lines=4-5 level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp"] path=rules/0001.yml rule=colo:alerting -rules/0001.yml:2 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0001.yml:2 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 2 | expr: sum(foo) without(job) level=INFO msg="Problems found" Warning=1 diff --git a/cmd/pint/tests/0020_ignore_kind.txt b/cmd/pint/tests/0020_ignore_kind.txt index 8df6b71d..257dd2f1 100644 --- a/cmd/pint/tests/0020_ignore_kind.txt +++ b/cmd/pint/tests/0020_ignore_kind.txt @@ -11,10 +11,10 @@ level=DEBUG msg="Found recording rule" path=rules/0001.yml record=colo:recording level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/aggregate(job:true)"] path=rules/0001.yml rule=colo:recording level=DEBUG msg="Found alerting rule" path=rules/0001.yml alert=colo:alerting lines=7-8 level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp"] path=rules/0001.yml rule=colo:alerting -rules/0001.yml:5 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0001.yml:5 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 5 | expr: sum(foo) without(job) -rules/0001.yml:8 Warning: alert query doesn't have any condition, it will always fire if the metric exists (alerts/comparison) +rules/0001.yml:8 Warning: Alert query doesn't have any condition, it will always fire if the metric exists. (alerts/comparison) 8 | expr: sum(bar) without(job) level=INFO msg="Problems found" Warning=2 diff --git a/cmd/pint/tests/0022_ignore_multi.txt b/cmd/pint/tests/0022_ignore_multi.txt index 60885656..925fb629 100644 --- a/cmd/pint/tests/0022_ignore_multi.txt +++ b/cmd/pint/tests/0022_ignore_multi.txt @@ -5,10 +5,10 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/1.yaml:2 Warning: dropped label should be removed when aggregating "^.+$" rules, remove dropped from by() (promql/aggregate) +rules/1.yaml:2 Warning: `dropped` label should be removed when aggregating `^.+$` rules, remove dropped from `by()`. (promql/aggregate) 2 | expr: sum(errors_total) by(keep,dropped) -rules/1.yaml:5 Warning: keep label is required and should be preserved when aggregating "^.+$" rules, remove keep from without() (promql/aggregate) +rules/1.yaml:5 Warning: `keep` label is required and should be preserved when aggregating `^.+$` rules, remove keep from `without()`. (promql/aggregate) 5 | expr: sum(errors_total) without(keep,dropped) level=INFO msg="Problems found" Warning=2 diff --git a/cmd/pint/tests/0024_color_output.txt b/cmd/pint/tests/0024_color_output.txt index 2307cec7..cebeee11 100644 --- a/cmd/pint/tests/0024_color_output.txt +++ b/cmd/pint/tests/0024_color_output.txt @@ -6,49 +6,49 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/0001.yml:2 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0001.yml:2 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 2 | expr: sum(rate(fl_cf_html_bytes_in[10m])) WITHOUT (colo_id, instance, node_type, region, node_status, job, colo_name) -rules/0001.yml:6 Warning: instance label should be removed when aggregating "^colo(?:_.+)?:.+$" rules, use without(instance, ...) (promql/aggregate) +rules/0001.yml:6 Warning: `instance` label should be removed when aggregating `^colo(?:_.+)?:.+$` rules, use `without(instance, ...)`. (promql/aggregate) 6 | expr: sum(irate(foo[3m])) WITHOUT (colo_id) -rules/0003.yaml:11 Warning: instance label should be removed when aggregating "^colo(?:_.+)?:.+$" rules, use without(instance, ...) (promql/aggregate) +rules/0003.yaml:11 Warning: `instance` label should be removed when aggregating `^colo(?:_.+)?:.+$` rules, use `without(instance, ...)`. (promql/aggregate) 11 | expr: sum(foo) without(job) -rules/0003.yaml:11 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0003.yaml:11 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 11 | expr: sum(foo) without(job) -rules/0003.yaml:14 Fatal: syntax error: unexpected right parenthesis ')' (promql/syntax) +rules/0003.yaml:14 Fatal: Prometheus failed to parse the query with this PromQL error: unexpected right parenthesis ')'. (promql/syntax) 14 | expr: sum(foo) by ()) -rules/0003.yaml:22-25 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0003.yaml:22-25 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 22 | expr: | 23 | sum( 24 | multiline 25 | ) without(job, instance) -rules/0003.yaml:28-31 Warning: instance label should be removed when aggregating "^colo(?:_.+)?:.+$" rules, use without(instance, ...) (promql/aggregate) +rules/0003.yaml:28-31 Warning: `instance` label should be removed when aggregating `^colo(?:_.+)?:.+$` rules, use `without(instance, ...)`. (promql/aggregate) 28 | expr: | 29 | sum(sum) without(job) 30 | + 31 | sum(sum) without(job) -rules/0003.yaml:28-31 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0003.yaml:28-31 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 28 | expr: | 29 | sum(sum) without(job) 30 | + 31 | sum(sum) without(job) -rules/0003.yaml:34-37 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0003.yaml:34-37 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 34 | expr: >- 35 | sum( 36 | multiline2 37 | ) without(job, instance) -rules/0003.yaml:40 Warning: instance label should be removed when aggregating "^colo(?:_.+)?:.+$" rules, remove instance from by() (promql/aggregate) +rules/0003.yaml:40 Warning: `instance` label should be removed when aggregating `^colo(?:_.+)?:.+$` rules, remove instance from `by()`. (promql/aggregate) 40 | expr: sum(byinstance) by(instance) -rules/0003.yaml:40 Warning: job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...) (promql/aggregate) +rules/0003.yaml:40 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`. (promql/aggregate) 40 | expr: sum(byinstance) by(instance) level=INFO msg="Problems found" Fatal=1 Warning=10 diff --git a/cmd/pint/tests/0027_ci_branch.txt b/cmd/pint/tests/0027_ci_branch.txt index 497f00d8..dd1e2b8e 100644 --- a/cmd/pint/tests/0027_ci_branch.txt +++ b/cmd/pint/tests/0027_ci_branch.txt @@ -23,7 +23,7 @@ cmp stderr ../stderr.txt level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check on current git branch using git blame" base=main level=INFO msg="Problems found" Fatal=1 -rules.yml:2 Fatal: syntax error: unexpected identifier "bi" (promql/syntax) +rules.yml:2 Fatal: Prometheus failed to parse the query with this PromQL error: unexpected identifier "bi". (promql/syntax) 2 | expr: sum(foo) bi(job) level=ERROR msg="Fatal error" err="problems found" diff --git a/cmd/pint/tests/0037_disable_checks.txt b/cmd/pint/tests/0037_disable_checks.txt index fbd26caf..e47b4a79 100644 --- a/cmd/pint/tests/0037_disable_checks.txt +++ b/cmd/pint/tests/0037_disable_checks.txt @@ -15,7 +15,7 @@ level=DEBUG msg="Found recording rule" path=rules/0001.yml record=sum-job lines= level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/template","promql/fragile","promql/regexp","promql/vector_matching(prom)","rule/duplicate(prom)","labels/conflict(prom)","promql/aggregate(job:true)"] path=rules/0001.yml rule=sum-job level=DEBUG msg="Found alerting rule" path=rules/0001.yml alert=no-comparison lines=8-9 level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/template","promql/fragile","promql/regexp","promql/vector_matching(prom)","rule/duplicate(prom)","labels/conflict(prom)"] path=rules/0001.yml rule=no-comparison -rules/0001.yml:6 Warning: job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...) (promql/aggregate) +rules/0001.yml:6 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`. (promql/aggregate) 6 | expr: sum(foo) level=INFO msg="Problems found" Warning=1 diff --git a/cmd/pint/tests/0038_disable_checks_regex.txt b/cmd/pint/tests/0038_disable_checks_regex.txt index a06ebf07..e393e872 100644 --- a/cmd/pint/tests/0038_disable_checks_regex.txt +++ b/cmd/pint/tests/0038_disable_checks_regex.txt @@ -5,7 +5,7 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/0001.yml:6 Warning: job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...) (promql/aggregate) +rules/0001.yml:6 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`. (promql/aggregate) 6 | expr: sum(foo) level=INFO msg="Problems found" Warning=1 diff --git a/cmd/pint/tests/0039_prom_selected_path.txt b/cmd/pint/tests/0039_prom_selected_path.txt index bf8d8fe7..4f35a869 100644 --- a/cmd/pint/tests/0039_prom_selected_path.txt +++ b/cmd/pint/tests/0039_prom_selected_path.txt @@ -15,7 +15,7 @@ level=DEBUG msg="Found recording rule" path=rules/0001.yml record=second lines=5 level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/aggregate(job:true)"] path=rules/0001.yml rule=second level=DEBUG msg="Found alerting rule" path=rules/0001.yml alert=third lines=8-9 level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp"] path=rules/0001.yml rule=third -rules/0001.yml:6 Warning: job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...) (promql/aggregate) +rules/0001.yml:6 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`. (promql/aggregate) 6 | expr: sum(bar) level=INFO msg="Problems found" Warning=1 diff --git a/cmd/pint/tests/0040_rule_match_label.txt b/cmd/pint/tests/0040_rule_match_label.txt index cf9b63f9..a555aead 100644 --- a/cmd/pint/tests/0040_rule_match_label.txt +++ b/cmd/pint/tests/0040_rule_match_label.txt @@ -15,10 +15,10 @@ level=DEBUG msg="Found alerting rule" path=rules/rules.yml alert=ignore lines=9- level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp"] path=rules/rules.yml rule=ignore level=DEBUG msg="Found alerting rule" path=rules/rules.yml alert=match lines=12-15 level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/aggregate(job:true)"] path=rules/rules.yml rule=match -rules/rules.yml:5 Warning: job label is required and should be preserved when aggregating "^.*$" rules, use by(job, ...) (promql/aggregate) +rules/rules.yml:5 Warning: `job` label is required and should be preserved when aggregating `^.*$` rules, use `by(job, ...)`. (promql/aggregate) 5 | expr: sum(foo) -rules/rules.yml:13 Warning: job label is required and should be preserved when aggregating "^.*$" rules, use by(job, ...) (promql/aggregate) +rules/rules.yml:13 Warning: `job` label is required and should be preserved when aggregating `^.*$` rules, use `by(job, ...)`. (promql/aggregate) 13 | expr: sum(foo) > 0 level=INFO msg="Problems found" Warning=2 diff --git a/cmd/pint/tests/0042_watch_metrics.txt b/cmd/pint/tests/0042_watch_metrics.txt index 65713bf7..fc4f4ba3 100644 --- a/cmd/pint/tests/0042_watch_metrics.txt +++ b/cmd/pint/tests/0042_watch_metrics.txt @@ -160,9 +160,9 @@ pint_last_run_duration_seconds pint_last_run_time_seconds # HELP pint_problem Prometheus rule problem reported by pint # TYPE pint_problem gauge -pint_problem{filename="rules/alice.yml",kind="alerting",name="broken",owner="alice",problem="syntax error: no arguments for aggregate expression provided",reporter="promql/syntax",severity="fatal"} -pint_problem{filename="rules/bob.yml",kind="alerting",name="broken",owner="bob",problem="syntax error: no arguments for aggregate expression provided",reporter="promql/syntax",severity="fatal"} -pint_problem{filename="rules/unknown.yml",kind="recording",name="broken",owner="",problem="syntax error: no arguments for aggregate expression provided",reporter="promql/syntax",severity="fatal"} +pint_problem{filename="rules/alice.yml",kind="alerting",name="broken",owner="alice",problem="Prometheus failed to parse the query with this PromQL error: no arguments for aggregate expression provided.",reporter="promql/syntax",severity="fatal"} +pint_problem{filename="rules/bob.yml",kind="alerting",name="broken",owner="bob",problem="Prometheus failed to parse the query with this PromQL error: no arguments for aggregate expression provided.",reporter="promql/syntax",severity="fatal"} +pint_problem{filename="rules/unknown.yml",kind="recording",name="broken",owner="",problem="Prometheus failed to parse the query with this PromQL error: no arguments for aggregate expression provided.",reporter="promql/syntax",severity="fatal"} # HELP pint_problems Total number of problems reported by pint # TYPE pint_problems gauge pint_problems diff --git a/cmd/pint/tests/0048_watch_limit.txt b/cmd/pint/tests/0048_watch_limit.txt index dcbe2430..fd03fef0 100644 --- a/cmd/pint/tests/0048_watch_limit.txt +++ b/cmd/pint/tests/0048_watch_limit.txt @@ -32,5 +32,5 @@ rule { } -- metrics.txt -- -pint_problem{filename="rules/1.yml",kind="recording",name="broken",owner="",problem="syntax error: no arguments for aggregate expression provided",reporter="promql/syntax",severity="fatal"} 1 +pint_problem{filename="rules/1.yml",kind="recording",name="broken",owner="",problem="Prometheus failed to parse the query with this PromQL error: no arguments for aggregate expression provided.",reporter="promql/syntax",severity="fatal"} 1 pint_problems 1 diff --git a/cmd/pint/tests/0049_watch_severity_warning.txt b/cmd/pint/tests/0049_watch_severity_warning.txt index b5f4e6d6..404476ac 100644 --- a/cmd/pint/tests/0049_watch_severity_warning.txt +++ b/cmd/pint/tests/0049_watch_severity_warning.txt @@ -32,7 +32,7 @@ rule { } -- metrics.txt -- -pint_problem{filename="rules/1.yml",kind="alerting",name="comparison",owner="",problem="alert query doesn't have any condition, it will always fire if the metric exists",reporter="alerts/comparison",severity="warning"} 1 -pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="job label is required and should be preserved when aggregating \"^.+$\" rules, remove job from without()",reporter="promql/aggregate",severity="warning"} 1 -pint_problem{filename="rules/1.yml",kind="recording",name="broken",owner="",problem="syntax error: no arguments for aggregate expression provided",reporter="promql/syntax",severity="fatal"} 1 +pint_problem{filename="rules/1.yml",kind="alerting",name="comparison",owner="",problem="Alert query doesn't have any condition, it will always fire if the metric exists.",reporter="alerts/comparison",severity="warning"} 1 +pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="`job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`.",reporter="promql/aggregate",severity="warning"} 1 +pint_problem{filename="rules/1.yml",kind="recording",name="broken",owner="",problem="Prometheus failed to parse the query with this PromQL error: no arguments for aggregate expression provided.",reporter="promql/syntax",severity="fatal"} 1 pint_problems 3 diff --git a/cmd/pint/tests/0050_watch_severity_fatal.txt b/cmd/pint/tests/0050_watch_severity_fatal.txt index 768715bb..5eaa5a3c 100644 --- a/cmd/pint/tests/0050_watch_severity_fatal.txt +++ b/cmd/pint/tests/0050_watch_severity_fatal.txt @@ -32,5 +32,5 @@ rule { } -- metrics.txt -- -pint_problem{filename="rules/1.yml",kind="recording",name="broken",owner="",problem="syntax error: no arguments for aggregate expression provided",reporter="promql/syntax",severity="fatal"} 1 +pint_problem{filename="rules/1.yml",kind="recording",name="broken",owner="",problem="Prometheus failed to parse the query with this PromQL error: no arguments for aggregate expression provided.",reporter="promql/syntax",severity="fatal"} 1 pint_problems 1 diff --git a/cmd/pint/tests/0052_match_multiple.txt b/cmd/pint/tests/0052_match_multiple.txt index f8f22579..30679b20 100644 --- a/cmd/pint/tests/0052_match_multiple.txt +++ b/cmd/pint/tests/0052_match_multiple.txt @@ -11,10 +11,10 @@ level=DEBUG msg="Found recording rule" path=rules/0001.yml record=colo:recording level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/aggregate(job:true)"] path=rules/0001.yml rule=colo:recording level=DEBUG msg="Found alerting rule" path=rules/0001.yml alert=colo:alerting lines=7-8 level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/aggregate(job:true)"] path=rules/0001.yml rule=colo:alerting -rules/0001.yml:5 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0001.yml:5 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 5 | expr: sum(foo) without(job) -rules/0001.yml:8 Warning: job label is required and should be preserved when aggregating "^.+$" rules, remove job from without() (promql/aggregate) +rules/0001.yml:8 Warning: `job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`. (promql/aggregate) 8 | expr: sum(bar) without(job) > 0 level=INFO msg="Problems found" Warning=2 diff --git a/cmd/pint/tests/0054_watch_metrics_prometheus.txt b/cmd/pint/tests/0054_watch_metrics_prometheus.txt index cc33e83a..bb58eb1c 100644 --- a/cmd/pint/tests/0054_watch_metrics_prometheus.txt +++ b/cmd/pint/tests/0054_watch_metrics_prometheus.txt @@ -85,19 +85,19 @@ pint_last_run_duration_seconds pint_last_run_time_seconds # HELP pint_problem Prometheus rule problem reported by pint # TYPE pint_problem gauge -pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="couldn't run \"promql/range_query\" checks due to prometheus \"prom2\" at http://127.0.0.1:1054 connection error: connection refused",reporter="promql/range_query",severity="bug"} -pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="couldn't run \"promql/rate\" checks due to prometheus \"prom1\" at http://127.0.0.1:7054 connection error: server_error: server error: 500",reporter="promql/rate",severity="bug"} -pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="couldn't run \"promql/rate\" checks due to prometheus \"prom2\" at http://127.0.0.1:1054 connection error: connection refused",reporter="promql/rate",severity="bug"} -pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="couldn't run \"promql/series\" checks due to prometheus \"prom2\" at http://127.0.0.1:1054 connection error: connection refused",reporter="promql/series",severity="bug"} -pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="prometheus \"prom1\" at http://127.0.0.1:7054 failed with: bad_data: bogus query",reporter="promql/series",severity="bug"} -pint_problem{filename="rules/1.yml",kind="recording",name="broken",owner="",problem="syntax error: no arguments for aggregate expression provided",reporter="promql/syntax",severity="fatal"} -pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="couldn't run \"alerts/external_labels\" checks due to prometheus \"prom1\" at http://127.0.0.1:7054 connection error: server_error: server error: 500",reporter="alerts/external_labels",severity="bug"} -pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="couldn't run \"alerts/external_labels\" checks due to prometheus \"prom2\" at http://127.0.0.1:1054 connection error: connection refused",reporter="alerts/external_labels",severity="bug"} -pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="couldn't run \"promql/range_query\" checks due to prometheus \"prom2\" at http://127.0.0.1:1054 connection error: connection refused",reporter="promql/range_query",severity="bug"} -pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="couldn't run \"promql/rate\" checks due to prometheus \"prom1\" at http://127.0.0.1:7054 connection error: server_error: server error: 500",reporter="promql/rate",severity="bug"} -pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="couldn't run \"promql/rate\" checks due to prometheus \"prom2\" at http://127.0.0.1:1054 connection error: connection refused",reporter="promql/rate",severity="bug"} -pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="couldn't run \"promql/series\" checks due to prometheus \"prom2\" at http://127.0.0.1:1054 connection error: connection refused",reporter="promql/series",severity="bug"} -pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="prometheus \"prom1\" at http://127.0.0.1:7054 failed with: bad_data: bogus query",reporter="promql/series",severity="bug"} +pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="Couldn't run \"promql/range_query\" checks due to `prom2` Prometheus server at http://127.0.0.1:1054 connection error: `connection refused`.",reporter="promql/range_query",severity="bug"} +pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="Couldn't run \"promql/rate\" checks due to `prom1` Prometheus server at http://127.0.0.1:7054 connection error: `server_error: server error: 500`.",reporter="promql/rate",severity="bug"} +pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="Couldn't run \"promql/rate\" checks due to `prom2` Prometheus server at http://127.0.0.1:1054 connection error: `connection refused`.",reporter="promql/rate",severity="bug"} +pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="Couldn't run \"promql/series\" checks due to `prom2` Prometheus server at http://127.0.0.1:1054 connection error: `connection refused`.",reporter="promql/series",severity="bug"} +pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="`prom1` Prometheus server at http://127.0.0.1:7054 failed with: `bad_data: bogus query`.",reporter="promql/series",severity="bug"} +pint_problem{filename="rules/1.yml",kind="recording",name="broken",owner="",problem="Prometheus failed to parse the query with this PromQL error: no arguments for aggregate expression provided.",reporter="promql/syntax",severity="fatal"} +pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="Couldn't run \"alerts/external_labels\" checks due to `prom1` Prometheus server at http://127.0.0.1:7054 connection error: `server_error: server error: 500`.",reporter="alerts/external_labels",severity="bug"} +pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="Couldn't run \"alerts/external_labels\" checks due to `prom2` Prometheus server at http://127.0.0.1:1054 connection error: `connection refused`.",reporter="alerts/external_labels",severity="bug"} +pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="Couldn't run \"promql/range_query\" checks due to `prom2` Prometheus server at http://127.0.0.1:1054 connection error: `connection refused`.",reporter="promql/range_query",severity="bug"} +pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="Couldn't run \"promql/rate\" checks due to `prom1` Prometheus server at http://127.0.0.1:7054 connection error: `server_error: server error: 500`.",reporter="promql/rate",severity="bug"} +pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="Couldn't run \"promql/rate\" checks due to `prom2` Prometheus server at http://127.0.0.1:1054 connection error: `connection refused`.",reporter="promql/rate",severity="bug"} +pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="Couldn't run \"promql/series\" checks due to `prom2` Prometheus server at http://127.0.0.1:1054 connection error: `connection refused`.",reporter="promql/series",severity="bug"} +pint_problem{filename="rules/2.yml",kind="alerting",name="comparison",owner="bob and alice",problem="`prom1` Prometheus server at http://127.0.0.1:7054 failed with: `bad_data: bogus query`.",reporter="promql/series",severity="bug"} # HELP pint_problems Total number of problems reported by pint # TYPE pint_problems gauge pint_problems diff --git a/cmd/pint/tests/0055_prometheus_failover.txt b/cmd/pint/tests/0055_prometheus_failover.txt index 106a225e..00c3503d 100644 --- a/cmd/pint/tests/0055_prometheus_failover.txt +++ b/cmd/pint/tests/0055_prometheus_failover.txt @@ -8,7 +8,7 @@ pint.error --no-color lint rules stderr 'level=ERROR msg="Query returned an error" err="Post \\"http://127.0.0.1:1055/api/v1/query\\": dial tcp 127.0.0.1:1055: connect: connection refused" uri=http://127.0.0.1:1055 query=count\(foo\)' stderr 'level=ERROR msg="Query returned an error" err="failed to query Prometheus config: Get \\"http://127.0.0.1:1055/api/v1/status/config\\": dial tcp 127.0.0.1:1055: connect: connection refused" uri=http://127.0.0.1:1055 query=/api/v1/status/config' ! stderr 'query="count\(foo offset ' -stderr 'rules/1.yml:2 Bug: prometheus "prom" at http://127.0.0.1:7055 didn''t have any series for "foo" metric in the last 1w \(promql/series\)' +stderr 'rules/1.yml:2 Bug: `prom` Prometheus server at http://127.0.0.1:7055 didn''t have any series for `foo` metric in the last 1w. \(promql/series\)' -- rules/1.yml -- - record: aggregate diff --git a/cmd/pint/tests/0057_watch_metrics_prometheus_ignore.txt b/cmd/pint/tests/0057_watch_metrics_prometheus_ignore.txt index 22bdb392..1d8fe214 100644 --- a/cmd/pint/tests/0057_watch_metrics_prometheus_ignore.txt +++ b/cmd/pint/tests/0057_watch_metrics_prometheus_ignore.txt @@ -83,9 +83,9 @@ pint_last_run_duration_seconds pint_last_run_time_seconds # HELP pint_problem Prometheus rule problem reported by pint # TYPE pint_problem gauge -pint_problem{filename="rules/1.yml",kind="alerting",name="comparison",owner="",problem="prometheus \"prom1\" at http://127.0.0.1:7057 failed with: bad_data: bogus query",reporter="promql/series",severity="bug"} -pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="prometheus \"prom1\" at http://127.0.0.1:7057 failed with: bad_data: bogus query",reporter="promql/series",severity="bug"} -pint_problem{filename="rules/1.yml",kind="recording",name="broken",owner="",problem="syntax error: no arguments for aggregate expression provided",reporter="promql/syntax",severity="fatal"} +pint_problem{filename="rules/1.yml",kind="alerting",name="comparison",owner="",problem="`prom1` Prometheus server at http://127.0.0.1:7057 failed with: `bad_data: bogus query`.",reporter="promql/series",severity="bug"} +pint_problem{filename="rules/1.yml",kind="recording",name="aggregate",owner="",problem="`prom1` Prometheus server at http://127.0.0.1:7057 failed with: `bad_data: bogus query`.",reporter="promql/series",severity="bug"} +pint_problem{filename="rules/1.yml",kind="recording",name="broken",owner="",problem="Prometheus failed to parse the query with this PromQL error: no arguments for aggregate expression provided.",reporter="promql/syntax",severity="fatal"} # HELP pint_problems Total number of problems reported by pint # TYPE pint_problems gauge pint_problems diff --git a/cmd/pint/tests/0058_templated_check.txt b/cmd/pint/tests/0058_templated_check.txt index c46549f9..08cf13b6 100644 --- a/cmd/pint/tests/0058_templated_check.txt +++ b/cmd/pint/tests/0058_templated_check.txt @@ -5,12 +5,12 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/0001.yml:4-6 Bug: alert_for annotation is required (alerts/annotation) +rules/0001.yml:4-6 Bug: `alert_for` annotation is required. (alerts/annotation) 4 | - alert: Instance Is Down 2 5 | expr: up == 0 6 | for: 5m -rules/0001.yml:12 Bug: alert_for annotation value must match "^{{ $for }}$" (alerts/annotation) +rules/0001.yml:12 Bug: `alert_for` annotation value must match `^{{ $for }}$`. (alerts/annotation) 12 | alert_for: 4m level=INFO msg="Problems found" Bug=2 diff --git a/cmd/pint/tests/0060_ci_noop.txt b/cmd/pint/tests/0060_ci_noop.txt index 774189ed..81d7e29a 100644 --- a/cmd/pint/tests/0060_ci_noop.txt +++ b/cmd/pint/tests/0060_ci_noop.txt @@ -32,7 +32,7 @@ cmp stderr ../stderr.txt level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check on current git branch using git blame" base=main level=INFO msg="Problems found" Fatal=1 -b.yml:2 Fatal: syntax error: unexpected identifier "bi" (promql/syntax) +b.yml:2 Fatal: Prometheus failed to parse the query with this PromQL error: unexpected identifier "bi". (promql/syntax) 2 | expr: sum(foo) bi() level=ERROR msg="Fatal error" err="problems found" diff --git a/cmd/pint/tests/0066_lint_owner.txt b/cmd/pint/tests/0066_lint_owner.txt index dbbaeb10..e8f1e10b 100644 --- a/cmd/pint/tests/0066_lint_owner.txt +++ b/cmd/pint/tests/0066_lint_owner.txt @@ -5,15 +5,15 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/1.yml:4-5 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules/1.yml:4-5 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 4 | - alert: No Owner 5 | expr: up > 0 -rules/1.yml:9-10 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules/1.yml:9-10 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 9 | - alert: No Owner 10 | expr: up > 0 -rules/3.yml:1-2 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules/3.yml:1-2 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 1 | - alert: No Owner 2 | expr: up{job="foo"} == 0 diff --git a/cmd/pint/tests/0067_relaxed.txt b/cmd/pint/tests/0067_relaxed.txt index 536689cb..85d4613f 100644 --- a/cmd/pint/tests/0067_relaxed.txt +++ b/cmd/pint/tests/0067_relaxed.txt @@ -5,7 +5,7 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/strict.yml:2 Fatal: cannot unmarshal !!seq into rulefmt.RuleGroups (yaml/parse) +rules/strict.yml:2 Fatal: YAML parser returned an error when reading this file: `cannot unmarshal !!seq into rulefmt.RuleGroups`. (yaml/parse) 2 | - alert: No Owner level=INFO msg="Problems found" Fatal=1 diff --git a/cmd/pint/tests/0071_ci_owner.txt b/cmd/pint/tests/0071_ci_owner.txt index b1e2323f..6f015024 100644 --- a/cmd/pint/tests/0071_ci_owner.txt +++ b/cmd/pint/tests/0071_ci_owner.txt @@ -26,14 +26,14 @@ cd .. cmp stderr stderr.txt -- stderr.txt -- -rules.yml:4-5 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules.yml:4-5 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 4 | - alert: rule1 5 | expr: sum(foo) by(job) -rules.yml:5 Warning: alert query doesn't have any condition, it will always fire if the metric exists (alerts/comparison) +rules.yml:5 Warning: Alert query doesn't have any condition, it will always fire if the metric exists. (alerts/comparison) 5 | expr: sum(foo) by(job) -rules.yml:6-7 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules.yml:6-7 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 6 | - alert: rule2 7 | expr: sum(foo) by(job) > 0 diff --git a/cmd/pint/tests/0073_lint_k8s.txt b/cmd/pint/tests/0073_lint_k8s.txt index 06bb32f1..6cb2cf6f 100644 --- a/cmd/pint/tests/0073_lint_k8s.txt +++ b/cmd/pint/tests/0073_lint_k8s.txt @@ -5,26 +5,26 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/1.yml:22-23 Bug: summary annotation is required (alerts/annotation) +rules/1.yml:22-23 Bug: `summary` annotation is required. (alerts/annotation) 22 | - alert: Example_High_Restart_Rate 23 | expr: sum(rate(kube_pod_container_status_restarts_total{namespace="example-app"}[5m])) > ( 3/60 ) -rules/1.yml:22-23 Bug: priority label is required (rule/label) +rules/1.yml:22-23 Bug: `priority` label is required. (rule/label) 22 | - alert: Example_High_Restart_Rate 23 | expr: sum(rate(kube_pod_container_status_restarts_total{namespace="example-app"}[5m])) > ( 3/60 ) -rules/1.yml:24-25 Bug: summary annotation is required (alerts/annotation) +rules/1.yml:24-25 Bug: `summary` annotation is required. (alerts/annotation) 24 | - alert: Invalid Query 25 | expr: sum(rate(kube_pod_container_status_restarts_total{namespace="example-app"}[5m]) / x -rules/1.yml:24-25 Bug: priority label is required (rule/label) +rules/1.yml:24-25 Bug: `priority` label is required. (rule/label) 24 | - alert: Invalid Query 25 | expr: sum(rate(kube_pod_container_status_restarts_total{namespace="example-app"}[5m]) / x -rules/1.yml:25 Fatal: syntax error: no arguments for aggregate expression provided (promql/syntax) +rules/1.yml:25 Fatal: Prometheus failed to parse the query with this PromQL error: no arguments for aggregate expression provided. (promql/syntax) 25 | expr: sum(rate(kube_pod_container_status_restarts_total{namespace="example-app"}[5m]) / x -rules/1.yml:28 Fatal: duplicated expr key (yaml/parse) +rules/1.yml:28 Fatal: This rule is not a valid Prometheus rule: `duplicated expr key`. (yaml/parse) 28 | expr: sum(rate(kube_pod_container_status_restarts_total{namespace="example-app"}[5m])) > ( 3/60 ) level=INFO msg="Problems found" Fatal=2 Bug=4 diff --git a/cmd/pint/tests/0074_strict_error.txt b/cmd/pint/tests/0074_strict_error.txt index f238963e..fa8f3a9b 100644 --- a/cmd/pint/tests/0074_strict_error.txt +++ b/cmd/pint/tests/0074_strict_error.txt @@ -4,7 +4,7 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Finding all rules to check" paths=["rules"] -rules/strict.yml:2 Fatal: field alert not found in type rulefmt.RuleGroup (yaml/parse) +rules/strict.yml:2 Fatal: YAML parser returned an error when reading this file: `field alert not found in type rulefmt.RuleGroup`. (yaml/parse) 2 | - alert: Conntrack_Table_Almost_Full level=INFO msg="Problems found" Fatal=1 diff --git a/cmd/pint/tests/0076_ci_group_errors.txt b/cmd/pint/tests/0076_ci_group_errors.txt index 73f9d7fd..551ee586 100644 --- a/cmd/pint/tests/0076_ci_group_errors.txt +++ b/cmd/pint/tests/0076_ci_group_errors.txt @@ -137,99 +137,99 @@ rule { } -- stderr.txt -- -rules.yml:4-5 Bug: link annotation is required (alerts/annotation) +rules.yml:4-5 Bug: `link` annotation is required. (alerts/annotation) 4 | - alert: syntax error 5 | expr: sum(foo) bar -rules.yml:4-5 Bug: summary annotation is required (alerts/annotation) +rules.yml:4-5 Bug: `summary` annotation is required. (alerts/annotation) 4 | - alert: syntax error 5 | expr: sum(foo) bar -rules.yml:4-5 Bug: component label is required (rule/label) +rules.yml:4-5 Bug: `component` label is required. (rule/label) 4 | - alert: syntax error 5 | expr: sum(foo) bar -rules.yml:4-5 Bug: notify label is required (rule/label) +rules.yml:4-5 Bug: `notify` label is required. (rule/label) 4 | - alert: syntax error 5 | expr: sum(foo) bar -rules.yml:4-5 Bug: priority label is required (rule/label) +rules.yml:4-5 Bug: `priority` label is required. (rule/label) 4 | - alert: syntax error 5 | expr: sum(foo) bar -rules.yml:4-5 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules.yml:4-5 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 4 | - alert: syntax error 5 | expr: sum(foo) bar -rules.yml:5 Fatal: syntax error: unexpected identifier "bar" (promql/syntax) +rules.yml:5 Fatal: Prometheus failed to parse the query with this PromQL error: unexpected identifier "bar". (promql/syntax) 5 | expr: sum(foo) bar -rules.yml:7-8 Bug: link annotation is required (alerts/annotation) +rules.yml:7-8 Bug: `link` annotation is required. (alerts/annotation) 7 | - alert: missing required fields 8 | expr: no_such_metric{job="fake"} -rules.yml:7-8 Bug: summary annotation is required (alerts/annotation) +rules.yml:7-8 Bug: `summary` annotation is required. (alerts/annotation) 7 | - alert: missing required fields 8 | expr: no_such_metric{job="fake"} -rules.yml:7-8 Bug: component label is required (rule/label) +rules.yml:7-8 Bug: `component` label is required. (rule/label) 7 | - alert: missing required fields 8 | expr: no_such_metric{job="fake"} -rules.yml:7-8 Bug: notify label is required (rule/label) +rules.yml:7-8 Bug: `notify` label is required. (rule/label) 7 | - alert: missing required fields 8 | expr: no_such_metric{job="fake"} -rules.yml:7-8 Bug: priority label is required (rule/label) +rules.yml:7-8 Bug: `priority` label is required. (rule/label) 7 | - alert: missing required fields 8 | expr: no_such_metric{job="fake"} -rules.yml:7-8 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules.yml:7-8 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 7 | - alert: missing required fields 8 | expr: no_such_metric{job="fake"} -rules.yml:8 Warning: alert query doesn't have any condition, it will always fire if the metric exists (alerts/comparison) +rules.yml:8 Warning: Alert query doesn't have any condition, it will always fire if the metric exists. (alerts/comparison) 8 | expr: no_such_metric{job="fake"} -rules.yml:10-11 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules.yml:10-11 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 10 | - record: vector_matching 11 | expr: up{job="prometheus"} / prometheus_build_info{job="prometheus"} -rules.yml:13-17 Bug: link annotation is required (alerts/annotation) +rules.yml:13-17 Bug: `link` annotation is required. (alerts/annotation) 13 | - alert: count 14 | expr: up{job="prometheus"} == 0 15 | for: 2m 16 | labels: 17 | notify: blackhole -rules.yml:13-17 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules.yml:13-17 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 13 | - alert: count 14 | expr: up{job="prometheus"} == 0 15 | for: 2m 16 | labels: 17 | notify: blackhole -rules.yml:19-23 Bug: link annotation is required (alerts/annotation) +rules.yml:19-23 Bug: `link` annotation is required. (alerts/annotation) 19 | - alert: for_and_rate 20 | expr: rate(no_such_metric[10s]) 21 | for: 0m 22 | labels: 23 | notify: blackhole -rules.yml:19-23 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules.yml:19-23 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 19 | - alert: for_and_rate 20 | expr: rate(no_such_metric[10s]) 21 | for: 0m 22 | labels: 23 | notify: blackhole -rules.yml:20 Warning: alert query doesn't have any condition, it will always fire if the metric exists (alerts/comparison) +rules.yml:20 Warning: Alert query doesn't have any condition, it will always fire if the metric exists. (alerts/comparison) 20 | expr: rate(no_such_metric[10s]) -rules.yml:21 Information: "0m" is the default value of "for", consider removing this line (alerts/for) +rules.yml:21 Information: `0m` is the default value of `for`, consider removing this redundant line. (alerts/for) 21 | for: 0m -rules.yml:25-30 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules.yml:25-30 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 25 | - alert: template 26 | expr: sum(no_such_metric) by(foo) > 0 27 | labels: @@ -237,102 +237,102 @@ rules.yml:25-30 Bug: rule/owner comments are required in all files, please add a 29 | annotations: 30 | instance: 'sum on {{ $labels.instance }} is {{ $value }}' -rules.yml:26-30 Bug: template is using "instance" label but the query removes it (alerts/template) +rules.yml:26-30 Bug: Template is using `instance` label but the query removes it. (alerts/template) 26 | expr: sum(no_such_metric) by(foo) > 0 .. 30 | instance: 'sum on {{ $labels.instance }} is {{ $value }}' -rules.yml:27-28 Bug: component label is required (rule/label) +rules.yml:27-28 Bug: `component` label is required. (rule/label) 27 | labels: 28 | value: '{{ $value }}' -rules.yml:27-28 Bug: notify label is required (rule/label) +rules.yml:27-28 Bug: `notify` label is required. (rule/label) 27 | labels: 28 | value: '{{ $value }}' -rules.yml:27-28 Bug: priority label is required (rule/label) +rules.yml:27-28 Bug: `priority` label is required. (rule/label) 27 | labels: 28 | value: '{{ $value }}' -rules.yml:28 Bug: using $value in labels will generate a new alert on every value change, move it to annotations (alerts/template) +rules.yml:28 Bug: Using `$value` in labels will generate a new alert on every value change, move it to annotations. (alerts/template) 28 | value: '{{ $value }}' -rules.yml:29-30 Bug: link annotation is required (alerts/annotation) +rules.yml:29-30 Bug: `link` annotation is required. (alerts/annotation) 29 | annotations: 30 | instance: 'sum on {{ $labels.instance }} is {{ $value }}' -rules.yml:29-30 Bug: summary annotation is required (alerts/annotation) +rules.yml:29-30 Bug: `summary` annotation is required. (alerts/annotation) 29 | annotations: 30 | instance: 'sum on {{ $labels.instance }} is {{ $value }}' -rules.yml:32-33 Bug: link annotation is required (alerts/annotation) +rules.yml:32-33 Bug: `link` annotation is required. (alerts/annotation) 32 | - alert: fragile 33 | expr: errors / sum(requests) without(rack) -rules.yml:32-33 Bug: summary annotation is required (alerts/annotation) +rules.yml:32-33 Bug: `summary` annotation is required. (alerts/annotation) 32 | - alert: fragile 33 | expr: errors / sum(requests) without(rack) -rules.yml:32-33 Bug: component label is required (rule/label) +rules.yml:32-33 Bug: `component` label is required. (rule/label) 32 | - alert: fragile 33 | expr: errors / sum(requests) without(rack) -rules.yml:32-33 Bug: notify label is required (rule/label) +rules.yml:32-33 Bug: `notify` label is required. (rule/label) 32 | - alert: fragile 33 | expr: errors / sum(requests) without(rack) -rules.yml:32-33 Bug: priority label is required (rule/label) +rules.yml:32-33 Bug: `priority` label is required. (rule/label) 32 | - alert: fragile 33 | expr: errors / sum(requests) without(rack) -rules.yml:32-33 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules.yml:32-33 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 32 | - alert: fragile 33 | expr: errors / sum(requests) without(rack) -rules.yml:33 Warning: alert query doesn't have any condition, it will always fire if the metric exists (alerts/comparison) +rules.yml:33 Warning: Alert query doesn't have any condition, it will always fire if the metric exists. (alerts/comparison) 33 | expr: errors / sum(requests) without(rack) -rules.yml:33 Warning: aggregation using without() can be fragile when used inside binary expression because both sides must have identical sets of labels to produce any results, adding or removing labels to metrics used here can easily break the query, consider aggregating using by() to ensure consistent labels (promql/fragile) +rules.yml:33 Warning: Aggregation using `without()` can be fragile when used inside binary expression because both sides must have identical sets of labels to produce any results, adding or removing labels to metrics used here can easily break the query, consider aggregating using `by()` to ensure consistent labels. (promql/fragile) 33 | expr: errors / sum(requests) without(rack) -rules.yml:35-36 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules.yml:35-36 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 35 | - record: regexp 36 | expr: sum(no_such_metric{job=~"fake"}) -rules.yml:36 Bug: job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...) (promql/aggregate) +rules.yml:36 Bug: `job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`. (promql/aggregate) 36 | expr: sum(no_such_metric{job=~"fake"}) -rules.yml:36 Bug: unnecessary regexp match on static string job=~"fake", use job="fake" instead (promql/regexp) +rules.yml:36 Bug: Unnecessary regexp match on static string `job=~"fake"`, use `job="fake"` instead. (promql/regexp) 36 | expr: sum(no_such_metric{job=~"fake"}) -rules.yml:38-39 Bug: link annotation is required (alerts/annotation) +rules.yml:38-39 Bug: `link` annotation is required. (alerts/annotation) 38 | - alert: dups 39 | expr: errors / sum(requests) without(rack) -rules.yml:38-39 Bug: summary annotation is required (alerts/annotation) +rules.yml:38-39 Bug: `summary` annotation is required. (alerts/annotation) 38 | - alert: dups 39 | expr: errors / sum(requests) without(rack) -rules.yml:38-39 Bug: component label is required (rule/label) +rules.yml:38-39 Bug: `component` label is required. (rule/label) 38 | - alert: dups 39 | expr: errors / sum(requests) without(rack) -rules.yml:38-39 Bug: notify label is required (rule/label) +rules.yml:38-39 Bug: `notify` label is required. (rule/label) 38 | - alert: dups 39 | expr: errors / sum(requests) without(rack) -rules.yml:38-39 Bug: priority label is required (rule/label) +rules.yml:38-39 Bug: `priority` label is required. (rule/label) 38 | - alert: dups 39 | expr: errors / sum(requests) without(rack) -rules.yml:38-39 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules.yml:38-39 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 38 | - alert: dups 39 | expr: errors / sum(requests) without(rack) -rules.yml:39 Warning: alert query doesn't have any condition, it will always fire if the metric exists (alerts/comparison) +rules.yml:39 Warning: Alert query doesn't have any condition, it will always fire if the metric exists. (alerts/comparison) 39 | expr: errors / sum(requests) without(rack) -rules.yml:39 Warning: aggregation using without() can be fragile when used inside binary expression because both sides must have identical sets of labels to produce any results, adding or removing labels to metrics used here can easily break the query, consider aggregating using by() to ensure consistent labels (promql/fragile) +rules.yml:39 Warning: Aggregation using `without()` can be fragile when used inside binary expression because both sides must have identical sets of labels to produce any results, adding or removing labels to metrics used here can easily break the query, consider aggregating using `by()` to ensure consistent labels. (promql/fragile) 39 | expr: errors / sum(requests) without(rack) level=ERROR msg="Fatal error" err="submitting reports: fatal error(s) reported" diff --git a/cmd/pint/tests/0077_strict_error_owner.txt b/cmd/pint/tests/0077_strict_error_owner.txt index b1caf27c..31dac220 100644 --- a/cmd/pint/tests/0077_strict_error_owner.txt +++ b/cmd/pint/tests/0077_strict_error_owner.txt @@ -4,10 +4,10 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Finding all rules to check" paths=["rules"] -rules/strict.yml:4 Fatal: "foo bar": invalid field 'annotations' in recording rule (yaml/parse) +rules/strict.yml:4 Fatal: YAML parser returned an error when reading this file: `"foo bar": invalid field 'annotations' in recording rule`. (yaml/parse) 4 | - record: foo bar -rules/strict.yml:4 Fatal: "foo bar": invalid recording rule name: foo bar (yaml/parse) +rules/strict.yml:4 Fatal: YAML parser returned an error when reading this file: `"foo bar": invalid recording rule name: foo bar`. (yaml/parse) 4 | - record: foo bar level=INFO msg="Problems found" Fatal=2 diff --git a/cmd/pint/tests/0078_repeated_group.txt b/cmd/pint/tests/0078_repeated_group.txt index 73c22da4..ce84f272 100644 --- a/cmd/pint/tests/0078_repeated_group.txt +++ b/cmd/pint/tests/0078_repeated_group.txt @@ -4,7 +4,7 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Finding all rules to check" paths=["rules"] -rules/strict.yml:4 Fatal: groupname: "foo" is repeated in the same file (yaml/parse) +rules/strict.yml:4 Fatal: YAML parser returned an error when reading this file: `groupname: "foo" is repeated in the same file`. (yaml/parse) 4 | - name: foo level=INFO msg="Problems found" Fatal=1 diff --git a/cmd/pint/tests/0080_lint_online.txt b/cmd/pint/tests/0080_lint_online.txt index 6e174936..0c69ba19 100644 --- a/cmd/pint/tests/0080_lint_online.txt +++ b/cmd/pint/tests/0080_lint_online.txt @@ -15,10 +15,10 @@ level=INFO msg="Finding all rules to check" paths=["rules"] level=INFO msg="Configured new Prometheus server" name=prom1 uris=1 tags=[] include=[] exclude=[] level=WARN msg="No results for Prometheus uptime metric, you might have set uptime config option to a missing metric, please check your config" name=prom1 metric=prometheus_ready level=WARN msg="Using dummy Prometheus uptime metric results with no gaps" name=prom1 metric=prometheus_ready -rules/1.yml:2 Warning: http_errors_total[2d] selector is trying to query Prometheus for 2d worth of metrics, but prometheus "prom1" at http://127.0.0.1:7080 is configured to only keep 1d of metrics history (promql/range_query) +rules/1.yml:2 Warning: `http_errors_total[2d]` selector is trying to query Prometheus for 2d worth of metrics, but `prom1` Prometheus server at http://127.0.0.1:7080 is configured to only keep 1d of metrics history. (promql/range_query) 2 | expr: rate(http_errors_total[2d]) > 0 -rules/1.yml:2 Warning: prometheus "prom1" at http://127.0.0.1:7080 didn't have any series for "http_errors_total" metric in the last 1w. Metric name "http_errors_total" matches "promql/series" check ignore regexp "^.+_errors_.+$" (promql/series) +rules/1.yml:2 Warning: `prom1` Prometheus server at http://127.0.0.1:7080 didn't have any series for `http_errors_total` metric in the last 1w. Metric name `http_errors_total` matches `promql/series` check ignore regexp `^.+_errors_.+$`. (promql/series) 2 | expr: rate(http_errors_total[2d]) > 0 level=INFO msg="Problems found" Warning=2 diff --git a/cmd/pint/tests/0081_rulefmt.txt b/cmd/pint/tests/0081_rulefmt.txt index 5b2393fd..6e581d3c 100644 --- a/cmd/pint/tests/0081_rulefmt.txt +++ b/cmd/pint/tests/0081_rulefmt.txt @@ -4,7 +4,7 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Finding all rules to check" paths=["rules"] -rules/strict.yml:4 Fatal: missing expr key (yaml/parse) +rules/strict.yml:4 Fatal: This rule is not a valid Prometheus rule: `missing expr key`. (yaml/parse) 4 | - record: foo level=INFO msg="Problems found" Fatal=1 diff --git a/cmd/pint/tests/0086_rulefmt_ignored_errors.txt b/cmd/pint/tests/0086_rulefmt_ignored_errors.txt index a0674f06..4a1d2efd 100644 --- a/cmd/pint/tests/0086_rulefmt_ignored_errors.txt +++ b/cmd/pint/tests/0086_rulefmt_ignored_errors.txt @@ -4,19 +4,19 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Finding all rules to check" paths=["rules"] -rules/strict.yml:4 Fatal: incomplete rule, no alert or record key (yaml/parse) +rules/strict.yml:4 Fatal: This rule is not a valid Prometheus rule: `incomplete rule, no alert or record key`. (yaml/parse) 4 | - expr: MissingAlertOrRecord -rules/strict.yml:7 Fatal: expr value cannot be empty (yaml/parse) +rules/strict.yml:7 Fatal: This rule is not a valid Prometheus rule: `expr value cannot be empty`. (yaml/parse) 7 | expr: -rules/strict.yml:10 Fatal: syntax error: unknown function with name "sumz" (promql/syntax) +rules/strict.yml:10 Fatal: Prometheus failed to parse the query with this PromQL error: unknown function with name "sumz". (promql/syntax) 10 | expr: sumz(0) -rules/strict.yml:15 Fatal: template parse error: function "bogus" not defined (alerts/template) +rules/strict.yml:15 Fatal: Template failed to parse with this error: `function "bogus" not defined`. (alerts/template) 15 | dashboard: '{{ bogus }}' -rules/strict.yml:20 Fatal: template parse error: function "bogus" not defined (alerts/template) +rules/strict.yml:20 Fatal: Template failed to parse with this error: `function "bogus" not defined`. (alerts/template) 20 | dashboard: '{{ bogus }}' level=INFO msg="Problems found" Fatal=5 diff --git a/cmd/pint/tests/0087_dedup.txt b/cmd/pint/tests/0087_dedup.txt index 805dfbf1..737ebc68 100644 --- a/cmd/pint/tests/0087_dedup.txt +++ b/cmd/pint/tests/0087_dedup.txt @@ -4,20 +4,20 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Finding all rules to check" paths=["rules"] -rules/01.yml:5 Warning: alert query doesn't have any condition, it will always fire if the metric exists (alerts/comparison) +rules/01.yml:5 Warning: Alert query doesn't have any condition, it will always fire if the metric exists. (alerts/comparison) 5 | expr: sum(up{job="bar"}) / sum(foo) / sum(bar) -rules/01.yml:5-12 Bug: template is using "cluster" label but the query removes it (alerts/template) +rules/01.yml:5-12 Bug: Template is using `cluster` label but the query removes it. (alerts/template) 5 | expr: sum(up{job="bar"}) / sum(foo) / sum(bar) .. 12 | summary: "Server {{ $labels.instance }} in cluster {{ $labels.cluster }} has gone down" -rules/01.yml:5-13 Bug: template is using "cluster" label but the query removes it (alerts/template) +rules/01.yml:5-13 Bug: Template is using `cluster` label but the query removes it. (alerts/template) 5 | expr: sum(up{job="bar"}) / sum(foo) / sum(bar) .. 13 | dashboard: "https://grafana.example.com/dashboard?var-cluster={{ $labels.cluster }}&var-instance={{ $labels.cluster }}" -rules/01.yml:5-12 Bug: template is using "instance" label but the query removes it (alerts/template) +rules/01.yml:5-12 Bug: Template is using `instance` label but the query removes it. (alerts/template) 5 | expr: sum(up{job="bar"}) / sum(foo) / sum(bar) .. 12 | summary: "Server {{ $labels.instance }} in cluster {{ $labels.cluster }} has gone down" diff --git a/cmd/pint/tests/0088_rule_link.txt b/cmd/pint/tests/0088_rule_link.txt index bea0aff5..1ef5b3f5 100644 --- a/cmd/pint/tests/0088_rule_link.txt +++ b/cmd/pint/tests/0088_rule_link.txt @@ -12,13 +12,13 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/1.yml:10 Information: GET request for http://127.0.0.1:7088/404 returned invalid status code: 404 Not Found (rule/link) +rules/1.yml:10 Information: GET request for http://127.0.0.1:7088/404 returned invalid status code: `404 Not Found`. (rule/link) 10 | r404: http://127.0.0.1:7088/404 -rules/1.yml:11 Information: GET request for http://127.0.0.1:7088/500 returned invalid status code: 500 Internal Server Error (rule/link) +rules/1.yml:11 Information: GET request for http://127.0.0.1:7088/500 returned invalid status code: `500 Internal Server Error`. (rule/link) 11 | r500: http://127.0.0.1:7088/500 -rules/1.yml:13 Warning: GET request for http://127.0.0.1:7088/redirect/404 returned invalid status code: 404 Not Found (rule/link) +rules/1.yml:13 Warning: GET request for http://127.0.0.1:7088/redirect/404 returned invalid status code: `404 Not Found`. (rule/link) 13 | rewrite: https://xxxx.example.com/redirect/404 level=INFO msg="Problems found" Warning=1 Information=2 diff --git a/cmd/pint/tests/0090_lint_min_severity_info.txt b/cmd/pint/tests/0090_lint_min_severity_info.txt index ce90e528..60b2653c 100644 --- a/cmd/pint/tests/0090_lint_min_severity_info.txt +++ b/cmd/pint/tests/0090_lint_min_severity_info.txt @@ -4,7 +4,7 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Finding all rules to check" paths=["rules"] -rules/0001.yml:5-7 Information: using the value of rate(errors[2m]) inside this annotation might be hard to read, consider using one of humanize template functions to make it more human friendly (alerts/template) +rules/0001.yml:5-7 Information: Using the value of `rate(errors[2m])` inside this annotation might be hard to read, consider using one of humanize template functions to make it more human friendly. (alerts/template) 5 | expr: rate(errors[2m]) > 0 . 7 | summary: 'error rate: {{ $value }}' diff --git a/cmd/pint/tests/0094_rule_file_symlink_bb.txt b/cmd/pint/tests/0094_rule_file_symlink_bb.txt index f2867134..77d8e62f 100644 --- a/cmd/pint/tests/0094_rule_file_symlink_bb.txt +++ b/cmd/pint/tests/0094_rule_file_symlink_bb.txt @@ -51,12 +51,12 @@ stderr 'path=double.yml rule=rule2' stderr 'level=INFO msg="Problems found" Bug=4' stderr 'result":"FAIL"' -! stderr '^rules.yml:5 Bug: duration for rate' -! stderr '^rules.yml:7 Bug: duration for rate' -stderr 'symlink.yml ~> rules.yml:5 Bug: duration for rate' -stderr 'symlink.yml ~> rules.yml:7 Bug: duration for rate' -stderr 'double.yml ~> rules.yml:5 Bug: duration for rate' -stderr 'double.yml ~> rules.yml:7 Bug: duration for rate' +! stderr '^rules.yml:5 Bug: Duration for `rate' +! stderr '^rules.yml:7 Bug: Duration for `rate' +stderr 'symlink.yml ~> rules.yml:5 Bug: Duration for `rate' +stderr 'symlink.yml ~> rules.yml:7 Bug: Duration for `rate' +stderr 'double.yml ~> rules.yml:5 Bug: Duration for `rate' +stderr 'double.yml ~> rules.yml:7 Bug: Duration for `rate' stderr '{"path":"rules.yml","line":5,' stderr '{"path":"rules.yml","line":7,' diff --git a/cmd/pint/tests/0108_rule_duplicate.txt b/cmd/pint/tests/0108_rule_duplicate.txt index 743468eb..082bd458 100644 --- a/cmd/pint/tests/0108_rule_duplicate.txt +++ b/cmd/pint/tests/0108_rule_duplicate.txt @@ -11,33 +11,33 @@ level=ERROR msg="Query returned an error" err="failed to query Prometheus config level=ERROR msg="Query returned an error" err="failed to query Prometheus config: Get \"http://127.0.0.1:7108/api/v1/status/config\": dial tcp 127.0.0.1:7108: connect: connection refused" uri=http://127.0.0.1:7108 query=/api/v1/status/config level=ERROR msg="Query returned an error" err="failed to query Prometheus config: Get \"http://127.0.0.1:7108/api/v1/status/config\": dial tcp 127.0.0.1:7108: connect: connection refused" uri=http://127.0.0.1:7108 query=/api/v1/status/config level=ERROR msg="Query returned an error" err="failed to query Prometheus config: Get \"http://127.0.0.1:7108/api/v1/status/config\": dial tcp 127.0.0.1:7108: connect: connection refused" uri=http://127.0.0.1:7108 query=/api/v1/status/config -rules/0001.yml:1-2 Bug: duplicated rule, identical rule found at rules/0002.yml:1 (rule/duplicate) +rules/0001.yml:1-2 Bug: Duplicated rule, identical rule found at rules/0002.yml:1. (rule/duplicate) 1 | - record: "colo:duplicate" 2 | expr: sum(foo) without(job) -rules/0001.yml:7-8 Bug: couldn't run "labels/conflict" checks due to prometheus "prom" at http://127.0.0.1:7108 connection error: connection refused (labels/conflict) +rules/0001.yml:7-8 Bug: Couldn't run "labels/conflict" checks due to `prom` Prometheus server at http://127.0.0.1:7108 connection error: `connection refused`. (labels/conflict) 7 | labels: 8 | file: a -rules/0001.yml:9-12 Bug: duplicated rule, identical rule found at rules/0002.yml:11 (rule/duplicate) +rules/0001.yml:9-12 Bug: Duplicated rule, identical rule found at rules/0002.yml:11. (rule/duplicate) 9 | - record: "colo:labels:equal" 10 | expr: sum(foo) without(job) 11 | labels: 12 | same: yes -rules/0001.yml:11-12 Bug: couldn't run "labels/conflict" checks due to prometheus "prom" at http://127.0.0.1:7108 connection error: connection refused (labels/conflict) +rules/0001.yml:11-12 Bug: Couldn't run "labels/conflict" checks due to `prom` Prometheus server at http://127.0.0.1:7108 connection error: `connection refused`. (labels/conflict) 11 | labels: 12 | same: yes -rules/0002.yml:5-6 Bug: couldn't run "labels/conflict" checks due to prometheus "prom" at http://127.0.0.1:7108 connection error: connection refused (labels/conflict) +rules/0002.yml:5-6 Bug: Couldn't run "labels/conflict" checks due to `prom` Prometheus server at http://127.0.0.1:7108 connection error: `connection refused`. (labels/conflict) 5 | labels: 6 | empty: nope -rules/0002.yml:9-10 Bug: couldn't run "labels/conflict" checks due to prometheus "prom" at http://127.0.0.1:7108 connection error: connection refused (labels/conflict) +rules/0002.yml:9-10 Bug: Couldn't run "labels/conflict" checks due to `prom` Prometheus server at http://127.0.0.1:7108 connection error: `connection refused`. (labels/conflict) 9 | labels: 10 | file: b -rules/0002.yml:13-14 Bug: couldn't run "labels/conflict" checks due to prometheus "prom" at http://127.0.0.1:7108 connection error: connection refused (labels/conflict) +rules/0002.yml:13-14 Bug: Couldn't run "labels/conflict" checks due to `prom` Prometheus server at http://127.0.0.1:7108 connection error: `connection refused`. (labels/conflict) 13 | labels: 14 | same: yes diff --git a/cmd/pint/tests/0112_expired_snooze.txt b/cmd/pint/tests/0112_expired_snooze.txt index 727fcb91..2e37b927 100644 --- a/cmd/pint/tests/0112_expired_snooze.txt +++ b/cmd/pint/tests/0112_expired_snooze.txt @@ -9,7 +9,7 @@ level=DEBUG msg="File parsed" path=rules/0001.yml rules=1 level=DEBUG msg="Generated all Prometheus servers" count=0 level=DEBUG msg="Found recording rule" path=rules/0001.yml record=sum-job lines=2-3 level=DEBUG msg="Configured checks for rule" enabled=["promql/syntax","alerts/for","alerts/comparison","alerts/template","promql/fragile","promql/regexp","promql/aggregate(job:true)"] path=rules/0001.yml rule=sum-job -rules/0001.yml:3 Bug: job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...) (promql/aggregate) +rules/0001.yml:3 Bug: `job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`. (promql/aggregate) 3 | expr: sum(foo) level=INFO msg="Problems found" Bug=1 diff --git a/cmd/pint/tests/0121_rule_for.txt b/cmd/pint/tests/0121_rule_for.txt index 097a913f..96b4b529 100644 --- a/cmd/pint/tests/0121_rule_for.txt +++ b/cmd/pint/tests/0121_rule_for.txt @@ -5,13 +5,13 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/0001.yml:6 Bug: this alert rule must have a 'for' field with a minimum duration of 5m (rule/for) +rules/0001.yml:6 Bug: This alert rule must have a `for` field with a minimum duration of 5m. (rule/for) 6 | for: 3m -rules/0001.yml:9 Bug: this alert rule must have a 'for' field with a maximum duration of 10m (rule/for) +rules/0001.yml:9 Bug: This alert rule must have a `for` field with a maximum duration of 10m. (rule/for) 9 | for: 13m -rules/0001.yml:10 Bug: this alert rule must have a 'for' field with a minimum duration of 5m (rule/for) +rules/0001.yml:10 Bug: This alert rule must have a `for` field with a minimum duration of 5m. (rule/for) 10 | - alert: none level=INFO msg="Problems found" Bug=3 diff --git a/cmd/pint/tests/0122_lint_owner_allowed.txt b/cmd/pint/tests/0122_lint_owner_allowed.txt index 3c9312db..be82c42c 100644 --- a/cmd/pint/tests/0122_lint_owner_allowed.txt +++ b/cmd/pint/tests/0122_lint_owner_allowed.txt @@ -5,11 +5,11 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/1.yml:4-5 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules/1.yml:4-5 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 4 | - alert: No Owner 5 | expr: up > 0 -rules/1.yml:7-8 Bug: this rule is set as owned by "bob" but "bob" doesn't match any of the allowed owner values (rule/owner) +rules/1.yml:7-8 Bug: This rule is set as owned by `bob` but `bob` doesn't match any of the allowed owner values. (rule/owner) 7 | - alert: Invalid 8 | expr: up == 0 diff --git a/cmd/pint/tests/0123_ci_owner_allowed.txt b/cmd/pint/tests/0123_ci_owner_allowed.txt index dfea7de9..2fd6f720 100644 --- a/cmd/pint/tests/0123_ci_owner_allowed.txt +++ b/cmd/pint/tests/0123_ci_owner_allowed.txt @@ -26,11 +26,11 @@ cd .. cmp stderr stderr.txt -- stderr.txt -- -rules.yml:4-5 Bug: rule/owner comments are required in all files, please add a "# pint file/owner $owner" somewhere in this file and/or "# pint rule/owner $owner" on top of each rule (rule/owner) +rules.yml:4-5 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 4 | - alert: No Owner 5 | expr: up > 0 -rules.yml:7-8 Bug: this rule is set as owned by "bob" but "bob" doesn't match any of the allowed owner values (rule/owner) +rules.yml:7-8 Bug: This rule is set as owned by `bob` but `bob` doesn't match any of the allowed owner values. (rule/owner) 7 | - alert: Invalid 8 | expr: up == 0 diff --git a/cmd/pint/tests/0124_ci_base_branch_flag.txt b/cmd/pint/tests/0124_ci_base_branch_flag.txt index 53b1a904..8545e5a0 100644 --- a/cmd/pint/tests/0124_ci_base_branch_flag.txt +++ b/cmd/pint/tests/0124_ci_base_branch_flag.txt @@ -23,7 +23,7 @@ cmp stderr ../stderr.txt level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check on current git branch using git blame" base=main level=INFO msg="Problems found" Fatal=1 -rules.yml:2 Fatal: syntax error: unexpected identifier "bi" (promql/syntax) +rules.yml:2 Fatal: Prometheus failed to parse the query with this PromQL error: unexpected identifier "bi". (promql/syntax) 2 | expr: sum(foo) bi(job) level=ERROR msg="Fatal error" err="problems found" diff --git a/cmd/pint/tests/0125_lint_fail_on_warning.txt b/cmd/pint/tests/0125_lint_fail_on_warning.txt index 96ca2bc8..a6458d30 100644 --- a/cmd/pint/tests/0125_lint_fail_on_warning.txt +++ b/cmd/pint/tests/0125_lint_fail_on_warning.txt @@ -11,10 +11,10 @@ groups: -- stderr.txt -- level=INFO msg="Finding all rules to check" paths=["rules"] -rules/0001.yml:5 Warning: alert query doesn't have any condition, it will always fire if the metric exists (alerts/comparison) +rules/0001.yml:5 Warning: Alert query doesn't have any condition, it will always fire if the metric exists. (alerts/comparison) 5 | expr: up{job=~"xxx"} -rules/0001.yml:5 Bug: unnecessary regexp match on static string job=~"xxx", use job="xxx" instead (promql/regexp) +rules/0001.yml:5 Bug: Unnecessary regexp match on static string `job=~"xxx"`, use `job="xxx"` instead. (promql/regexp) 5 | expr: up{job=~"xxx"} level=INFO msg="Problems found" Bug=1 Warning=1 diff --git a/cmd/pint/tests/0137_annotation_regex_key_fail.txt b/cmd/pint/tests/0137_annotation_regex_key_fail.txt index 58c09199..4f40260b 100644 --- a/cmd/pint/tests/0137_annotation_regex_key_fail.txt +++ b/cmd/pint/tests/0137_annotation_regex_key_fail.txt @@ -5,7 +5,7 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/0001.yml:4 Bug: annotation_.* annotation value must match "^bar$" (alerts/annotation) +rules/0001.yml:4 Bug: `annotation_.*` annotation value must match `^bar$`. (alerts/annotation) 4 | annotation_foo: foo level=INFO msg="Problems found" Bug=1 diff --git a/cmd/pint/tests/0138_annoation_regex_key_required.txt b/cmd/pint/tests/0138_annoation_regex_key_required.txt index 5aa4060d..2ce32cfc 100644 --- a/cmd/pint/tests/0138_annoation_regex_key_required.txt +++ b/cmd/pint/tests/0138_annoation_regex_key_required.txt @@ -5,7 +5,7 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/0001.yml:1-2 Bug: annotation_.* annotation is required (alerts/annotation) +rules/0001.yml:1-2 Bug: `annotation_.*` annotation is required. (alerts/annotation) 1 | - alert: Instance Is Down 1 2 | expr: up == 0 diff --git a/cmd/pint/tests/0141_empty_keys.txt b/cmd/pint/tests/0141_empty_keys.txt index 4efff815..fdeed374 100644 --- a/cmd/pint/tests/0141_empty_keys.txt +++ b/cmd/pint/tests/0141_empty_keys.txt @@ -4,22 +4,22 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Finding all rules to check" paths=["rules.yml"] -rules.yml:4 Fatal: record value cannot be empty (yaml/parse) +rules.yml:4 Fatal: This rule is not a valid Prometheus rule: `record value cannot be empty`. (yaml/parse) 4 | - record: -rules.yml:6 Fatal: record value cannot be empty (yaml/parse) +rules.yml:6 Fatal: This rule is not a valid Prometheus rule: `record value cannot be empty`. (yaml/parse) 6 | - record: -rules.yml:9 Fatal: expr value cannot be empty (yaml/parse) +rules.yml:9 Fatal: This rule is not a valid Prometheus rule: `expr value cannot be empty`. (yaml/parse) 9 | expr: -rules.yml:10 Fatal: alert value cannot be empty (yaml/parse) +rules.yml:10 Fatal: This rule is not a valid Prometheus rule: `alert value cannot be empty`. (yaml/parse) 10 | - alert: -rules.yml:12 Fatal: alert value cannot be empty (yaml/parse) +rules.yml:12 Fatal: This rule is not a valid Prometheus rule: `alert value cannot be empty`. (yaml/parse) 12 | - alert: -rules.yml:15 Fatal: expr value cannot be empty (yaml/parse) +rules.yml:15 Fatal: This rule is not a valid Prometheus rule: `expr value cannot be empty`. (yaml/parse) 15 | expr: level=INFO msg="Problems found" Fatal=6 diff --git a/cmd/pint/tests/0143_keep_firing_for.txt b/cmd/pint/tests/0143_keep_firing_for.txt index be40edf4..14c2cea6 100644 --- a/cmd/pint/tests/0143_keep_firing_for.txt +++ b/cmd/pint/tests/0143_keep_firing_for.txt @@ -5,13 +5,13 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -rules/0001.yml:6 Bug: this alert rule must have a 'keep_firing_for' field with a minimum duration of 5m (rule/for) +rules/0001.yml:6 Bug: This alert rule must have a `keep_firing_for` field with a minimum duration of 5m. (rule/for) 6 | keep_firing_for: 3m -rules/0001.yml:9 Bug: this alert rule must have a 'keep_firing_for' field with a maximum duration of 10m (rule/for) +rules/0001.yml:9 Bug: This alert rule must have a `keep_firing_for` field with a maximum duration of 10m. (rule/for) 9 | keep_firing_for: 13m -rules/0001.yml:10 Bug: this alert rule must have a 'keep_firing_for' field with a minimum duration of 5m (rule/for) +rules/0001.yml:10 Bug: This alert rule must have a `keep_firing_for` field with a minimum duration of 5m. (rule/for) 10 | - alert: none level=INFO msg="Problems found" Bug=3 diff --git a/cmd/pint/tests/0157_series_other_servers.txt b/cmd/pint/tests/0157_series_other_servers.txt index a67ea8bb..0fe95bea 100644 --- a/cmd/pint/tests/0157_series_other_servers.txt +++ b/cmd/pint/tests/0157_series_other_servers.txt @@ -19,7 +19,7 @@ level=INFO msg="Configured new Prometheus server" name=prom1 uris=1 tags=[] incl level=INFO msg="Configured new Prometheus server" name=prom2 uris=1 tags=[] include=["^rules/2.yml$"] exclude=[] level=WARN msg="No results for Prometheus uptime metric, you might have set uptime config option to a missing metric, please check your config" name=prom1 metric=up level=WARN msg="Using dummy Prometheus uptime metric results with no gaps" name=prom1 metric=up -rules/1.yml:5 Bug: prometheus "prom1" at http://127.0.0.1:7157 didn't have any series for "only_on_prom2" metric in the last 1w, "only_on_prom2" was found on other prometheus servers: prom2, are you deploying this rule to the correct instance? (promql/series) +rules/1.yml:5 Bug: `prom1` Prometheus server at http://127.0.0.1:7157 didn't have any series for `only_on_prom2` metric in the last 1w. (promql/series) 5 | expr: only_on_prom2 == 0 level=INFO msg="Problems found" Bug=1 diff --git a/cmd/pint/tests/0158_lint_teamcity.txt b/cmd/pint/tests/0158_lint_teamcity.txt index fc015b15..7fa7ea02 100644 --- a/cmd/pint/tests/0158_lint_teamcity.txt +++ b/cmd/pint/tests/0158_lint_teamcity.txt @@ -8,14 +8,14 @@ level=INFO msg="Finding all rules to check" paths=["rules"] ##teamcity[testSuiteStarted name='alerts/comparison'] ##teamcity[testSuiteStarted name='Warning'] ##teamcity[testStarted name='rules/0001.yml:5'] -##teamcity[testStdErr name='rules/0001.yml:5' out='alert query doesn|'t have any condition, it will always fire if the metric exists'] +##teamcity[testStdErr name='rules/0001.yml:5' out='Alert query doesn|'t have any condition, it will always fire if the metric exists.'] ##teamcity[testFinished name='rules/0001.yml:5'] ##teamcity[testSuiteFinished name='Warning'] ##teamcity[testSuiteFinished name='alerts/comparison'] ##teamcity[testSuiteStarted name='promql/syntax'] ##teamcity[testSuiteStarted name='Fatal'] ##teamcity[testStarted name='rules/0001.yml:7'] -##teamcity[testFailed name='rules/0001.yml:7' message='' details='syntax error: unexpected identifier "with"'] +##teamcity[testFailed name='rules/0001.yml:7' message='' details='Prometheus failed to parse the query with this PromQL error: unexpected identifier "with".'] ##teamcity[testFinished name='rules/0001.yml:7'] ##teamcity[testSuiteFinished name='Fatal'] ##teamcity[testSuiteFinished name='promql/syntax'] diff --git a/cmd/pint/tests/0159_ci_teamcity.txt b/cmd/pint/tests/0159_ci_teamcity.txt index d5eef7cc..e8002463 100644 --- a/cmd/pint/tests/0159_ci_teamcity.txt +++ b/cmd/pint/tests/0159_ci_teamcity.txt @@ -35,14 +35,14 @@ level=INFO msg="Problems found" Fatal=1 Warning=1 ##teamcity[testSuiteStarted name='promql/syntax'] ##teamcity[testSuiteStarted name='Fatal'] ##teamcity[testStarted name='b.yml:2'] -##teamcity[testFailed name='b.yml:2' message='' details='syntax error: unexpected identifier "bi"'] +##teamcity[testFailed name='b.yml:2' message='' details='Prometheus failed to parse the query with this PromQL error: unexpected identifier "bi".'] ##teamcity[testFinished name='b.yml:2'] ##teamcity[testSuiteFinished name='Fatal'] ##teamcity[testSuiteFinished name='promql/syntax'] ##teamcity[testSuiteStarted name='alerts/comparison'] ##teamcity[testSuiteStarted name='Warning'] ##teamcity[testStarted name='b.yml:4'] -##teamcity[testStdErr name='b.yml:4' out='alert query doesn|'t have any condition, it will always fire if the metric exists'] +##teamcity[testStdErr name='b.yml:4' out='Alert query doesn|'t have any condition, it will always fire if the metric exists.'] ##teamcity[testFinished name='b.yml:4'] ##teamcity[testSuiteFinished name='Warning'] ##teamcity[testSuiteFinished name='alerts/comparison'] diff --git a/docs/changelog.md b/docs/changelog.md index 417ef07b..d7f5e7a4 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -7,6 +7,8 @@ - Added [alerts/external_labels](checks/alerts/external_labels.md) check. - Added support for reporting problems to TeamCity using [Service Messages](https://www.jetbrains.com/help/teamcity/service-messages.html). To enable run it run `pint --teamcity lint` or `pint --teamcity ci`. +- Problems reported to BitBucket and GitHub will now include more details. +- Added `publicURI` field to `prometheus` configuration blocks. ### Changed diff --git a/docs/checks/promql/series.md b/docs/checks/promql/series.md index aa5c7843..4c9505c6 100644 --- a/docs/checks/promql/series.md +++ b/docs/checks/promql/series.md @@ -168,7 +168,7 @@ check "promql/series" { ### min-age But default this check will report a problem if a metric was present -in Prometheus but disappeared for at least two hours ago. +in Prometheus but disappeared at least two hours ago. You can change this duration per Prometheus rule by adding a comment around it. Syntax: @@ -178,6 +178,8 @@ To set `min-age` for all metrics in a query: # pint rule/set promql/series min-age $duration ``` +Duration must follow syntax documented [here](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-durations). + To set `min-age` for specific metric: ```yaml diff --git a/docs/configuration.md b/docs/configuration.md index a04192b4..5aaa5668 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -212,6 +212,7 @@ Syntax: ```js prometheus "$name" { uri = "https://..." + publicURI = "https://..." failover = ["https://...", ...] tags = ["...", ...] headers = { "...": "..." } @@ -234,6 +235,10 @@ prometheus "$name" { - `$name` - each defined server should have a unique name that can be used in check definitions. - `uri` - base URI of this Prometheus server, used for API requests and queries. +- `publicURI` - optional URI to use instead of `uri` in problems reported to users. + Set it if Prometheus links used by pint in comments submitted to BitBucket or GitHub + should use different URIs then the one used by pint when querying Prometheus. + If not set `uri` will be used instead. - `failover` - list of URIs to try (in order they are specified) if `uri` doesn't respond to requests or returns an error. This allows to configure fail-over Prometheus servers to avoid CI failures in case main Prometheus server is unreachable. @@ -411,6 +416,7 @@ Fields that are allowed to be templated are: template { name = "..." uri = "https://..." + uri = "https://..." failover = ["https://...", ...] tags = ["...", ...] headers = { "...": "..." } diff --git a/go.mod b/go.mod index 0216e859..0b6953f4 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/cloudflare/pint -go 1.21.3 +go 1.21.4 require ( github.com/cespare/xxhash/v2 v2.2.0 diff --git a/internal/checks/alerts_annotation.go b/internal/checks/alerts_annotation.go index 516c90cf..b166d699 100644 --- a/internal/checks/alerts_annotation.go +++ b/internal/checks/alerts_annotation.go @@ -49,7 +49,7 @@ func (c AnnotationCheck) Check(_ context.Context, _ string, rule parser.Rule, _ Fragment: fmt.Sprintf("%s: %s", rule.AlertingRule.Alert.Key.Value, rule.AlertingRule.Alert.Value.Value), Lines: rule.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("%s annotation is required", c.keyRe.original), + Text: fmt.Sprintf("`%s` annotation is required.", c.keyRe.original), Severity: c.severity, }) } @@ -66,7 +66,7 @@ func (c AnnotationCheck) Check(_ context.Context, _ string, rule parser.Rule, _ Fragment: fmt.Sprintf("%s: %s", annotation.Key.Value, annotation.Value.Value), Lines: annotation.Value.Position.Lines, Reporter: c.Reporter(), - Text: fmt.Sprintf("%s annotation value must match %q", c.keyRe.original, c.valueRe.anchored), + Text: fmt.Sprintf("`%s` annotation value must match `%s`.", c.keyRe.original, c.valueRe.anchored), Severity: c.severity, }) return problems @@ -79,7 +79,7 @@ func (c AnnotationCheck) Check(_ context.Context, _ string, rule parser.Rule, _ Fragment: fmt.Sprintf("%s:", rule.AlertingRule.Annotations.Key.Value), Lines: rule.AlertingRule.Annotations.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("%s annotation is required", c.keyRe.original), + Text: fmt.Sprintf("`%s` annotation is required.", c.keyRe.original), Severity: c.severity, }) return problems diff --git a/internal/checks/alerts_annotation_test.go b/internal/checks/alerts_annotation_test.go index 4e840e55..d9a4f947 100644 --- a/internal/checks/alerts_annotation_test.go +++ b/internal/checks/alerts_annotation_test.go @@ -31,7 +31,7 @@ func TestAnnotationCheck(t *testing.T) { Fragment: "alert: foo", Lines: []int{1, 2}, Reporter: checks.AnnotationCheckName, - Text: "severity annotation is required", + Text: "`severity` annotation is required.", Severity: checks.Warning, }, } @@ -50,7 +50,7 @@ func TestAnnotationCheck(t *testing.T) { Fragment: "alert: foo", Lines: []int{1, 2}, Reporter: checks.AnnotationCheckName, - Text: "severity annotation is required", + Text: "`severity` annotation is required.", Severity: checks.Warning, }, } @@ -78,7 +78,7 @@ func TestAnnotationCheck(t *testing.T) { Fragment: "annotations:", Lines: []int{3, 4}, Reporter: checks.AnnotationCheckName, - Text: "severity annotation is required", + Text: "`severity` annotation is required.", Severity: checks.Warning, }, } @@ -106,7 +106,7 @@ func TestAnnotationCheck(t *testing.T) { Fragment: "severity: bar", Lines: []int{4}, Reporter: checks.AnnotationCheckName, - Text: `severity annotation value must match "^critical$"`, + Text: "`severity` annotation value must match `^critical$`.", Severity: checks.Warning, }, } @@ -125,7 +125,7 @@ func TestAnnotationCheck(t *testing.T) { Fragment: "severity: bar", Lines: []int{4}, Reporter: checks.AnnotationCheckName, - Text: `severity annotation value must match "^critical$"`, + Text: "`severity` annotation value must match `^critical$`.", Severity: checks.Warning, }, } @@ -171,7 +171,7 @@ func TestAnnotationCheck(t *testing.T) { Fragment: "for: 4m", Lines: []int{5}, Reporter: checks.AnnotationCheckName, - Text: `for annotation value must match "^{{ $for }}$"`, + Text: "`for` annotation value must match `^{{ $for }}$`.", Severity: checks.Bug, }, } @@ -208,7 +208,7 @@ func TestAnnotationCheck(t *testing.T) { Fragment: "annotation_1: bar", Lines: []int{4}, Reporter: checks.AnnotationCheckName, - Text: `annotation_.* annotation value must match "^critical$"`, + Text: "`annotation_.*` annotation value must match `^critical$`.", Severity: checks.Warning, }, } @@ -227,7 +227,7 @@ func TestAnnotationCheck(t *testing.T) { Fragment: "annotation_1: bar", Lines: []int{4}, Reporter: checks.AnnotationCheckName, - Text: `annotation_.* annotation value must match "^critical$"`, + Text: "`annotation_.*` annotation value must match `^critical$`.", Severity: checks.Warning, }, } diff --git a/internal/checks/alerts_comparison.go b/internal/checks/alerts_comparison.go index d16a98dd..31c6584d 100644 --- a/internal/checks/alerts_comparison.go +++ b/internal/checks/alerts_comparison.go @@ -11,7 +11,12 @@ import ( ) const ( - ComparisonCheckName = "alerts/comparison" + ComparisonCheckName = "alerts/comparison" + ComparisonCheckDetails = `Prometheus alerting rules will trigger an alert for each query that returns *any* result. +Unless you do want an alert to always fire you should write your query in a way that returns results only when some condition is met. +In most cases this can be achieved by having some condition in the query expression. +For example ` + "`" + `up == 0` + "`" + " or " + "`" + "rate(error_total[2m]) > 0" + "`." + ` +Be careful as some PromQL operations will cause the query to always return the results, for example using the [bool modifier](https://prometheus.io/docs/prometheus/latest/querying/operators/#comparison-binary-operators).` ) func NewComparisonCheck() ComparisonCheck { @@ -49,7 +54,8 @@ func (c ComparisonCheck) Check(_ context.Context, _ string, rule parser.Rule, _ Fragment: rule.AlertingRule.Expr.Value.Value, Lines: rule.AlertingRule.Expr.Lines(), Reporter: c.Reporter(), - Text: "alert query uses 'or' operator with one side of the query that will always return a result, this alert will always fire", + Text: "Alert query uses `or` operator with one side of the query that will always return a result, this alert will always fire.", + Details: ComparisonCheckDetails, Severity: rewriteSeverity(Warning, n.LHS, n.RHS), }) } @@ -61,7 +67,8 @@ func (c ComparisonCheck) Check(_ context.Context, _ string, rule parser.Rule, _ Fragment: rule.AlertingRule.Expr.Value.Value, Lines: rule.AlertingRule.Expr.Lines(), Reporter: c.Reporter(), - Text: "alert query uses bool modifier for comparison, this means it will always return a result and the alert will always fire", + Text: "Alert query uses `bool` modifier for comparison, this means it will always return a result and the alert will always fire.", + Details: ComparisonCheckDetails, Severity: Bug, }) } @@ -76,7 +83,8 @@ func (c ComparisonCheck) Check(_ context.Context, _ string, rule parser.Rule, _ Fragment: rule.AlertingRule.Expr.Value.Value, Lines: rule.AlertingRule.Expr.Lines(), Reporter: c.Reporter(), - Text: "alert query doesn't have any condition, it will always fire if the metric exists", + Text: "Alert query doesn't have any condition, it will always fire if the metric exists.", + Details: ComparisonCheckDetails, Severity: Warning, }) diff --git a/internal/checks/alerts_comparison_test.go b/internal/checks/alerts_comparison_test.go index 6dc7ccd5..d7e1e494 100644 --- a/internal/checks/alerts_comparison_test.go +++ b/internal/checks/alerts_comparison_test.go @@ -59,7 +59,8 @@ func TestComparisonCheck(t *testing.T) { Fragment: `up{job="foo"}`, Lines: []int{2}, Reporter: checks.ComparisonCheckName, - Text: "alert query doesn't have any condition, it will always fire if the metric exists", + Text: "Alert query doesn't have any condition, it will always fire if the metric exists.", + Details: checks.ComparisonCheckDetails, Severity: checks.Warning, }, } @@ -93,7 +94,8 @@ func TestComparisonCheck(t *testing.T) { Fragment: `quantile_over_time(0.7,(irate(udp_packets_drops[2m]))[10m:2m]) AND ON (instance) rate(node_netstat_Udp_RcvbufErrors[5m])+rate(node_netstat_Udp6_RcvbufErrors[5m])`, Lines: []int{3}, Reporter: checks.ComparisonCheckName, - Text: "alert query doesn't have any condition, it will always fire if the metric exists", + Text: "Alert query doesn't have any condition, it will always fire if the metric exists.", + Details: checks.ComparisonCheckDetails, Severity: checks.Warning, }, } @@ -117,7 +119,8 @@ func TestComparisonCheck(t *testing.T) { Fragment: "rate(error_count[5m]) > bool 5", Lines: []int{2}, Reporter: checks.ComparisonCheckName, - Text: "alert query uses bool modifier for comparison, this means it will always return a result and the alert will always fire", + Text: "Alert query uses `bool` modifier for comparison, this means it will always return a result and the alert will always fire.", + Details: checks.ComparisonCheckDetails, Severity: checks.Bug, }, } @@ -169,7 +172,8 @@ func TestComparisonCheck(t *testing.T) { Fragment: `(foo > 0) or vector(0)`, Lines: []int{2}, Reporter: checks.ComparisonCheckName, - Text: "alert query uses 'or' operator with one side of the query that will always return a result, this alert will always fire", + Text: "Alert query uses `or` operator with one side of the query that will always return a result, this alert will always fire.", + Details: checks.ComparisonCheckDetails, Severity: checks.Bug, }, } @@ -186,7 +190,8 @@ func TestComparisonCheck(t *testing.T) { Fragment: `(foo > 0) or vector(0)`, Lines: []int{2}, Reporter: checks.ComparisonCheckName, - Text: "alert query uses 'or' operator with one side of the query that will always return a result, this alert will always fire", + Text: "Alert query uses `or` operator with one side of the query that will always return a result, this alert will always fire.", + Details: checks.ComparisonCheckDetails, Severity: checks.Bug, }, } @@ -203,7 +208,8 @@ func TestComparisonCheck(t *testing.T) { Fragment: `(foo > 0) or vector(0)`, Lines: []int{2}, Reporter: checks.ComparisonCheckName, - Text: "alert query uses 'or' operator with one side of the query that will always return a result, this alert will always fire", + Text: "Alert query uses `or` operator with one side of the query that will always return a result, this alert will always fire.", + Details: checks.ComparisonCheckDetails, Severity: checks.Bug, }, } diff --git a/internal/checks/alerts_count.go b/internal/checks/alerts_count.go index dc884ac2..90705296 100644 --- a/internal/checks/alerts_count.go +++ b/internal/checks/alerts_count.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "log/slog" + "net/url" "sort" "time" @@ -116,12 +117,15 @@ func (c AlertsCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ [] } sort.Ints(lines) - delta := qr.Series.Until.Sub(qr.Series.From) + delta := qr.Series.Until.Sub(qr.Series.From).Round(time.Minute) problems = append(problems, Problem{ Fragment: rule.AlertingRule.Expr.Value.Value, Lines: lines, Reporter: c.Reporter(), - Text: fmt.Sprintf("%s would trigger %d alert(s) in the last %s", promText(c.prom.Name(), qr.URI), alerts, output.HumanizeDuration(delta)), + Text: fmt.Sprintf("%s would trigger %d alert(s) in the last %s.", promText(c.prom.Name(), qr.URI), alerts, output.HumanizeDuration(delta)), + Details: fmt.Sprintf(`To get a preview of the alerts that would fire please [click here](%s/graph?g0.expr=%s&g0.range_input=%s).`, + qr.PublicURI, url.QueryEscape(rule.AlertingRule.Expr.Value.Value), output.HumanizeDuration(delta), + ), Severity: c.severity, }) return problems diff --git a/internal/checks/alerts_count_test.go b/internal/checks/alerts_count_test.go index 31420900..6a098424 100644 --- a/internal/checks/alerts_count_test.go +++ b/internal/checks/alerts_count_test.go @@ -2,6 +2,7 @@ package checks_test import ( "fmt" + "net/url" "testing" "time" @@ -16,7 +17,14 @@ func newAlertsCheck(prom *promapi.FailoverGroup) checks.RuleChecker { } func alertsText(name, uri string, count int, since string) string { - return fmt.Sprintf(`prometheus %q at %s would trigger %d alert(s) in the last %s`, name, uri, count, since) + return fmt.Sprintf("`%s` Prometheus server at %s would trigger %d alert(s) in the last %s.", name, uri, count, since) +} + +func alertsDetails(uri, query, since string) string { + return fmt.Sprintf( + `To get a preview of the alerts that would fire please [click here](%s/graph?g0.expr=%s&g0.range_input=%s).`, + uri, url.QueryEscape(query), since, + ) } func TestAlertsCountCheck(t *testing.T) { @@ -94,6 +102,7 @@ func TestAlertsCountCheck(t *testing.T) { Lines: []int{2}, Reporter: "alerts/count", Text: alertsText("prom", uri, 0, "1d"), + Details: alertsDetails(uri, `up{job="foo"} == 0`, "1d"), Severity: checks.Information, }, } @@ -120,6 +129,7 @@ func TestAlertsCountCheck(t *testing.T) { Lines: []int{2}, Reporter: "alerts/count", Text: alertsText("prom", uri, 7, "1d"), + Details: alertsDetails(uri, `up{job="foo"} == 0`, "1d"), Severity: checks.Information, }, } @@ -205,6 +215,7 @@ func TestAlertsCountCheck(t *testing.T) { Lines: []int{2, 3}, Reporter: "alerts/count", Text: alertsText("prom", uri, 2, "1d"), + Details: alertsDetails(uri, `up{job="foo"} == 0`, "1d"), Severity: checks.Information, }, } @@ -279,6 +290,7 @@ func TestAlertsCountCheck(t *testing.T) { Lines: []int{2, 3}, Reporter: "alerts/count", Text: alertsText("prom", uri, 2, "1d"), + Details: alertsDetails(uri, `up{job="foo"} == 0`, "1d"), Severity: checks.Information, }, } @@ -353,6 +365,7 @@ func TestAlertsCountCheck(t *testing.T) { Lines: []int{2, 3}, Reporter: "alerts/count", Text: alertsText("prom", uri, 2, "1d"), + Details: alertsDetails(uri, `up{job="foo"} == 0`, "1d"), Severity: checks.Bug, }, } @@ -492,6 +505,7 @@ func TestAlertsCountCheck(t *testing.T) { Lines: []int{3}, Reporter: "alerts/count", Text: alertsText("prom", uri, 3, "1d"), + Details: alertsDetails(uri, `{__name__="up", job="foo"} == 0`, "1d"), Severity: checks.Information, }, } @@ -549,6 +563,8 @@ func TestAlertsCountCheck(t *testing.T) { Lines: []int{3}, Reporter: "alerts/count", Text: alertsText("prom", uri, 3, "1d"), + Details: alertsDetails(uri, `{__name__=~"(up|foo)", job="foo"} == 0`, "1d"), + Severity: checks.Information, }, } @@ -603,6 +619,8 @@ func TestAlertsCountCheck(t *testing.T) { Lines: []int{2}, Reporter: "alerts/count", Text: alertsText("prom", uri, 3, "1d"), + Details: alertsDetails(uri, `up{job="foo"} == 0`, "1d"), + Severity: checks.Information, }, } @@ -657,6 +675,7 @@ func TestAlertsCountCheck(t *testing.T) { Lines: []int{2, 3}, Reporter: "alerts/count", Text: alertsText("prom", uri, 2, "1d"), + Details: alertsDetails(uri, `up{job="foo"} == 0`, "1d"), Severity: checks.Information, }, } @@ -729,6 +748,7 @@ func TestAlertsCountCheck(t *testing.T) { Lines: []int{2, 3, 4}, Reporter: "alerts/count", Text: alertsText("prom", uri, 1, "1d"), + Details: alertsDetails(uri, `up{job="foo"} == 0`, "1d"), Severity: checks.Information, }, } diff --git a/internal/checks/alerts_external_labels.go b/internal/checks/alerts_external_labels.go index de71e528..a05eb68c 100644 --- a/internal/checks/alerts_external_labels.go +++ b/internal/checks/alerts_external_labels.go @@ -64,7 +64,8 @@ func (c AlertsExternalLabelsCheck) Check(ctx context.Context, _ string, rule par Fragment: fmt.Sprintf("%s: %s", label.Key.Value, label.Value.Value), Lines: label.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("template is using %q external label but %s doesn't have this label configured in global:external_labels", name, promText(c.prom.Name(), cfg.URI)), + Text: fmt.Sprintf("Template is using `%s` external label but %s doesn't have this label configured in global:external_labels.", name, promText(c.prom.Name(), cfg.URI)), + Details: fmt.Sprintf("[Click here](%s/config) to see `%s` Prometheus runtime configuration.", cfg.PublicURI, c.prom.Name()), Severity: Bug, }) } @@ -73,7 +74,8 @@ func (c AlertsExternalLabelsCheck) Check(ctx context.Context, _ string, rule par Fragment: fmt.Sprintf("%s: %s", label.Key.Value, label.Value.Value), Lines: label.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("template is using %q external label but %s doesn't have this label configured in global:external_labels", name, promText(c.prom.Name(), cfg.URI)), Severity: Bug, + Text: fmt.Sprintf("Template is using `%s` external label but %s doesn't have this label configured in global:external_labels.", name, promText(c.prom.Name(), cfg.URI)), Severity: Bug, + Details: fmt.Sprintf("[Click here](%s/config) to see `%s` Prometheus runtime configuration.", cfg.PublicURI, c.prom.Name()), }) } } @@ -86,7 +88,8 @@ func (c AlertsExternalLabelsCheck) Check(ctx context.Context, _ string, rule par Fragment: fmt.Sprintf("%s: %s", annotation.Key.Value, annotation.Value.Value), Lines: annotation.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("template is using %q external label but %s doesn't have this label configured in global:external_labels", name, promText(c.prom.Name(), cfg.URI)), + Text: fmt.Sprintf("Template is using `%s` external label but %s doesn't have this label configured in global:external_labels.", name, promText(c.prom.Name(), cfg.URI)), + Details: fmt.Sprintf("[Click here](%s/config) to see `%s` Prometheus runtime configuration.", cfg.PublicURI, c.prom.Name()), Severity: Bug, }) } @@ -95,7 +98,8 @@ func (c AlertsExternalLabelsCheck) Check(ctx context.Context, _ string, rule par Fragment: fmt.Sprintf("%s: %s", annotation.Key.Value, annotation.Value.Value), Lines: annotation.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("template is using %q external label but %s doesn't have this label configured in global:external_labels", name, promText(c.prom.Name(), cfg.URI)), + Text: fmt.Sprintf("Template is using `%s` external label but %s doesn't have this label configured in global:external_labels.", name, promText(c.prom.Name(), cfg.URI)), + Details: fmt.Sprintf("[Click here](%s/config) to see `%s` Prometheus runtime configuration.", cfg.PublicURI, c.prom.Name()), Severity: Bug, }) } diff --git a/internal/checks/alerts_external_labels_test.go b/internal/checks/alerts_external_labels_test.go index c27298c2..3f9e6759 100644 --- a/internal/checks/alerts_external_labels_test.go +++ b/internal/checks/alerts_external_labels_test.go @@ -14,7 +14,11 @@ func newAlertsExternalLabelsCheck(prom *promapi.FailoverGroup) checks.RuleChecke } func alertsExternalLabelsText(name, uri, label string) string { - return fmt.Sprintf("template is using %q external label but prometheus %q at %s doesn't have this label configured in global:external_labels", label, name, uri) + return fmt.Sprintf("Template is using `%s` external label but `%s` Prometheus server at %s doesn't have this label configured in global:external_labels.", label, name, uri) +} + +func alertsExternalLabelsDetails(name, uri string) string { + return fmt.Sprintf("[Click here](%s/config) to see `%s` Prometheus runtime configuration.", uri, name) } func TestAlertsExternalLabelsCountCheck(t *testing.T) { @@ -112,6 +116,7 @@ func TestAlertsExternalLabelsCountCheck(t *testing.T) { Lines: []int{9}, Reporter: checks.AlertsExternalLabelsCheckName, Text: alertsExternalLabelsText("prom", uri, "cluster"), + Details: alertsExternalLabelsDetails("prom", uri), Severity: checks.Bug, }, { @@ -119,6 +124,7 @@ func TestAlertsExternalLabelsCountCheck(t *testing.T) { Lines: []int{10}, Reporter: checks.AlertsExternalLabelsCheckName, Text: alertsExternalLabelsText("prom", uri, "cluster"), + Details: alertsExternalLabelsDetails("prom", uri), Severity: checks.Bug, }, { @@ -126,6 +132,7 @@ func TestAlertsExternalLabelsCountCheck(t *testing.T) { Lines: []int{10}, Reporter: checks.AlertsExternalLabelsCheckName, Text: alertsExternalLabelsText("prom", uri, "cluster"), + Details: alertsExternalLabelsDetails("prom", uri), Severity: checks.Bug, }, { @@ -133,6 +140,7 @@ func TestAlertsExternalLabelsCountCheck(t *testing.T) { Lines: []int{6}, Reporter: checks.AlertsExternalLabelsCheckName, Text: alertsExternalLabelsText("prom", uri, "cluster"), + Details: alertsExternalLabelsDetails("prom", uri), Severity: checks.Bug, }, { @@ -140,6 +148,7 @@ func TestAlertsExternalLabelsCountCheck(t *testing.T) { Lines: []int{6}, Reporter: checks.AlertsExternalLabelsCheckName, Text: alertsExternalLabelsText("prom", uri, "cluster"), + Details: alertsExternalLabelsDetails("prom", uri), Severity: checks.Bug, }, } diff --git a/internal/checks/alerts_for.go b/internal/checks/alerts_for.go index 1cf5e0b2..cccb2623 100644 --- a/internal/checks/alerts_for.go +++ b/internal/checks/alerts_for.go @@ -11,7 +11,8 @@ import ( ) const ( - AlertForCheckName = "alerts/for" + AlertForCheckName = "alerts/for" + AlertForCheckDurationHelp = `Supported time durations are documented [here](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-durations).` ) func NewAlertsForCheck() AlertsForChecksFor { @@ -55,6 +56,7 @@ func (c AlertsForChecksFor) checkField(name, value string, lines []int) (problem Lines: lines, Reporter: c.Reporter(), Text: fmt.Sprintf("invalid duration: %s", err), + Details: AlertForCheckDurationHelp, Severity: Bug, }) return problems @@ -65,7 +67,7 @@ func (c AlertsForChecksFor) checkField(name, value string, lines []int) (problem Fragment: value, Lines: lines, Reporter: c.Reporter(), - Text: fmt.Sprintf("%q is the default value of %q, consider removing this line", value, name), + Text: fmt.Sprintf("`%s` is the default value of `%s`, consider removing this redundant line.", value, name), Severity: Information, }) } diff --git a/internal/checks/alerts_for_test.go b/internal/checks/alerts_for_test.go index a98c47d2..3f058bf9 100644 --- a/internal/checks/alerts_for_test.go +++ b/internal/checks/alerts_for_test.go @@ -39,6 +39,7 @@ func TestAlertsForCheck(t *testing.T) { Lines: []int{3}, Reporter: "alerts/for", Text: `invalid duration: not a valid duration string: "abc"`, + Details: checks.AlertForCheckDurationHelp, Severity: checks.Bug, }, } @@ -56,6 +57,7 @@ func TestAlertsForCheck(t *testing.T) { Lines: []int{3}, Reporter: "alerts/for", Text: `invalid duration: not a valid duration string: "-5m"`, + Details: checks.AlertForCheckDurationHelp, Severity: checks.Bug, }, } @@ -72,7 +74,7 @@ func TestAlertsForCheck(t *testing.T) { Fragment: "0h", Lines: []int{3}, Reporter: "alerts/for", - Text: `"0h" is the default value of "for", consider removing this line`, + Text: "`0h` is the default value of `for`, consider removing this redundant line.", Severity: checks.Information, }, } @@ -90,6 +92,7 @@ func TestAlertsForCheck(t *testing.T) { Lines: []int{3}, Reporter: "alerts/for", Text: `invalid duration: not a valid duration string: "abc"`, + Details: checks.AlertForCheckDurationHelp, Severity: checks.Bug, }, } @@ -107,6 +110,7 @@ func TestAlertsForCheck(t *testing.T) { Lines: []int{3}, Reporter: "alerts/for", Text: `invalid duration: not a valid duration string: "-5m"`, + Details: checks.AlertForCheckDurationHelp, Severity: checks.Bug, }, } @@ -123,7 +127,7 @@ func TestAlertsForCheck(t *testing.T) { Fragment: "0h", Lines: []int{3}, Reporter: "alerts/for", - Text: `"0h" is the default value of "keep_firing_for", consider removing this line`, + Text: "`0h` is the default value of `keep_firing_for`, consider removing this redundant line.", Severity: checks.Information, }, } diff --git a/internal/checks/alerts_template.go b/internal/checks/alerts_template.go index de5d8cc0..d67ef289 100644 --- a/internal/checks/alerts_template.go +++ b/internal/checks/alerts_template.go @@ -24,11 +24,23 @@ import ( ) const ( - TemplateCheckName = "alerts/template" - - msgAggregation = "template is using %q label but the query removes it" - msgAbsent = "template is using %q label but absent() is not passing it" - msgOn = "template is using %q label but the query uses on(...) without it being set there, this label will be missing from the query result" + TemplateCheckName = "alerts/template" + TemplateCheckSyntaxDetails = `Supported template syntax is documented [here](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/#templating).` + TemplateCheckAggregationDetails = `The query used here is using one of [aggregation functions](https://prometheus.io/docs/prometheus/latest/querying/operators/#aggregation-operators) provided by PromQL. +By default aggregations will remove *all* labels from the results, unless you explicitly specify which labels to remove or keep. +This means that with current query it's impossible for the results to have labels you're trying to use.` + TemplateCheckAbsentDetails = `The [absent()](https://prometheus.io/docs/prometheus/latest/querying/functions/#absent) function is used to check if provided query doesn't match any time series. +You will only get any results back if the metric selector you pass doesn't match anything. +Since there are no matching time series there are also no labels. If some time series is missing you cannot read its labels. +This means that the only labels you can get back from absent call are the ones you pass to it. +If you're hoping to get instance specific labels this way and alert when some target is down then that won't work, use the ` + "`up`" + ` metric instead.` + TemplateCheckOnDetails = `Using [vector matching](https://prometheus.io/docs/prometheus/latest/querying/operators/#vector-matching) operations will impact which labels are available on the results of your query. +When using ` + "`on()`" + `make sure that all labels you're trying to use in this templare match what the query can return.` + TemplateCheckLabelsDetails = `This query doesn't seem to be using any time series and so cannot have any labels.` + + msgAggregation = "Template is using `%s` label but the query removes it." + msgAbsent = "Template is using `%s` label but `absent()` is not passing it." + msgOn = "Template is using `%s` label but the query uses `on(...)` without it being set there, this label will be missing from the query result." ) var ( @@ -132,7 +144,8 @@ func (c TemplateCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ Fragment: fmt.Sprintf("%s: %s", label.Key.Value, label.Value.Value), Lines: label.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("template parse error: %s", err), + Text: fmt.Sprintf("Template failed to parse with this error: `%s`.", err), + Details: TemplateCheckSyntaxDetails, Severity: Fatal, }) } @@ -164,6 +177,7 @@ func (c TemplateCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ Lines: mergeLines(label.Lines(), rule.AlertingRule.Expr.Lines()), Reporter: c.Reporter(), Text: msg, + Details: TemplateCheckAggregationDetails, Severity: Bug, }) } @@ -179,6 +193,7 @@ func (c TemplateCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ Lines: mergeLines(label.Lines(), rule.AlertingRule.Expr.Lines()), Reporter: c.Reporter(), Text: msg, + Details: TemplateCheckAbsentDetails, Severity: Bug, }) } @@ -191,6 +206,7 @@ func (c TemplateCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ Lines: mergeLines(label.Lines(), rule.AlertingRule.Expr.Lines()), Reporter: c.Reporter(), Text: msg, + Details: TemplateCheckOnDetails, Severity: Bug, }) } @@ -203,7 +219,8 @@ func (c TemplateCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ Fragment: fmt.Sprintf("%s: %s", label.Key.Value, label.Value.Value), Lines: mergeLines(label.Lines(), rule.AlertingRule.Expr.Lines()), Reporter: c.Reporter(), - Text: fmt.Sprintf("template is using %q label but the query doesn't produce any labels", name), + Text: fmt.Sprintf("Template is using `%s` label but the query doesn't produce any labels.", name), + Details: TemplateCheckLabelsDetails, Severity: Bug, }) } @@ -218,7 +235,8 @@ func (c TemplateCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ Fragment: fmt.Sprintf("%s: %s", annotation.Key.Value, annotation.Value.Value), Lines: annotation.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("template parse error: %s", err), + Text: fmt.Sprintf("Template failed to parse with this error: `%s`.", err), + Details: TemplateCheckSyntaxDetails, Severity: Fatal, }) } @@ -230,6 +248,7 @@ func (c TemplateCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ Lines: mergeLines(annotation.Lines(), rule.AlertingRule.Expr.Lines()), Reporter: c.Reporter(), Text: msg, + Details: TemplateCheckAggregationDetails, Severity: Bug, }) } @@ -252,6 +271,7 @@ func (c TemplateCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ Lines: mergeLines(annotation.Lines(), rule.AlertingRule.Expr.Lines()), Reporter: c.Reporter(), Text: msg, + Details: TemplateCheckAbsentDetails, Severity: Bug, }) } @@ -264,7 +284,8 @@ func (c TemplateCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ Fragment: fmt.Sprintf("%s: %s", annotation.Key.Value, annotation.Value.Value), Lines: mergeLines(annotation.Lines(), rule.AlertingRule.Expr.Lines()), Reporter: c.Reporter(), - Text: fmt.Sprintf("template is using %q label but the query doesn't produce any labels", name), + Text: fmt.Sprintf("Template is using `%s` label but the query doesn't produce any labels.", name), + Details: TemplateCheckLabelsDetails, Severity: Bug, }) } @@ -277,6 +298,7 @@ func (c TemplateCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ Lines: mergeLines(annotation.Lines(), rule.AlertingRule.Expr.Lines()), Reporter: c.Reporter(), Text: msg, + Details: TemplateCheckOnDetails, Severity: Bug, }) } @@ -303,7 +325,8 @@ func (c TemplateCheck) checkHumanizeIsNeeded(node *parser.PromQLNode) (problems for _, call := range utils.HasOuterRate(node) { problems = append(problems, exprProblem{ expr: call.String(), - text: fmt.Sprintf("using the value of %s inside this annotation might be hard to read, consider using one of humanize template functions to make it more human friendly", call), + text: fmt.Sprintf("Using the value of `%s` inside this annotation might be hard to read, consider using one of humanize template functions to make it more human friendly.", call), + details: "[Click here](https://prometheus.io/docs/prometheus/latest/configuration/template_reference/) for a full list of all available template functions.", severity: Information, }) } @@ -370,7 +393,7 @@ func checkForValueInLabels(name, text string) (msgs []string) { aliases := aliasesForTemplate(t) for _, node := range t.Root.Nodes { if v, ok := containsAliasedNode(aliases, node, ".Value"); ok { - msg := fmt.Sprintf("using %s in labels will generate a new alert on every value change, move it to annotations", v) + msg := fmt.Sprintf("Using `%s` in labels will generate a new alert on every value change, move it to annotations.", v) msgs = append(msgs, msg) } } diff --git a/internal/checks/alerts_template_test.go b/internal/checks/alerts_template_test.go index e9ca46c1..36f3deef 100644 --- a/internal/checks/alerts_template_test.go +++ b/internal/checks/alerts_template_test.go @@ -13,7 +13,7 @@ func newTemplateCheck(_ *promapi.FailoverGroup) checks.RuleChecker { } func humanizeText(call string) string { - return fmt.Sprintf("using the value of %s inside this annotation might be hard to read, consider using one of humanize template functions to make it more human friendly", call) + return fmt.Sprintf("Using the value of `%s` inside this annotation might be hard to read, consider using one of humanize template functions to make it more human friendly.", call) } func TestTemplateCheck(t *testing.T) { @@ -36,7 +36,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: Instance {{ $label.instance }} down`, Lines: []int{4}, Reporter: checks.TemplateCheckName, - Text: "template parse error: undefined variable \"$label\"", + Text: "Template failed to parse with this error: `undefined variable \"$label\"`.", + Details: checks.TemplateCheckSyntaxDetails, Severity: checks.Fatal, }, } @@ -53,7 +54,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: {{ $value | xxx }}`, Lines: []int{4}, Reporter: checks.TemplateCheckName, - Text: "template parse error: function \"xxx\" not defined", + Text: "Template failed to parse with this error: `function \"xxx\" not defined`.", + Details: checks.TemplateCheckSyntaxDetails, Severity: checks.Fatal, }, } @@ -77,7 +79,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: Instance {{ $label.instance }} down`, Lines: []int{4}, Reporter: checks.TemplateCheckName, - Text: "template parse error: undefined variable \"$label\"", + Text: "Template failed to parse with this error: `undefined variable \"$label\"`.", + Details: checks.TemplateCheckSyntaxDetails, Severity: checks.Fatal, }, } @@ -94,7 +97,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: {{ $value | xxx }}`, Lines: []int{4}, Reporter: checks.TemplateCheckName, - Text: "template parse error: function \"xxx\" not defined", + Text: "Template failed to parse with this error: `function \"xxx\" not defined`.", + Details: checks.TemplateCheckSyntaxDetails, Severity: checks.Fatal, }, } @@ -118,7 +122,7 @@ func TestTemplateCheck(t *testing.T) { Fragment: "{{ $value}}: bar", Lines: []int{5}, Reporter: checks.TemplateCheckName, - Text: "using $value in labels will generate a new alert on every value change, move it to annotations", + Text: "Using `$value` in labels will generate a new alert on every value change, move it to annotations.", Severity: checks.Bug, }, } @@ -135,7 +139,7 @@ func TestTemplateCheck(t *testing.T) { Fragment: "{{ $value }}: bar", Lines: []int{5}, Reporter: checks.TemplateCheckName, - Text: "using $value in labels will generate a new alert on every value change, move it to annotations", + Text: "Using `$value` in labels will generate a new alert on every value change, move it to annotations.", Severity: checks.Bug, }, } @@ -152,7 +156,7 @@ func TestTemplateCheck(t *testing.T) { Fragment: "baz: {{$value}}", Lines: []int{5}, Reporter: checks.TemplateCheckName, - Text: "using $value in labels will generate a new alert on every value change, move it to annotations", + Text: "Using `$value` in labels will generate a new alert on every value change, move it to annotations.", Severity: checks.Bug, }, } @@ -169,14 +173,14 @@ func TestTemplateCheck(t *testing.T) { Fragment: "foo: {{ .Value }}", Lines: []int{4}, Reporter: checks.TemplateCheckName, - Text: "using .Value in labels will generate a new alert on every value change, move it to annotations", + Text: "Using `.Value` in labels will generate a new alert on every value change, move it to annotations.", Severity: checks.Bug, }, { Fragment: "baz: {{$value}}", Lines: []int{5}, Reporter: checks.TemplateCheckName, - Text: "using $value in labels will generate a new alert on every value change, move it to annotations", + Text: "Using `$value` in labels will generate a new alert on every value change, move it to annotations.", Severity: checks.Bug, }, } @@ -193,7 +197,7 @@ func TestTemplateCheck(t *testing.T) { Fragment: "baz: foo is {{ $value | humanizePercentage }}%\n", Lines: []int{5, 6}, Reporter: checks.TemplateCheckName, - Text: "using $value in labels will generate a new alert on every value change, move it to annotations", + Text: "Using `$value` in labels will generate a new alert on every value change, move it to annotations.", Severity: checks.Bug, }, } @@ -210,7 +214,7 @@ func TestTemplateCheck(t *testing.T) { Fragment: "baz: foo is {{$value|humanizePercentage}}%\n", Lines: []int{5, 6}, Reporter: checks.TemplateCheckName, - Text: "using $value in labels will generate a new alert on every value change, move it to annotations", + Text: "Using `$value` in labels will generate a new alert on every value change, move it to annotations.", Severity: checks.Bug, }, } @@ -227,7 +231,7 @@ func TestTemplateCheck(t *testing.T) { Fragment: "baz: value {{ .Value }}", Lines: []int{5}, Reporter: checks.TemplateCheckName, - Text: "using .Value in labels will generate a new alert on every value change, move it to annotations", + Text: "Using `.Value` in labels will generate a new alert on every value change, move it to annotations.", Severity: checks.Bug, }, } @@ -244,7 +248,7 @@ func TestTemplateCheck(t *testing.T) { Fragment: "baz: {{ .Value|humanize }}", Lines: []int{5}, Reporter: checks.TemplateCheckName, - Text: "using .Value in labels will generate a new alert on every value change, move it to annotations", + Text: "Using `.Value` in labels will generate a new alert on every value change, move it to annotations.", Severity: checks.Bug, }, } @@ -261,7 +265,7 @@ func TestTemplateCheck(t *testing.T) { Fragment: "baz: {{ $foo := $value }}{{ $foo }}", Lines: []int{5}, Reporter: checks.TemplateCheckName, - Text: "using $foo in labels will generate a new alert on every value change, move it to annotations", + Text: "Using `$foo` in labels will generate a new alert on every value change, move it to annotations.", Severity: checks.Bug, }, } @@ -278,7 +282,7 @@ func TestTemplateCheck(t *testing.T) { Fragment: "baz: {{ $foo := .Value }}{{ $foo }}", Lines: []int{5}, Reporter: checks.TemplateCheckName, - Text: "using $foo in labels will generate a new alert on every value change, move it to annotations", + Text: "Using `$foo` in labels will generate a new alert on every value change, move it to annotations.", Severity: checks.Bug, }, } @@ -295,7 +299,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: {{ $labels.job }}`, Lines: []int{2, 4}, Reporter: checks.TemplateCheckName, - Text: `template is using "job" label but the query removes it`, + Text: "Template is using `job` label but the query removes it.", + Details: checks.TemplateCheckAggregationDetails, Severity: checks.Bug, }, } @@ -312,7 +317,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: {{ .Labels.job }}`, Lines: []int{2, 4}, Reporter: checks.TemplateCheckName, - Text: `template is using "job" label but the query removes it`, + Text: "Template is using `job` label but the query removes it.", + Details: checks.TemplateCheckAggregationDetails, Severity: checks.Bug, }, } @@ -329,7 +335,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: {{ $labels.job }}`, Lines: []int{2, 4}, Reporter: checks.TemplateCheckName, - Text: `template is using "job" label but the query removes it`, + Text: "Template is using `job` label but the query removes it.", + Details: checks.TemplateCheckAggregationDetails, Severity: checks.Bug, }, } @@ -346,7 +353,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: {{ .Labels.job }}`, Lines: []int{2, 4}, Reporter: checks.TemplateCheckName, - Text: `template is using "job" label but the query removes it`, + Text: "Template is using `job` label but the query removes it.", + Details: checks.TemplateCheckAggregationDetails, Severity: checks.Bug, }, } @@ -363,7 +371,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: {{ $labels.job }}`, Lines: []int{2, 4}, Reporter: checks.TemplateCheckName, - Text: `template is using "job" label but the query removes it`, + Text: "Template is using `job` label but the query removes it.", + Details: checks.TemplateCheckAggregationDetails, Severity: checks.Bug, }, } @@ -380,7 +389,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: {{ .Labels.job }}`, Lines: []int{2, 4}, Reporter: checks.TemplateCheckName, - Text: `template is using "job" label but the query removes it`, + Text: "Template is using `job` label but the query removes it.", + Details: checks.TemplateCheckAggregationDetails, Severity: checks.Bug, }, } @@ -397,7 +407,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: {{ .Labels.job }}`, Lines: []int{2, 4}, Reporter: checks.TemplateCheckName, - Text: `template is using "job" label but the query removes it`, + Text: "Template is using `job` label but the query removes it.", + Details: checks.TemplateCheckAggregationDetails, Severity: checks.Bug, }, } @@ -420,7 +431,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `help: {{ $labels.ixtance }}`, Lines: []int{3, 6}, Reporter: checks.TemplateCheckName, - Text: `template is using "ixtance" label but the query removes it`, + Text: "Template is using `ixtance` label but the query removes it.", + Details: checks.TemplateCheckAggregationDetails, Severity: checks.Bug, }, } @@ -473,28 +485,32 @@ func TestTemplateCheck(t *testing.T) { Fragment: "instance: {{ $labels.instance }}", Lines: []int{3, 5}, Reporter: checks.TemplateCheckName, - Text: `template is using "instance" label but absent() is not passing it`, + Text: "Template is using `instance` label but `absent()` is not passing it.", + Details: checks.TemplateCheckAbsentDetails, Severity: checks.Bug, }, { Fragment: `summary: {{ $labels.instance }} on {{ .Labels.foo }} is missing`, Lines: []int{3, 7}, Reporter: checks.TemplateCheckName, - Text: `template is using "instance" label but absent() is not passing it`, + Text: "Template is using `instance` label but `absent()` is not passing it.", + Details: checks.TemplateCheckAbsentDetails, Severity: checks.Bug, }, { Fragment: `summary: {{ $labels.instance }} on {{ .Labels.foo }} is missing`, Lines: []int{3, 7}, Reporter: checks.TemplateCheckName, - Text: `template is using "foo" label but absent() is not passing it`, + Text: "Template is using `foo` label but `absent()` is not passing it.", + Details: checks.TemplateCheckAbsentDetails, Severity: checks.Bug, }, { Fragment: "help: {{ $labels.xxx }}", Lines: []int{3, 8}, Reporter: checks.TemplateCheckName, - Text: `template is using "xxx" label but absent() is not passing it`, + Text: "Template is using `xxx` label but `absent()` is not passing it.", + Details: checks.TemplateCheckAbsentDetails, Severity: checks.Bug, }, } @@ -528,7 +544,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: {{ $labels.instance }} on {{ .Labels.job }} is missing`, Lines: []int{3, 5}, Reporter: checks.TemplateCheckName, - Text: `template is using "instance" label but the query removes it`, + Text: "Template is using `instance` label but the query removes it.", + Details: checks.TemplateCheckAggregationDetails, Severity: checks.Bug, }, } @@ -550,7 +567,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: {{ .Labels.job }} is missing`, Lines: []int{3, 5}, Reporter: checks.TemplateCheckName, - Text: `template is using "job" label but absent() is not passing it`, + Text: "Template is using `job` label but `absent()` is not passing it.", + Details: checks.TemplateCheckAbsentDetails, Severity: checks.Bug, }, } @@ -572,14 +590,16 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: {{ .Labels.job }} / {{$labels.job}} is missing`, Lines: []int{3, 5}, Reporter: checks.TemplateCheckName, - Text: `template is using "job" label but absent() is not passing it`, + Text: "Template is using `job` label but `absent()` is not passing it.", + Details: checks.TemplateCheckAbsentDetails, Severity: checks.Bug, }, { Fragment: `summary: {{ .Labels.job }} / {{$labels.job}} is missing`, Lines: []int{3, 5}, Reporter: checks.TemplateCheckName, - Text: `template is using "job" label but absent() is not passing it`, + Text: "Template is using `job` label but `absent()` is not passing it.", + Details: checks.TemplateCheckAbsentDetails, Severity: checks.Bug, }, } @@ -848,7 +868,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: "summary: {{ with printf \"sum({job='%s'}) by(\" .Labels.job | query }}\n{{ . | first | label \"instance\" }}\n{{ end }}\n", Lines: []int{5, 6, 7, 8}, Reporter: checks.TemplateCheckName, - Text: `template parse error: 163: executing "summary" at : error calling query: 1:18: parse error: unclosed left parenthesis`, + Text: "Template failed to parse with this error: `163: executing \"summary\" at : error calling query: 1:18: parse error: unclosed left parenthesis`.", + Details: checks.TemplateCheckSyntaxDetails, Severity: checks.Fatal, }, } @@ -873,7 +894,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: "summary: {{ with printf \"suz({job='%s'})\" .Labels.job | query }}\n{{ . | first | label \"instance\" }}\n{{ end }}\n", Lines: []int{5, 6, 7, 8}, Reporter: checks.TemplateCheckName, - Text: `template parse error: 159: executing "summary" at : error calling query: 1:1: parse error: unknown function with name "suz"`, + Text: "Template failed to parse with this error: `159: executing \"summary\" at : error calling query: 1:1: parse error: unknown function with name \"suz\"`.", + Details: checks.TemplateCheckSyntaxDetails, Severity: checks.Fatal, }, } @@ -895,8 +917,9 @@ func TestTemplateCheck(t *testing.T) { Fragment: "summary: {{ $value | first }} errors", Lines: []int{5}, Reporter: checks.TemplateCheckName, - Text: `template parse error: 124: executing "summary" at : wrong type for value; expected template.queryResult; got float64`, + Text: "Template failed to parse with this error: `124: executing \"summary\" at : wrong type for value; expected template.queryResult; got float64`.", Severity: checks.Fatal, + Details: checks.TemplateCheckSyntaxDetails, }, { Fragment: "rate(errors[2m])", @@ -927,7 +950,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: "summary: {{ range query \"up xxx\" }}\n{{ .Labels.instance }} {{ .Value }}\n{{ end }}\n", Lines: []int{5, 6, 7, 8}, Reporter: checks.TemplateCheckName, - Text: `template parse error: 121: executing "summary" at : error calling query: 1:4: parse error: unexpected identifier "xxx"`, + Text: "Template failed to parse with this error: `121: executing \"summary\" at : error calling query: 1:4: parse error: unexpected identifier \"xxx\"`.", + Details: checks.TemplateCheckSyntaxDetails, Severity: checks.Fatal, }, } @@ -1028,7 +1052,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: Deadmans switch on {{ $labels.instance }} is firing`, Lines: []int{2, 4}, Reporter: checks.TemplateCheckName, - Text: `template is using "instance" label but the query doesn't produce any labels`, + Text: "Template is using `instance` label but the query doesn't produce any labels.", + Details: checks.TemplateCheckLabelsDetails, Severity: checks.Bug, }, } @@ -1045,7 +1070,8 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: Deadmans switch on {{ $labels.instance }} is firing`, Lines: []int{2, 4}, Reporter: checks.TemplateCheckName, - Text: `template is using "instance" label but the query doesn't produce any labels`, + Text: "Template is using `instance` label but the query doesn't produce any labels.", + Details: checks.TemplateCheckLabelsDetails, Severity: checks.Bug, }, } @@ -1062,14 +1088,16 @@ func TestTemplateCheck(t *testing.T) { Fragment: `summary: Deadmans switch on {{ $labels.instance }} / {{ $labels.job }} is firing`, Lines: []int{2, 4}, Reporter: checks.TemplateCheckName, - Text: `template is using "instance" label but the query doesn't produce any labels`, + Text: "Template is using `instance` label but the query doesn't produce any labels.", + Details: checks.TemplateCheckLabelsDetails, Severity: checks.Bug, }, { Fragment: `summary: Deadmans switch on {{ $labels.instance }} / {{ $labels.job }} is firing`, Lines: []int{2, 4}, Reporter: checks.TemplateCheckName, - Text: `template is using "job" label but the query doesn't produce any labels`, + Text: "Template is using `job` label but the query doesn't produce any labels.", + Details: checks.TemplateCheckLabelsDetails, Severity: checks.Bug, }, } @@ -1092,14 +1120,16 @@ func TestTemplateCheck(t *testing.T) { Fragment: `job: {{ $labels.job_name }}`, Lines: []int{2, 6}, Reporter: checks.TemplateCheckName, - Text: `template is using "job_name" label but the query uses on(...) without it being set there, this label will be missing from the query result`, + Text: "Template is using `job_name` label but the query uses `on(...)` without it being set there, this label will be missing from the query result.", + Details: checks.TemplateCheckOnDetails, Severity: checks.Bug, }, { Fragment: `summary: {{ $labels.app_type }} is using {{ $value }} fds.`, Lines: []int{2, 4}, Reporter: checks.TemplateCheckName, - Text: `template is using "app_type" label but the query uses on(...) without it being set there, this label will be missing from the query result`, + Text: "Template is using `app_type` label but the query uses `on(...)` without it being set there, this label will be missing from the query result.", + Details: checks.TemplateCheckOnDetails, Severity: checks.Bug, }, } diff --git a/internal/checks/base.go b/internal/checks/base.go index 1c8881c0..d4a6963f 100644 --- a/internal/checks/base.go +++ b/internal/checks/base.go @@ -101,6 +101,7 @@ type Problem struct { Lines []int Reporter string Text string + Details string Severity Severity } @@ -122,6 +123,7 @@ type RuleChecker interface { type exprProblem struct { expr string text string + details string severity Severity } @@ -137,16 +139,16 @@ func textAndSeverityFromError(err error, reporter, prom string, s Severity) (tex switch { case promapi.IsQueryTooExpensive(err): - text = fmt.Sprintf("couldn't run %q checks on %s because some queries are too expensive: %s", reporter, promDesc, err) + text = fmt.Sprintf("Couldn't run %q checks on %s because some queries are too expensive: `%s`.", reporter, promDesc, err) severity = Warning case promapi.IsUnavailableError(err): - text = fmt.Sprintf("couldn't run %q checks due to %s connection error: %s", reporter, promDesc, err) + text = fmt.Sprintf("Couldn't run %q checks due to %s connection error: `%s`.", reporter, promDesc, err) severity = Warning if perrOk && perr.IsStrict() { severity = Bug } default: - text = fmt.Sprintf("%s failed with: %s", promDesc, err) + text = fmt.Sprintf("%s failed with: `%s`.", promDesc, err) severity = s } @@ -154,5 +156,5 @@ func textAndSeverityFromError(err error, reporter, prom string, s Severity) (tex } func promText(name, uri string) string { - return fmt.Sprintf("prometheus %q at %s", name, uri) + return fmt.Sprintf("`%s` Prometheus server at %s", name, uri) } diff --git a/internal/checks/base_test.go b/internal/checks/base_test.go index 24c97677..e6a8be72 100644 --- a/internal/checks/base_test.go +++ b/internal/checks/base_test.go @@ -66,8 +66,9 @@ func TestParseSeverity(t *testing.T) { func simpleProm(name, uri string, timeout time.Duration, required bool) *promapi.FailoverGroup { return promapi.NewFailoverGroup( name, + uri, []*promapi.Prometheus{ - promapi.NewPrometheus(name, uri, map[string]string{"X-Debug": "1"}, timeout, 16, 1000, nil), + promapi.NewPrometheus(name, uri, "", map[string]string{"X-Debug": "1"}, timeout, 16, 1000, nil), }, required, "up", @@ -562,13 +563,13 @@ func generateSampleStream(labels map[string]string, from, until time.Time, step } func checkErrorBadData(name, uri, err string) string { - return fmt.Sprintf(`prometheus %q at %s failed with: %s`, name, uri, err) + return fmt.Sprintf("`%s` Prometheus server at %s failed with: `%s`.", name, uri, err) } func checkErrorUnableToRun(c, name, uri, err string) string { - return fmt.Sprintf(`couldn't run %q checks due to prometheus %q at %s connection error: %s`, c, name, uri, err) + return fmt.Sprintf("Couldn't run %q checks due to `%s` Prometheus server at %s connection error: `%s`.", c, name, uri, err) } func checkErrorTooExpensiveToRun(c, name, uri, err string) string { - return fmt.Sprintf(`couldn't run %q checks on prometheus %q at %s because some queries are too expensive: %s`, c, name, uri, err) + return fmt.Sprintf("Couldn't run %q checks on `%s` Prometheus server at %s because some queries are too expensive: `%s`.", c, name, uri, err) } diff --git a/internal/checks/labels_conflict.go b/internal/checks/labels_conflict.go index 7741aa74..25244e36 100644 --- a/internal/checks/labels_conflict.go +++ b/internal/checks/labels_conflict.go @@ -62,7 +62,8 @@ func (c LabelsConflictCheck) Check(ctx context.Context, _ string, rule parser.Ru Fragment: fmt.Sprintf("%s: %s", label.Key.Value, label.Value.Value), Lines: label.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("%s external_labels already has %s=%q label set, please choose a different name for this label to avoid any conflicts", promText(c.prom.Name(), cfg.URI), k, v), + Text: fmt.Sprintf("%s external_labels already has %s=%q label set, please choose a different name for this label to avoid any conflicts.", promText(c.prom.Name(), cfg.URI), k, v), + Details: fmt.Sprintf("[Click here](%s/config) to see `%s` Prometheus runtime configuration.", cfg.PublicURI, c.prom.Name()), Severity: Warning, }) } diff --git a/internal/checks/labels_conflict_test.go b/internal/checks/labels_conflict_test.go index b889fb89..979b7c6d 100644 --- a/internal/checks/labels_conflict_test.go +++ b/internal/checks/labels_conflict_test.go @@ -10,7 +10,7 @@ import ( ) func textExternalLabels(name, uri, k, v string) string { - return fmt.Sprintf("prometheus %q at %s external_labels already has %s=%q label set, please choose a different name for this label to avoid any conflicts", name, uri, k, v) + return fmt.Sprintf("`%s` Prometheus server at %s external_labels already has %s=%q label set, please choose a different name for this label to avoid any conflicts.", name, uri, k, v) } func newLabelsConflict(prom *promapi.FailoverGroup) checks.RuleChecker { @@ -71,6 +71,7 @@ func TestLabelsConflictCheck(t *testing.T) { Lines: []int{4}, Reporter: checks.LabelsConflictCheckName, Text: textExternalLabels("prom", uri, "foo", "bob"), + Details: alertsExternalLabelsDetails("prom", uri), Severity: checks.Warning, }, } diff --git a/internal/checks/promql_aggregation.go b/internal/checks/promql_aggregation.go index bca216b0..333521c2 100644 --- a/internal/checks/promql_aggregation.go +++ b/internal/checks/promql_aggregation.go @@ -117,14 +117,14 @@ func (c AggregationCheck) checkNode(node *parser.PromQLNode) (problems []exprPro if found && c.keep { problems = append(problems, exprProblem{ expr: node.Expr, - text: fmt.Sprintf("%s label is required and should be preserved when aggregating %q rules, remove %s from without()", c.label, c.nameRegex.anchored, c.label), + text: fmt.Sprintf("`%s` label is required and should be preserved when aggregating `%s` rules, remove %s from `without()`.", c.label, c.nameRegex.anchored, c.label), }) } if !found && !c.keep { problems = append(problems, exprProblem{ expr: node.Expr, - text: fmt.Sprintf("%s label should be removed when aggregating %q rules, use without(%s, ...)", c.label, c.nameRegex.anchored, c.label), + text: fmt.Sprintf("`%s` label should be removed when aggregating `%s` rules, use `without(%s, ...)`.", c.label, c.nameRegex.anchored, c.label), }) } @@ -137,14 +137,14 @@ func (c AggregationCheck) checkNode(node *parser.PromQLNode) (problems []exprPro if found && !c.keep { problems = append(problems, exprProblem{ expr: node.Expr, - text: fmt.Sprintf("%s label should be removed when aggregating %q rules, remove %s from by()", c.label, c.nameRegex.anchored, c.label), + text: fmt.Sprintf("`%s` label should be removed when aggregating `%s` rules, remove %s from `by()`.", c.label, c.nameRegex.anchored, c.label), }) } if !found && c.keep { problems = append(problems, exprProblem{ expr: node.Expr, - text: fmt.Sprintf("%s label is required and should be preserved when aggregating %q rules, use by(%s, ...)", c.label, c.nameRegex.anchored, c.label), + text: fmt.Sprintf("`%s` label is required and should be preserved when aggregating `%s` rules, use `by(%s, ...)`.", c.label, c.nameRegex.anchored, c.label), }) } diff --git a/internal/checks/promql_aggregation_test.go b/internal/checks/promql_aggregation_test.go index 6fe44190..69cd5246 100644 --- a/internal/checks/promql_aggregation_test.go +++ b/internal/checks/promql_aggregation_test.go @@ -67,7 +67,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum(foo) without(instance, job)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, remove job from without()`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`.", Severity: checks.Warning, }, } @@ -86,7 +86,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum(foo) without(instance, job)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, remove job from without()`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`.", Severity: checks.Bug, }, } @@ -105,7 +105,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum(foo) without(instance)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label should be removed when aggregating "^.+$" rules, use without(job, ...)`, + Text: "`job` label should be removed when aggregating `^.+$` rules, use `without(job, ...)`.", Severity: checks.Warning, }, } @@ -142,7 +142,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum without (job) (foo)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, remove job from without()`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`.", Severity: checks.Warning, }, } @@ -170,14 +170,14 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum(sum(foo) without(foo)) without(bar)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `instance label should be removed when aggregating "^.+$" rules, use without(instance, ...)`, + Text: "`instance` label should be removed when aggregating `^.+$` rules, use `without(instance, ...)`.", Severity: checks.Warning, }, { Fragment: "sum without (foo) (foo)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `instance label should be removed when aggregating "^.+$" rules, use without(instance, ...)`, + Text: "`instance` label should be removed when aggregating `^.+$` rules, use `without(instance, ...)`.", Severity: checks.Warning, }, } @@ -196,7 +196,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum without (job) (foo)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, remove job from without()`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`.", Severity: checks.Warning, }, } @@ -224,7 +224,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "max without (job) (foo)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, remove job from without()`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`.", Severity: checks.Warning, }, } @@ -252,7 +252,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum without (job) (foo)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, remove job from without()`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`.", Severity: checks.Warning, }, } @@ -280,7 +280,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum without (job) (bar)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, remove job from without()`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`.", Severity: checks.Warning, }, } @@ -336,7 +336,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum(foo) by(instance)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...)`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`.", Severity: checks.Warning, }, } @@ -355,7 +355,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum(foo) by(instance)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...)`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`.", Severity: checks.Bug, }, } @@ -374,7 +374,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum(foo) by(job)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label should be removed when aggregating "^.+$" rules, remove job from by()`, + Text: "`job` label should be removed when aggregating `^.+$` rules, remove job from `by()`.", Severity: checks.Warning, }, } @@ -402,7 +402,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum by (instance) (foo)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...)`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`.", Severity: checks.Warning, }, } @@ -430,7 +430,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "max by (instance) (foo)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...)`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`.", Severity: checks.Warning, }, } @@ -458,7 +458,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum by (type) (foo)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...)`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`.", Severity: checks.Warning, }, } @@ -486,7 +486,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum by (type) (bar)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...)`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`.", Severity: checks.Warning, }, } @@ -523,14 +523,14 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum(sum(foo) by(instance)) without(job)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, remove job from without()`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`.", Severity: checks.Warning, }, { Fragment: "sum by (instance) (foo)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...)`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`.", Severity: checks.Warning, }, } @@ -549,7 +549,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum(sum(foo) by(instance,job)) without(job)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, remove job from without()`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, remove job from `without()`.", Severity: checks.Warning, }, } @@ -568,7 +568,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum by (instance) (foo)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...)`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`.", Severity: checks.Warning, }, } @@ -587,14 +587,14 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum(sum(foo) by(instance)) without(job)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `instance label should be removed when aggregating "^.+$" rules, use without(instance, ...)`, + Text: "`instance` label should be removed when aggregating `^.+$` rules, use `without(instance, ...)`.", Severity: checks.Warning, }, { Fragment: "sum by (instance) (foo)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `instance label should be removed when aggregating "^.+$" rules, remove instance from by()`, + Text: "`instance` label should be removed when aggregating `^.+$` rules, remove instance from `by()`.", Severity: checks.Warning, }, } @@ -613,7 +613,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum(foo)", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...)`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`.", Severity: checks.Warning, }, } @@ -632,7 +632,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum(foo) by()", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label is required and should be preserved when aggregating "^.+$" rules, use by(job, ...)`, + Text: "`job` label is required and should be preserved when aggregating `^.+$` rules, use `by(job, ...)`.", Severity: checks.Warning, }, } @@ -651,7 +651,7 @@ func TestAggregationCheck(t *testing.T) { Fragment: "sum(foo) without()", Lines: []int{2}, Reporter: checks.AggregationCheckName, - Text: `job label should be removed when aggregating "^.+$" rules, use without(job, ...)`, + Text: "`job` label should be removed when aggregating `^.+$` rules, use `without(job, ...)`.", Severity: checks.Warning, }, } diff --git a/internal/checks/promql_fragile.go b/internal/checks/promql_fragile.go index 3038431e..99b89692 100644 --- a/internal/checks/promql_fragile.go +++ b/internal/checks/promql_fragile.go @@ -83,7 +83,7 @@ func (c FragileCheck) checkNode(node *parser.PromQLNode) (problems []exprProblem if len(series) >= 2 { p := exprProblem{ expr: node.Expr, - text: "aggregation using without() can be fragile when used inside binary expression because both sides must have identical sets of labels to produce any results, adding or removing labels to metrics used here can easily break the query, consider aggregating using by() to ensure consistent labels", + text: "Aggregation using `without()` can be fragile when used inside binary expression because both sides must have identical sets of labels to produce any results, adding or removing labels to metrics used here can easily break the query, consider aggregating using `by()` to ensure consistent labels.", severity: Warning, } problems = append(problems, p) diff --git a/internal/checks/promql_fragile_test.go b/internal/checks/promql_fragile_test.go index 23e48ee1..e7723273 100644 --- a/internal/checks/promql_fragile_test.go +++ b/internal/checks/promql_fragile_test.go @@ -12,7 +12,7 @@ func newFragileCheck(_ *promapi.FailoverGroup) checks.RuleChecker { } func TestFragileCheck(t *testing.T) { - text := "aggregation using without() can be fragile when used inside binary expression because both sides must have identical sets of labels to produce any results, adding or removing labels to metrics used here can easily break the query, consider aggregating using by() to ensure consistent labels" + text := "Aggregation using `without()` can be fragile when used inside binary expression because both sides must have identical sets of labels to produce any results, adding or removing labels to metrics used here can easily break the query, consider aggregating using `by()` to ensure consistent labels." testCases := []checkTest{ { diff --git a/internal/checks/promql_range_query.go b/internal/checks/promql_range_query.go index 4d68e0bd..4fa85553 100644 --- a/internal/checks/promql_range_query.go +++ b/internal/checks/promql_range_query.go @@ -93,7 +93,7 @@ func (c RangeQueryCheck) checkNode(ctx context.Context, node *parser.PromQLNode, if n.Range > retention { problems = append(problems, exprProblem{ expr: node.Expr, - text: fmt.Sprintf("%s selector is trying to query Prometheus for %s worth of metrics, but %s is configured to only keep %s of metrics history", + text: fmt.Sprintf("`%s` selector is trying to query Prometheus for %s worth of metrics, but %s is configured to only keep %s of metrics history.", node.Expr, model.Duration(n.Range), promText(c.prom.Name(), uri), model.Duration(retention)), severity: Warning, }) diff --git a/internal/checks/promql_range_query_test.go b/internal/checks/promql_range_query_test.go index 93a2e855..d2634dde 100644 --- a/internal/checks/promql_range_query_test.go +++ b/internal/checks/promql_range_query_test.go @@ -13,7 +13,7 @@ func newRangeQueryCheck(prom *promapi.FailoverGroup) checks.RuleChecker { } func retentionToLow(name, uri, metric, qr, retention string) string { - return fmt.Sprintf("%s selector is trying to query Prometheus for %s worth of metrics, but prometheus %q at %s is configured to only keep %s of metrics history", + return fmt.Sprintf("`%s` selector is trying to query Prometheus for %s worth of metrics, but `%s` Prometheus server at %s is configured to only keep %s of metrics history.", metric, qr, name, uri, retention) } diff --git a/internal/checks/promql_rate.go b/internal/checks/promql_rate.go index 96e3a9a8..0bf2a6c9 100644 --- a/internal/checks/promql_rate.go +++ b/internal/checks/promql_rate.go @@ -17,8 +17,18 @@ import ( promParser "github.com/prometheus/prometheus/promql/parser" ) +// FIXME: add native histograms + const ( - RateCheckName = "promql/rate" + RateCheckName = "promql/rate" + RateCheckDetails = `Using [rate](https://prometheus.io/docs/prometheus/latest/querying/functions/#rate) and [irate](https://prometheus.io/docs/prometheus/latest/querying/functions/#irate) function comes with a few requirements: + +- The metric you calculate (i)rate from must be a counter or native histograms. +- The time window of the (i)rate function must have at least 2 samples. + +The type of your metric is defined by the application that exports that metric. +The number of samples depends on how often your application is being scraped by Prometheus. +Each scrape produces a sample, so if your application is scrape every minute then the minimal time window you can use is two minutes.` ) func NewRateCheck(prom *promapi.FailoverGroup) RateCheck { @@ -69,6 +79,7 @@ func (c RateCheck) Check(ctx context.Context, _ string, rule parser.Rule, entrie Lines: expr.Lines(), Reporter: c.Reporter(), Text: problem.text, + Details: problem.details, Severity: problem.severity, }) } @@ -86,8 +97,9 @@ func (c RateCheck) checkNode(ctx context.Context, node *parser.PromQLNode, entri if m.Range < cfg.Config.Global.ScrapeInterval*time.Duration(c.minIntervals) { p := exprProblem{ expr: node.Expr, - text: fmt.Sprintf("duration for %s() must be at least %d x scrape_interval, %s is using %s scrape_interval", + text: fmt.Sprintf("Duration for `%s()` must be at least %d x scrape_interval, %s is using `%s` scrape_interval.", n.Func.Name, c.minIntervals, promText(c.prom.Name(), cfg.URI), output.HumanizeDuration(cfg.Config.Global.ScrapeInterval)), + details: RateCheckDetails, severity: Bug, } problems = append(problems, p) @@ -114,8 +126,9 @@ func (c RateCheck) checkNode(ctx context.Context, node *parser.PromQLNode, entri if m.Type != v1.MetricTypeCounter && m.Type != v1.MetricTypeUnknown { problems = append(problems, exprProblem{ expr: s.Name, - text: fmt.Sprintf("%s() should only be used with counters but %q is a %s according to metrics metadata from %s", + text: fmt.Sprintf("`%s()` should only be used with counters but `%s` is a %s according to metrics metadata from %s.", n.Func.Name, s.Name, m.Type, promText(c.prom.Name(), metadata.URI)), + details: RateCheckDetails, severity: Bug, }) } @@ -145,7 +158,7 @@ func (c RateCheck) checkNode(ctx context.Context, node *parser.PromQLNode, entri if m.Type == v1.MetricTypeCounter { problems = append(problems, exprProblem{ expr: node.Expr, - text: fmt.Sprintf("rate(sum(counter)) chain detected, %s is called here on results of %s, calling rate on sum() results will return bogus results, always sum(rate(counter)), never rate(sum(counter))", + text: fmt.Sprintf("`rate(sum(counter))` chain detected, `%s` is called here on results of `%s`, calling `rate()` on `sum()` results will return bogus results, always `sum(rate(counter))`, never `rate(sum(counter))`.", node.Expr, sm), severity: Bug, }) diff --git a/internal/checks/promql_rate_test.go b/internal/checks/promql_rate_test.go index 2e1c9856..2768825a 100644 --- a/internal/checks/promql_rate_test.go +++ b/internal/checks/promql_rate_test.go @@ -16,15 +16,15 @@ func newRateCheck(prom *promapi.FailoverGroup) checks.RuleChecker { } func durationMustText(name, uri, fun, multi, using string) string { - return fmt.Sprintf(`duration for %s() must be at least %s x scrape_interval, prometheus %q at %s is using %s scrape_interval`, fun, multi, name, uri, using) + return fmt.Sprintf("Duration for `%s()` must be at least %s x scrape_interval, `%s` Prometheus server at %s is using `%s` scrape_interval.", fun, multi, name, uri, using) } func notCounterText(name, uri, fun, metric, kind string) string { - return fmt.Sprintf(`%s() should only be used with counters but %q is a %s according to metrics metadata from prometheus %q at %s`, fun, metric, kind, name, uri) + return fmt.Sprintf("`%s()` should only be used with counters but `%s` is a %s according to metrics metadata from `%s` Prometheus server at %s.", fun, metric, kind, name, uri) } func rateSumText(rateName, sumExpr string) string { - return fmt.Sprintf("rate(sum(counter)) chain detected, rate(%s) is called here on results of %s, calling rate on sum() results will return bogus results, always sum(rate(counter)), never rate(sum(counter))", rateName, sumExpr) + return fmt.Sprintf("`rate(sum(counter))` chain detected, `rate(%s)` is called here on results of `%s`, calling `rate()` on `sum()` results will return bogus results, always `sum(rate(counter))`, never `rate(sum(counter))`.", rateName, sumExpr) } func TestRateCheck(t *testing.T) { @@ -48,6 +48,7 @@ func TestRateCheck(t *testing.T) { Lines: []int{2}, Reporter: "promql/rate", Text: durationMustText("prom", uri, "rate", "2", "1m"), + Details: checks.RateCheckDetails, Severity: checks.Bug, }, } @@ -115,6 +116,7 @@ func TestRateCheck(t *testing.T) { Lines: []int{2}, Reporter: "promql/rate", Text: durationMustText("prom", uri, "irate", "2", "1m"), + Details: checks.RateCheckDetails, Severity: checks.Bug, }, } @@ -144,6 +146,7 @@ func TestRateCheck(t *testing.T) { Lines: []int{2}, Reporter: "promql/rate", Text: durationMustText("prom", uri, "deriv", "2", "1m"), + Details: checks.RateCheckDetails, Severity: checks.Bug, }, } @@ -319,6 +322,7 @@ func TestRateCheck(t *testing.T) { Lines: []int{2}, Reporter: "promql/rate", Text: durationMustText("prom", uri, "rate", "2", "1m"), + Details: checks.RateCheckDetails, Severity: checks.Bug, }, } @@ -456,6 +460,7 @@ func TestRateCheck(t *testing.T) { Lines: []int{2}, Reporter: "promql/rate", Text: durationMustText("prom", uri, "rate", "2", "1m"), + Details: checks.RateCheckDetails, Severity: checks.Bug, }, { @@ -507,6 +512,7 @@ func TestRateCheck(t *testing.T) { Lines: []int{2}, Reporter: "promql/rate", Text: durationMustText("prom", uri, "rate", "2", "1m"), + Details: checks.RateCheckDetails, Severity: checks.Bug, }, { @@ -514,6 +520,7 @@ func TestRateCheck(t *testing.T) { Lines: []int{2}, Reporter: "promql/rate", Text: notCounterText("prom", uri, "rate", "foo", "gauge"), + Details: checks.RateCheckDetails, Severity: checks.Bug, }, } @@ -543,6 +550,7 @@ func TestRateCheck(t *testing.T) { Lines: []int{2}, Reporter: "promql/rate", Text: notCounterText("prom", uri, "rate", "bar_g", "gauge"), + Details: checks.RateCheckDetails, Severity: checks.Bug, }, } @@ -603,6 +611,7 @@ func TestRateCheck(t *testing.T) { Lines: []int{2}, Reporter: "promql/rate", Text: notCounterText("prom", uri, "rate", "foo", "gauge"), + Details: checks.RateCheckDetails, Severity: checks.Bug, }, } diff --git a/internal/checks/promql_regexp.go b/internal/checks/promql_regexp.go index 88756b0e..5b0485d0 100644 --- a/internal/checks/promql_regexp.go +++ b/internal/checks/promql_regexp.go @@ -83,7 +83,7 @@ func (c RegexpCheck) Check(_ context.Context, _ string, rule parser.Rule, _ []di Fragment: selector.String(), Lines: expr.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf(`unnecessary regexp match on static string %s, use %s%s%q instead`, lm, lm.Name, op, lm.Value), + Text: fmt.Sprintf("Unnecessary regexp match on static string `%s`, use `%s%s%q` instead.", lm, lm.Name, op, lm.Value), Severity: Bug, }) } @@ -92,7 +92,7 @@ func (c RegexpCheck) Check(_ context.Context, _ string, rule parser.Rule, _ []di Fragment: selector.String(), Lines: expr.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf(`prometheus regexp matchers are automatically fully anchored so match for %s will result in %s%s"^%s$", remove regexp anchors ^ and/or $`, + Text: fmt.Sprintf("Prometheus regexp matchers are automatically fully anchored so match for `%s` will result in `%s%s\"^%s$\"`, remove regexp anchors `^` and/or `$`.", lm, lm.Name, lm.Type, lm.Value, ), Severity: Bug, diff --git a/internal/checks/promql_regexp_test.go b/internal/checks/promql_regexp_test.go index ab1cd47a..59da655f 100644 --- a/internal/checks/promql_regexp_test.go +++ b/internal/checks/promql_regexp_test.go @@ -59,7 +59,7 @@ func TestRegexpCheck(t *testing.T) { Fragment: `foo{job=~"bar"}`, Lines: []int{2}, Reporter: checks.RegexpCheckName, - Text: `unnecessary regexp match on static string job=~"bar", use job="bar" instead`, + Text: "Unnecessary regexp match on static string `job=~\"bar\"`, use `job=\"bar\"` instead.", Severity: checks.Bug, }, } @@ -76,7 +76,7 @@ func TestRegexpCheck(t *testing.T) { Fragment: `foo{job!~"bar"}`, Lines: []int{2}, Reporter: checks.RegexpCheckName, - Text: `unnecessary regexp match on static string job!~"bar", use job!="bar" instead`, + Text: "Unnecessary regexp match on static string `job!~\"bar\"`, use `job!=\"bar\"` instead.", Severity: checks.Bug, }, } @@ -93,7 +93,7 @@ func TestRegexpCheck(t *testing.T) { Fragment: `foo{job=~""}`, Lines: []int{2}, Reporter: checks.RegexpCheckName, - Text: `unnecessary regexp match on static string job=~"", use job="" instead`, + Text: "Unnecessary regexp match on static string `job=~\"\"`, use `job=\"\"` instead.", Severity: checks.Bug, }, } @@ -110,7 +110,7 @@ func TestRegexpCheck(t *testing.T) { Fragment: `foo{job=~"^.+$"}`, Lines: []int{2}, Reporter: checks.RegexpCheckName, - Text: `prometheus regexp matchers are automatically fully anchored so match for job=~"^.+$" will result in job=~"^^.+$$", remove regexp anchors ^ and/or $`, + Text: "Prometheus regexp matchers are automatically fully anchored so match for `job=~\"^.+$\"` will result in `job=~\"^^.+$$\"`, remove regexp anchors `^` and/or `$`.", Severity: checks.Bug, }, } @@ -127,7 +127,7 @@ func TestRegexpCheck(t *testing.T) { Fragment: `foo{job=~"(foo|^.+)$"}`, Lines: []int{2}, Reporter: checks.RegexpCheckName, - Text: `prometheus regexp matchers are automatically fully anchored so match for job=~"(foo|^.+)$" will result in job=~"^(foo|^.+)$$", remove regexp anchors ^ and/or $`, + Text: "Prometheus regexp matchers are automatically fully anchored so match for `job=~\"(foo|^.+)$\"` will result in `job=~\"^(foo|^.+)$$\"`, remove regexp anchors `^` and/or `$`.", Severity: checks.Bug, }, } @@ -144,7 +144,7 @@ func TestRegexpCheck(t *testing.T) { Fragment: `foo{job=~"bar"}`, Lines: []int{2}, Reporter: checks.RegexpCheckName, - Text: `unnecessary regexp match on static string job=~"bar", use job="bar" instead`, + Text: "Unnecessary regexp match on static string `job=~\"bar\"`, use `job=\"bar\"` instead.", Severity: checks.Bug, }, } @@ -161,14 +161,14 @@ func TestRegexpCheck(t *testing.T) { Fragment: `foo{job=~"bar"}`, Lines: []int{2}, Reporter: checks.RegexpCheckName, - Text: `unnecessary regexp match on static string job=~"bar", use job="bar" instead`, + Text: "Unnecessary regexp match on static string `job=~\"bar\"`, use `job=\"bar\"` instead.", Severity: checks.Bug, }, { Fragment: `foo{job=~"bar",level="total"}`, Lines: []int{2}, Reporter: checks.RegexpCheckName, - Text: `unnecessary regexp match on static string job=~"bar", use job="bar" instead`, + Text: "Unnecessary regexp match on static string `job=~\"bar\"`, use `job=\"bar\"` instead.", Severity: checks.Bug, }, } diff --git a/internal/checks/promql_series.go b/internal/checks/promql_series.go index e813bb43..98a2c00b 100644 --- a/internal/checks/promql_series.go +++ b/internal/checks/promql_series.go @@ -60,7 +60,15 @@ func (c *PromqlSeriesSettings) Validate() error { } const ( - SeriesCheckName = "promql/series" + SeriesCheckName = "promql/series" + SeriesCheckRuleDetails = `This usually means that you're deploying a set of rules where one is using the metric produced by another rule. +To avoid false positives pint won't run series checks here but that doesn't guarantee that there are no problems here. +To fully validate your changes it's best to first deploy the rules that generate the time series needed by other rules. +[Click here](https://cloudflare.github.io/pint/checks/promql/series.html#your-query-is-using-recording-rules) for more details. +` + SeriesCheckCommonProblemDetails = `[Click here](https://cloudflare.github.io/pint/checks/promql/series.html#common-problems) to see a list of common problems that might cause this.` + SeriesCheckMinAgeDetails = `You have a comment that tells pint how long can a metric be missing before it warns you about it but this comment is not formatted correctly. +[Click here](https://cloudflare.github.io/pint/checks/promql/series.html#min-age) to see supported syntax.` ) func NewSeriesCheck(prom *promapi.FailoverGroup) SeriesCheck { @@ -154,7 +162,8 @@ func (c SeriesCheck) Check(ctx context.Context, _ string, rule parser.Rule, entr Fragment: selector.String(), Lines: expr.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("%s metric is generated by alerts but didn't found any rule named %q", selector.String(), alertname), + Text: fmt.Sprintf("`%s` metric is generated by alerts but didn't found any rule named `%s`.", selector.String(), alertname), + Details: SeriesCheckCommonProblemDetails, Severity: Bug, }) } @@ -252,8 +261,9 @@ func (c SeriesCheck) Check(ctx context.Context, _ string, rule parser.Rule, entr Fragment: bareSelector.String(), Lines: expr.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("%s didn't have any series for %q metric in the last %s but found recording rule that generates it, skipping further checks", + Text: fmt.Sprintf("%s didn't have any series for `%s` metric in the last %s but found recording rule that generates it, skipping further checks.", promText(c.prom.Name(), trs.URI), bareSelector.String(), sinceDesc(trs.Series.From)), + Details: SeriesCheckRuleDetails, Severity: Information, }) continue @@ -262,11 +272,10 @@ func (c SeriesCheck) Check(ctx context.Context, _ string, rule parser.Rule, entr text, severity := c.textAndSeverity( settings, bareSelector.String(), - fmt.Sprintf("%s didn't have any series for %q metric in the last %s%s", + fmt.Sprintf("%s didn't have any series for `%s` metric in the last %s.", promText(c.prom.Name(), trs.URI), bareSelector.String(), sinceDesc(trs.Series.From), - c.checkOtherServer(ctx, selector.String()), ), Bug, ) @@ -275,6 +284,7 @@ func (c SeriesCheck) Check(ctx context.Context, _ string, rule parser.Rule, entr Lines: expr.Lines(), Reporter: c.Reporter(), Text: text, + Details: c.checkOtherServer(ctx, selector.String()), Severity: severity, }) slog.Debug("No historical series for base metric", slog.String("check", c.Reporter()), slog.String("selector", (&bareSelector).String())) @@ -311,8 +321,9 @@ func (c SeriesCheck) Check(ctx context.Context, _ string, rule parser.Rule, entr Lines: expr.Lines(), Reporter: c.Reporter(), Text: fmt.Sprintf( - "%s has %q metric but there are no series with %q label in the last %s", + "%s has `%s` metric but there are no series with `%s` label in the last %s.", promText(c.prom.Name(), trsLabelCount.URI), bareSelector.String(), name, sinceDesc(trsLabelCount.Series.From)), + Details: SeriesCheckCommonProblemDetails, Severity: Bug, }) slog.Debug("No historical series with label used for the query", slog.String("check", c.Reporter()), slog.String("selector", (&l).String()), slog.String("label", name)) @@ -347,7 +358,7 @@ func (c SeriesCheck) Check(ctx context.Context, _ string, rule parser.Rule, entr settings, bareSelector.String(), fmt.Sprintf( - "%s doesn't currently have %q, it was last present %s ago", + "%s doesn't currently have `%s`, it was last present %s ago.", promText(c.prom.Name(), trs.URI), bareSelector.String(), sinceDesc(newest(trs.Series.Ranges))), Bug, ) @@ -356,6 +367,7 @@ func (c SeriesCheck) Check(ctx context.Context, _ string, rule parser.Rule, entr Lines: expr.Lines(), Reporter: c.Reporter(), Text: text, + Details: SeriesCheckCommonProblemDetails, Severity: severity, }) slog.Debug("Series disappeared from prometheus", slog.String("check", c.Reporter()), slog.String("selector", (&bareSelector).String())) @@ -393,7 +405,7 @@ func (c SeriesCheck) Check(ctx context.Context, _ string, rule parser.Rule, entr settings, bareSelector.String(), fmt.Sprintf( - "%s has %q metric with %q label but there are no series matching {%s} in the last %s", + "%s has `%s` metric with `%s` label but there are no series matching `{%s}` in the last %s.", promText(c.prom.Name(), trsLabel.URI), bareSelector.String(), lm.Name, lm.String(), sinceDesc(trs.Series.From)), Bug, ) @@ -402,6 +414,7 @@ func (c SeriesCheck) Check(ctx context.Context, _ string, rule parser.Rule, entr Lines: expr.Lines(), Reporter: c.Reporter(), Text: text, + Details: SeriesCheckCommonProblemDetails, Severity: severity, }) slog.Debug("No historical series matching filter used in the query", @@ -454,7 +467,7 @@ func (c SeriesCheck) Check(ctx context.Context, _ string, rule parser.Rule, entr settings, bareSelector.String(), fmt.Sprintf( - "%s has %q metric but doesn't currently have series matching {%s}, such series was last present %s ago", + "%s has `%s` metric but doesn't currently have series matching `{%s}`, such series was last present %s ago.", promText(c.prom.Name(), trs.URI), bareSelector.String(), lm.String(), sinceDesc(newest(trsLabel.Series.Ranges))), Bug, ) @@ -463,6 +476,7 @@ func (c SeriesCheck) Check(ctx context.Context, _ string, rule parser.Rule, entr Lines: expr.Lines(), Reporter: c.Reporter(), Text: text, + Details: SeriesCheckCommonProblemDetails, Severity: severity, }) slog.Debug( @@ -481,9 +495,10 @@ func (c SeriesCheck) Check(ctx context.Context, _ string, rule parser.Rule, entr Lines: expr.Lines(), Reporter: c.Reporter(), Text: fmt.Sprintf( - "metric %q with label {%s} is only sometimes present on %s with average life span of %s", + "Metric `%s` with label `{%s}` is only sometimes present on %s with average life span of %s.", bareSelector.String(), lm.String(), promText(c.prom.Name(), trs.URI), output.HumanizeDuration(avgLife(trsLabel.Series.Ranges))), + Details: SeriesCheckCommonProblemDetails, Severity: Warning, }) slog.Debug( @@ -505,8 +520,9 @@ func (c SeriesCheck) Check(ctx context.Context, _ string, rule parser.Rule, entr Lines: expr.Lines(), Reporter: c.Reporter(), Text: fmt.Sprintf( - "metric %q is only sometimes present on %s with average life span of %s in the last %s", + "Metric `%s` is only sometimes present on %s with average life span of %s in the last %s.", bareSelector.String(), promText(c.prom.Name(), trs.URI), output.HumanizeDuration(avgLife(trs.Series.Ranges)), sinceDesc(trs.Series.From)), + Details: SeriesCheckCommonProblemDetails, Severity: Warning, }) slog.Debug( @@ -527,10 +543,15 @@ func (c SeriesCheck) checkOtherServer(ctx context.Context, query string) string } if len(servers) == 0 { - return "" + return SeriesCheckCommonProblemDetails } - presentProms := []string{} + var buf strings.Builder + buf.WriteRune('`') + buf.WriteString(query) + buf.WriteString("` was found on other prometheus servers:\n\n") + + var matches int for _, prom := range servers { slog.Debug("Checking if metric exists on any other Prometheus server", slog.String("check", c.Reporter()), slog.String("selector", query)) @@ -544,16 +565,27 @@ func (c SeriesCheck) checkOtherServer(ctx context.Context, query string) string series += int(s.Value) } + uri := prom.PublicURI() + if series > 0 { - presentProms = append(presentProms, prom.Name()) + matches++ + buf.WriteString("- [") + buf.WriteString(prom.Name()) + buf.WriteString("](") + buf.WriteString(uri) + buf.WriteString("/graph?g0.expr=") + buf.WriteString(query) + buf.WriteString(")\n") } } - if len(presentProms) > 0 { - return fmt.Sprintf(", %q was found on other prometheus servers: %s, are you deploying this rule to the correct instance?", query, strings.Join(presentProms, ", ")) + buf.WriteString("\nYou might be trying to deploy this rule to the wrong Prometheus server instance.\n") + + if matches > 0 { + return buf.String() } - return "" + return SeriesCheckCommonProblemDetails } func (c SeriesCheck) queryProblem(err error, selector string, expr parser.PromQLExpr) Problem { @@ -597,7 +629,8 @@ func (c SeriesCheck) getMinAge(rule parser.Rule, selector promParser.VectorSelec Fragment: cmt.String(), Lines: rule.LineRange(), Reporter: c.Reporter(), - Text: fmt.Sprintf("failed to parse pint comment as duration: %s", err), + Text: fmt.Sprintf("Failed to parse pint comment as duration: %s", err), + Details: SeriesCheckMinAgeDetails, Severity: Warning, }) } else { @@ -631,7 +664,7 @@ func (c SeriesCheck) textAndSeverity(settings *PromqlSeriesSettings, name, text slog.String("check", c.Reporter()), slog.String("metric", name), slog.String("regexp", re.String())) - return fmt.Sprintf("%s. Metric name %q matches %q check ignore regexp %q", text, name, c.Reporter(), re), Warning + return fmt.Sprintf("%s Metric name `%s` matches `%s` check ignore regexp `%s`.", text, name, c.Reporter(), re), Warning } } return text, s diff --git a/internal/checks/promql_series_test.go b/internal/checks/promql_series_test.go index 517d933f..98e5b426 100644 --- a/internal/checks/promql_series_test.go +++ b/internal/checks/promql_series_test.go @@ -17,47 +17,47 @@ func newSeriesCheck(prom *promapi.FailoverGroup) checks.RuleChecker { } func noMetricText(name, uri, metric, since string) string { - return fmt.Sprintf(`prometheus %q at %s didn't have any series for %q metric in the last %s`, name, uri, metric, since) + return fmt.Sprintf("`%s` Prometheus server at %s didn't have any series for `%s` metric in the last %s.", name, uri, metric, since) } func noMetricRRText(name, uri, metric, since string) string { - return fmt.Sprintf(`prometheus %q at %s didn't have any series for %q metric in the last %s but found recording rule that generates it, skipping further checks`, name, uri, metric, since) + return fmt.Sprintf("`%s` Prometheus server at %s didn't have any series for `%s` metric in the last %s but found recording rule that generates it, skipping further checks.", name, uri, metric, since) } func noFilterMatchText(name, uri, metric, label, filter, since string) string { - return fmt.Sprintf(`prometheus %q at %s has %q metric with %q label but there are no series matching %s in the last %s`, name, uri, metric, label, filter, since) + return fmt.Sprintf("`%s` Prometheus server at %s has `%s` metric with `%s` label but there are no series matching `%s` in the last %s.", name, uri, metric, label, filter, since) } func noLabelKeyText(name, uri, metric, label, since string) string { - return fmt.Sprintf(`prometheus %q at %s has %q metric but there are no series with %q label in the last %s`, name, uri, metric, label, since) + return fmt.Sprintf("`%s` Prometheus server at %s has `%s` metric but there are no series with `%s` label in the last %s.", name, uri, metric, label, since) } func noSeriesText(name, uri, metric, since string) string { - return fmt.Sprintf(`prometheus %q at %s didn't have any series for %q metric in the last %s`, name, uri, metric, since) + return fmt.Sprintf("`%s` Prometheus server at %s didn't have any series for `%s` metric in the last %s.", name, uri, metric, since) } func seriesDisappearedText(name, uri, metric, since string) string { - return fmt.Sprintf(`prometheus %q at %s doesn't currently have %q, it was last present %s ago`, name, uri, metric, since) + return fmt.Sprintf("`%s` Prometheus server at %s doesn't currently have `%s`, it was last present %s ago.", name, uri, metric, since) } func filterDisappeardText(name, uri, metric, filter, since string) string { - return fmt.Sprintf(`prometheus %q at %s has %q metric but doesn't currently have series matching %s, such series was last present %s ago`, name, uri, metric, filter, since) + return fmt.Sprintf("`%s` Prometheus server at %s has `%s` metric but doesn't currently have series matching `%s`, such series was last present %s ago.", name, uri, metric, filter, since) } func filterSometimesText(name, uri, metric, filter, since string) string { - return fmt.Sprintf(`metric %q with label %s is only sometimes present on prometheus %q at %s with average life span of %s`, metric, filter, name, uri, since) + return fmt.Sprintf("Metric `%s` with label `%s` is only sometimes present on `%s` Prometheus server at %s with average life span of %s.", metric, filter, name, uri, since) } func seriesSometimesText(name, uri, metric, since, avg string) string { - return fmt.Sprintf(`metric %q is only sometimes present on prometheus %q at %s with average life span of %s in the last %s`, metric, name, uri, avg, since) + return fmt.Sprintf("Metric `%s` is only sometimes present on `%s` Prometheus server at %s with average life span of %s in the last %s.", metric, name, uri, avg, since) } func alertMissing(metric, alertname string) string { - return fmt.Sprintf("%s metric is generated by alerts but didn't found any rule named %q", metric, alertname) + return fmt.Sprintf("`%s` metric is generated by alerts but didn't found any rule named `%s`.", metric, alertname) } func metricIgnored(metric, check, re string) string { - return fmt.Sprintf("Metric name %q matches %q check ignore regexp %q", metric, check, re) + return fmt.Sprintf("Metric name `%s` matches `%s` check ignore regexp `%s`.", metric, check, re) } func TestSeriesCheck(t *testing.T) { @@ -177,6 +177,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noMetricText("prom", uri, "notfound", "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -204,6 +205,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noMetricText("prom", uri, "notfound", "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -231,6 +233,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noMetricText("prom", uri, "notfound", "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -387,6 +390,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noMetricText("prom", uri, "notfound", "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -425,6 +429,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noMetricText("prom", uri, "notfound", "3d"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -453,6 +458,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noMetricRRText("prom", uri, "foo:bar", "1w"), + Details: checks.SeriesCheckRuleDetails, Severity: checks.Information, }, } @@ -494,6 +500,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noMetricRRText("prom", uri, "foo:bar", "1w"), + Details: checks.SeriesCheckRuleDetails, Severity: checks.Information, }, } @@ -543,6 +550,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: alertMissing(`ALERTS{alertname="myalert"}`, "myalert"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -561,6 +569,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noMetricRRText("prom", uri, "foo:bar", "1w"), + Details: checks.SeriesCheckRuleDetails, Severity: checks.Information, }, } @@ -637,7 +646,8 @@ func TestSeriesCheck(t *testing.T) { Fragment: "notfound", Lines: []int{2}, Reporter: checks.SeriesCheckName, - Text: noMetricText("prom", uri, "notfound", "1w") + ". " + metricIgnored("notfound", checks.SeriesCheckName, "^not.+$"), + Text: noMetricText("prom", uri, "notfound", "1w") + " " + metricIgnored("notfound", checks.SeriesCheckName, "^not.+$"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Warning, }, } @@ -665,6 +675,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noLabelKeyText("prom", uri, "found", "notfound", "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -766,6 +777,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noLabelKeyText("prom", uri, "found", "job", "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -822,6 +834,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: seriesSometimesText("prom", uri, `found`, "1w", "5m"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Warning, }, } @@ -947,6 +960,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: seriesSometimesText("prom", uri, `found`, "1w", "1d5m"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Warning, }, } @@ -1072,6 +1086,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: seriesSometimesText("prom", uri, `found`, "1w", "1d5m"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Warning, }, } @@ -1268,6 +1283,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: seriesDisappearedText("prom", uri, "found", "4d"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -1358,7 +1374,8 @@ func TestSeriesCheck(t *testing.T) { Fragment: `found`, Lines: []int{2}, Reporter: checks.SeriesCheckName, - Text: seriesDisappearedText("prom", uri, "found", "4d") + ". " + metricIgnored("found", checks.SeriesCheckName, "^found$"), + Text: seriesDisappearedText("prom", uri, "found", "4d") + " " + metricIgnored("found", checks.SeriesCheckName, "^found$"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Warning, }, } @@ -1567,6 +1584,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{4}, Reporter: checks.SeriesCheckName, Text: seriesDisappearedText("prom", uri, "found", "4d"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -1652,6 +1670,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{4}, Reporter: checks.SeriesCheckName, Text: seriesDisappearedText("prom", uri, "found", "4d"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -1736,7 +1755,8 @@ func TestSeriesCheck(t *testing.T) { Fragment: `rule/set promql/series(found) min-age foo`, Lines: []int{2, 3, 4}, Reporter: checks.SeriesCheckName, - Text: `failed to parse pint comment as duration: not a valid duration string: "foo"`, + Text: `Failed to parse pint comment as duration: not a valid duration string: "foo"`, + Details: checks.SeriesCheckMinAgeDetails, Severity: checks.Warning, }, { @@ -1744,6 +1764,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{4}, Reporter: checks.SeriesCheckName, Text: seriesDisappearedText("prom", uri, "found", "4d"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -1834,7 +1855,8 @@ func TestSeriesCheck(t *testing.T) { Fragment: `found{instance!~"bad",instance=~".+",not!="negative",notfound="notfound"}`, Lines: []int{2}, Reporter: checks.SeriesCheckName, - Text: noFilterMatchText("prom", uri, "found", "notfound", `{notfound="notfound"}`, "1w") + ". " + metricIgnored("found", checks.SeriesCheckName, "^found$"), + Text: noFilterMatchText("prom", uri, "found", "notfound", `{notfound="notfound"}`, "1w") + " " + metricIgnored("found", checks.SeriesCheckName, "^found$"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Warning, }, } @@ -1903,6 +1925,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noFilterMatchText("prom", uri, "found", "notfound", `{notfound="notfound"}`, "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -2025,6 +2048,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noFilterMatchText("prom", uri, "sometimes", "churn", `{churn="notfound"}`, "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -2162,6 +2186,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: filterDisappeardText("prom", uri, "found", `{removed="xxx"}`, "5d16h"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -2237,7 +2262,8 @@ func TestSeriesCheck(t *testing.T) { Fragment: `rule/set promql/series(found) min-age 1e`, Lines: []int{3, 4}, Reporter: checks.SeriesCheckName, - Text: `failed to parse pint comment as duration: unknown unit "e" in duration "1e"`, + Text: `Failed to parse pint comment as duration: unknown unit "e" in duration "1e"`, + Details: checks.SeriesCheckMinAgeDetails, Severity: checks.Warning, }, { @@ -2245,6 +2271,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{4}, Reporter: checks.SeriesCheckName, Text: filterDisappeardText("prom", uri, "found", `{removed="xxx"}`, "5d16h"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -2383,6 +2410,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: filterSometimesText("prom", uri, `found`, `{sometimes="xxx"}`, "18h45m"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Warning, }, } @@ -2485,6 +2513,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: seriesSometimesText("prom", uri, "sometimes", "1w", "35m"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Warning, }, } @@ -2606,6 +2635,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noFilterMatchText("prom", uri, "found", "job", `{job="notfound"}`, "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -2660,6 +2690,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noSeriesText("prom", uri, "notfound", "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -2703,6 +2734,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{3}, Reporter: checks.SeriesCheckName, Text: noSeriesText("prom", uri, "notfound", "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -2857,6 +2889,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{4}, Reporter: checks.SeriesCheckName, Text: noMetricText("prom", uri, "notfound", "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -2888,6 +2921,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{4}, Reporter: checks.SeriesCheckName, Text: noMetricText("prom", uri, "notfound", "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -2941,6 +2975,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{4}, Reporter: checks.SeriesCheckName, Text: noSeriesText("prom", uri, "notfound", "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -2982,6 +3017,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noMetricRRText("prom", uri, "foo:count", "1w"), + Details: checks.SeriesCheckRuleDetails, Severity: checks.Information, }, { @@ -2989,6 +3025,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noMetricRRText("prom", uri, "foo:sum", "1w"), + Details: checks.SeriesCheckRuleDetails, Severity: checks.Information, }, } @@ -3044,6 +3081,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noSeriesText("prom", uri, `{__name__=~"(foo|bar)_panics_total"}`, "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -3098,6 +3136,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noFilterMatchText("prom", uri, `{__name__=~"(foo|bar)_panics_total"}`, "job", `{job="myjob"}`, "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } @@ -3161,6 +3200,7 @@ func TestSeriesCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.SeriesCheckName, Text: noSeriesText("prom", uri, "notfound", "1w"), + Details: checks.SeriesCheckCommonProblemDetails, Severity: checks.Bug, }, } diff --git a/internal/checks/promql_syntax.go b/internal/checks/promql_syntax.go index 36bfa1de..419cf5a0 100644 --- a/internal/checks/promql_syntax.go +++ b/internal/checks/promql_syntax.go @@ -9,7 +9,8 @@ import ( ) const ( - SyntaxCheckName = "promql/syntax" + SyntaxCheckName = "promql/syntax" + SyntaxCheckDetails = "[Click here](https://prometheus.io/docs/prometheus/latest/querying/basics/) for PromQL documentation." ) func NewSyntaxCheck() SyntaxCheck { @@ -37,7 +38,8 @@ func (c SyntaxCheck) Check(_ context.Context, _ string, rule parser.Rule, _ []di Fragment: q.Value.Value, Lines: q.Value.Position.Lines, Reporter: c.Reporter(), - Text: fmt.Sprintf("syntax error: %s", q.SyntaxError), + Text: fmt.Sprintf("Prometheus failed to parse the query with this PromQL error: %s.", q.SyntaxError), + Details: SyntaxCheckDetails, Severity: Fatal, }) } diff --git a/internal/checks/promql_syntax_test.go b/internal/checks/promql_syntax_test.go index 9d5987a3..5b715a34 100644 --- a/internal/checks/promql_syntax_test.go +++ b/internal/checks/promql_syntax_test.go @@ -38,7 +38,8 @@ func TestSyntaxCheck(t *testing.T) { Fragment: "sum(", Lines: []int{2}, Reporter: "promql/syntax", - Text: "syntax error: no arguments for aggregate expression provided", + Text: "Prometheus failed to parse the query with this PromQL error: no arguments for aggregate expression provided.", + Details: checks.SyntaxCheckDetails, Severity: checks.Fatal, }, } @@ -55,7 +56,8 @@ func TestSyntaxCheck(t *testing.T) { Fragment: "sum(foo) by(", Lines: []int{2}, Reporter: "promql/syntax", - Text: "syntax error: unclosed left parenthesis", + Text: "Prometheus failed to parse the query with this PromQL error: unclosed left parenthesis.", + Details: checks.SyntaxCheckDetails, Severity: checks.Fatal, }, } diff --git a/internal/checks/promql_vector_matching.go b/internal/checks/promql_vector_matching.go index 97502f44..8b019fca 100644 --- a/internal/checks/promql_vector_matching.go +++ b/internal/checks/promql_vector_matching.go @@ -18,7 +18,10 @@ import ( ) const ( - VectorMatchingCheckName = "promql/vector_matching" + VectorMatchingCheckName = "promql/vector_matching" + VectorMatchingCheckDetails = `Trying to match two different time series together will only work if both have the exact same set of labels. +You can match time series with different labels by using special keywords and follow the rules set by PromQL. +[Click here](https://prometheus.io/docs/prometheus/latest/querying/operators/#vector-matching) to read PromQL documentation that explains it.` ) func NewVectorMatchingCheck(prom *promapi.FailoverGroup) VectorMatchingCheck { @@ -53,6 +56,7 @@ func (c VectorMatchingCheck) Check(ctx context.Context, _ string, rule parser.Ru Lines: expr.Lines(), Reporter: c.Reporter(), Text: problem.text, + Details: problem.details, Severity: problem.severity, }) } @@ -115,7 +119,8 @@ func (c VectorMatchingCheck) checkNode(ctx context.Context, node *parser.PromQLN if rv, ok := rhsMatchers[k]; ok && rv != lv { problems = append(problems, exprProblem{ expr: node.Expr, - text: fmt.Sprintf("left hand side uses {%s=%q} while right hand side uses {%s=%q}, this will never match", k, lv, k, rv), + text: fmt.Sprintf("The left hand side uses `{%s=%q}` while the right hand side uses `{%s=%q}`, this will never match.", k, lv, k, rv), + details: VectorMatchingCheckDetails, severity: Bug, }) return problems @@ -156,21 +161,24 @@ func (c VectorMatchingCheck) checkNode(ctx context.Context, node *parser.PromQLN if !leftLabels.hasName(name) && rightLabels.hasName(name) { problems = append(problems, exprProblem{ expr: node.Expr, - text: fmt.Sprintf("using on(%q) won't produce any results because left hand side of the query doesn't have this label: %q", name, node.Node.(*promParser.BinaryExpr).LHS), + text: fmt.Sprintf("Using `on(%s)` won't produce any results because the left hand side of the query doesn't have this label: `%s`.", name, node.Node.(*promParser.BinaryExpr).LHS), + details: VectorMatchingCheckDetails, severity: Bug, }) } if leftLabels.hasName(name) && !rightLabels.hasName(name) { problems = append(problems, exprProblem{ expr: node.Expr, - text: fmt.Sprintf("using on(%q) won't produce any results because right hand side of the query doesn't have this label: %q", name, node.Node.(*promParser.BinaryExpr).RHS), + text: fmt.Sprintf("Using `on(%s)` won't produce any results because the right hand side of the query doesn't have this label: `%s`.", name, node.Node.(*promParser.BinaryExpr).RHS), + details: VectorMatchingCheckDetails, severity: Bug, }) } if !leftLabels.hasName(name) && !rightLabels.hasName(name) { problems = append(problems, exprProblem{ expr: node.Expr, - text: fmt.Sprintf("using on(%q) won't produce any results because both sides of the query don't have this label", name), + text: fmt.Sprintf("Using `on(%s)` won't produce any results because both sides of the query don't have this label.", name), + details: VectorMatchingCheckDetails, severity: Bug, }) } @@ -180,13 +188,15 @@ func (c VectorMatchingCheck) checkNode(ctx context.Context, node *parser.PromQLN if len(n.VectorMatching.MatchingLabels) == 0 { problems = append(problems, exprProblem{ expr: node.Expr, - text: fmt.Sprintf("both sides of the query have different labels: %s != %s", l, r), + text: fmt.Sprintf("This query will never return anything because the right and the left hand side have different labels: `%s` != `%s`.", l, r), + details: VectorMatchingCheckDetails, severity: Bug, }) } else { problems = append(problems, exprProblem{ expr: node.Expr, - text: fmt.Sprintf("using ignoring(%q) won't produce any results because both sides of the query have different labels: %s != %s", strings.Join(n.VectorMatching.MatchingLabels, ","), l, r), + text: fmt.Sprintf("Using `ignoring(%s)` won't produce any results because both sides of the query have different labels: `%s` != `%s`.", strings.Join(n.VectorMatching.MatchingLabels, ","), l, r), + details: VectorMatchingCheckDetails, severity: Bug, }) } diff --git a/internal/checks/promql_vector_matching_test.go b/internal/checks/promql_vector_matching_test.go index ef6be54d..9bb37c2c 100644 --- a/internal/checks/promql_vector_matching_test.go +++ b/internal/checks/promql_vector_matching_test.go @@ -16,15 +16,15 @@ func newVectorMatchingCheck(prom *promapi.FailoverGroup) checks.RuleChecker { } func differentLabelsText(l, r string) string { - return fmt.Sprintf(`both sides of the query have different labels: [%s] != [%s]`, l, r) + return fmt.Sprintf("This query will never return anything because the right and the left hand side have different labels: `[%s]` != `[%s]`.", l, r) } func usingMismatchText(f, l, r string) string { - return fmt.Sprintf(`using %s won't produce any results because both sides of the query have different labels: [%s] != [%s]`, f, l, r) + return fmt.Sprintf("Using `%s` won't produce any results because both sides of the query have different labels: `[%s]` != `[%s]`.", f, l, r) } func differentFilters(k, lv, rv string) string { - return fmt.Sprintf("left hand side uses {%s=%q} while right hand side uses {%s=%q}, this will never match", k, lv, k, rv) + return fmt.Sprintf("The left hand side uses `{%s=%q}` while the right hand side uses `{%s=%q}`, this will never match.", k, lv, k, rv) } func TestVectorMatchingCheck(t *testing.T) { @@ -55,6 +55,7 @@ func TestVectorMatchingCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.VectorMatchingCheckName, Text: differentLabelsText("instance, job, notfound", "instance, job"), + Details: checks.VectorMatchingCheckDetails, Severity: checks.Bug, }, } @@ -196,7 +197,8 @@ func TestVectorMatchingCheck(t *testing.T) { Fragment: "foo / ignoring(xxx) app_registry", Lines: []int{2}, Reporter: checks.VectorMatchingCheckName, - Text: usingMismatchText(`ignoring("xxx")`, "instance, job", "app_name"), + Text: usingMismatchText(`ignoring(xxx)`, "instance, job", "app_name"), + Details: checks.VectorMatchingCheckDetails, Severity: checks.Bug, }, } @@ -253,7 +255,8 @@ func TestVectorMatchingCheck(t *testing.T) { Fragment: "foo / on(notfound) bar", Lines: []int{2}, Reporter: checks.VectorMatchingCheckName, - Text: `using on("notfound") won't produce any results because both sides of the query don't have this label`, + Text: "Using `on(notfound)` won't produce any results because both sides of the query don't have this label.", + Details: checks.VectorMatchingCheckDetails, Severity: checks.Bug, }, } @@ -499,7 +502,8 @@ func TestVectorMatchingCheck(t *testing.T) { Fragment: "foo / on(notfound) bar_with_notfound", Lines: []int{2}, Reporter: checks.VectorMatchingCheckName, - Text: `using on("notfound") won't produce any results because left hand side of the query doesn't have this label: "foo"`, + Text: "Using `on(notfound)` won't produce any results because the left hand side of the query doesn't have this label: `foo`.", + Details: checks.VectorMatchingCheckDetails, Severity: checks.Bug, }, } @@ -554,7 +558,8 @@ func TestVectorMatchingCheck(t *testing.T) { Fragment: "foo_with_notfound / on(notfound) bar", Lines: []int{2}, Reporter: checks.VectorMatchingCheckName, - Text: `using on("notfound") won't produce any results because right hand side of the query doesn't have this label: "bar"`, + Text: "Using `on(notfound)` won't produce any results because the right hand side of the query doesn't have this label: `bar`.", + Details: checks.VectorMatchingCheckDetails, Severity: checks.Bug, }, } @@ -609,7 +614,8 @@ func TestVectorMatchingCheck(t *testing.T) { Fragment: "(memory_bytes / ignoring(job) (memory_limit > 0)) * on(app_name) group_left(a,b,c) app_registry", Lines: []int{2}, Reporter: checks.VectorMatchingCheckName, - Text: `using on("app_name") won't produce any results because left hand side of the query doesn't have this label: "(memory_bytes / ignoring (job) (memory_limit > 0))"`, + Text: "Using `on(app_name)` won't produce any results because the left hand side of the query doesn't have this label: `(memory_bytes / ignoring (job) (memory_limit > 0))`.", + Details: checks.VectorMatchingCheckDetails, Severity: checks.Bug, }, } @@ -797,7 +803,8 @@ func TestVectorMatchingCheck(t *testing.T) { Fragment: "min_over_time((foo_with_notfound > 0)[30m:1m]) / bar", Lines: []int{2}, Reporter: checks.VectorMatchingCheckName, - Text: `both sides of the query have different labels: [instance, job, notfound] != [instance, job]`, + Text: "This query will never return anything because the right and the left hand side have different labels: `[instance, job, notfound]` != `[instance, job]`.", + Details: checks.VectorMatchingCheckDetails, Severity: checks.Bug, }, } @@ -925,7 +932,8 @@ func TestVectorMatchingCheck(t *testing.T) { Fragment: "(foo / ignoring(notfound) foo_with_notfound) / (memory_bytes / ignoring(job) memory_limit)", Lines: []int{2}, Reporter: checks.VectorMatchingCheckName, - Text: "both sides of the query have different labels: [instance, job] != [dev, instance, job]", + Text: "This query will never return anything because the right and the left hand side have different labels: `[instance, job]` != `[dev, instance, job]`.", + Details: checks.VectorMatchingCheckDetails, Severity: checks.Bug, }, } @@ -1173,6 +1181,7 @@ func TestVectorMatchingCheck(t *testing.T) { Lines: []int{2}, Reporter: checks.VectorMatchingCheckName, Text: differentFilters("job", "a", "b"), + Details: checks.VectorMatchingCheckDetails, Severity: checks.Bug, }, } diff --git a/internal/checks/query_cost.go b/internal/checks/query_cost.go index a39b967e..5f20adf4 100644 --- a/internal/checks/query_cost.go +++ b/internal/checks/query_cost.go @@ -92,7 +92,9 @@ func (c CostCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ []di severity := Information if c.maxSeries > 0 && series > c.maxSeries { severity = c.severity - above = fmt.Sprintf(", maximum allowed series is %d", c.maxSeries) + above = fmt.Sprintf(", maximum allowed series is %d.", c.maxSeries) + } else { + estimate += "." } problems = append(problems, Problem{ @@ -108,7 +110,7 @@ func (c CostCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ []di Fragment: expr.Value.Value, Lines: expr.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("%s queried %d samples in total when executing this query, which is more than the configured limit of %d", promText(c.prom.Name(), qr.URI), qr.Stats.Samples.TotalQueryableSamples, c.maxTotalSamples), + Text: fmt.Sprintf("%s queried %d samples in total when executing this query, which is more than the configured limit of %d.", promText(c.prom.Name(), qr.URI), qr.Stats.Samples.TotalQueryableSamples, c.maxTotalSamples), Severity: c.severity, }) } @@ -118,7 +120,7 @@ func (c CostCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ []di Fragment: expr.Value.Value, Lines: expr.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("%s queried %d peak samples when executing this query, which is more than the configured limit of %d", promText(c.prom.Name(), qr.URI), qr.Stats.Samples.PeakSamples, c.maxPeakSamples), + Text: fmt.Sprintf("%s queried %d peak samples when executing this query, which is more than the configured limit of %d.", promText(c.prom.Name(), qr.URI), qr.Stats.Samples.PeakSamples, c.maxPeakSamples), Severity: c.severity, }) } @@ -129,7 +131,7 @@ func (c CostCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ []di Fragment: expr.Value.Value, Lines: expr.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("%s took %s when executing this query, which is more than the configured limit of %s", promText(c.prom.Name(), qr.URI), output.HumanizeDuration(evalDur), output.HumanizeDuration(c.maxEvaluationDuration)), + Text: fmt.Sprintf("%s took %s when executing this query, which is more than the configured limit of %s.", promText(c.prom.Name(), qr.URI), output.HumanizeDuration(evalDur), output.HumanizeDuration(c.maxEvaluationDuration)), Severity: c.severity, }) } diff --git a/internal/checks/query_cost_test.go b/internal/checks/query_cost_test.go index 04931ed6..8dac1df3 100644 --- a/internal/checks/query_cost_test.go +++ b/internal/checks/query_cost_test.go @@ -12,7 +12,7 @@ import ( ) func costText(name, uri string, count int) string { - return fmt.Sprintf(`prometheus %q at %s returned %d result(s)`, name, uri, count) + return fmt.Sprintf("`%s` Prometheus server at %s returned %d result(s)", name, uri, count) } func memUsageText(b string) string { @@ -24,15 +24,15 @@ func maxSeriesText(m int) string { } func evalDurText(name, uri, dur, limit string) string { - return fmt.Sprintf(`prometheus %q at %s took %s when executing this query, which is more than the configured limit of %s`, name, uri, dur, limit) + return fmt.Sprintf("`%s` Prometheus server at %s took %s when executing this query, which is more than the configured limit of %s.", name, uri, dur, limit) } func totalSamplesText(name, uri string, total, limit int) string { - return fmt.Sprintf(`prometheus %q at %s queried %d samples in total when executing this query, which is more than the configured limit of %d`, name, uri, total, limit) + return fmt.Sprintf("`%s` Prometheus server at %s queried %d samples in total when executing this query, which is more than the configured limit of %d.", name, uri, total, limit) } func peakSamplesText(name, uri string, total, limit int) string { - return fmt.Sprintf(`prometheus %q at %s queried %d peak samples when executing this query, which is more than the configured limit of %d`, name, uri, total, limit) + return fmt.Sprintf("`%s` Prometheus server at %s queried %d peak samples when executing this query, which is more than the configured limit of %d.", name, uri, total, limit) } func TestCostCheck(t *testing.T) { @@ -61,7 +61,7 @@ func TestCostCheck(t *testing.T) { Fragment: "sum(foo)", Lines: []int{2}, Reporter: "query/cost", - Text: costText("prom", uri, 0), + Text: costText("prom", uri, 0) + ".", Severity: checks.Information, }, } @@ -168,7 +168,7 @@ func TestCostCheck(t *testing.T) { Fragment: "sum(foo)", Lines: []int{2}, Reporter: "query/cost", - Text: costText("prom", uri, 1) + memUsageText("4.0KiB"), + Text: costText("prom", uri, 1) + memUsageText("4.0KiB") + ".", Severity: checks.Information, }, } @@ -207,7 +207,7 @@ func TestCostCheck(t *testing.T) { Fragment: "sum(foo)", Lines: []int{2}, Reporter: "query/cost", - Text: costText("prom", uri, 7) + memUsageText("707B"), + Text: costText("prom", uri, 7) + memUsageText("707B") + ".", Severity: checks.Information, }, } @@ -256,7 +256,7 @@ func TestCostCheck(t *testing.T) { Fragment: "sum(foo)", Lines: []int{2}, Reporter: "query/cost", - Text: costText("prom", uri, 7) + memUsageText("7.0MiB"), + Text: costText("prom", uri, 7) + memUsageText("7.0MiB") + ".", Severity: checks.Information, }, } @@ -305,7 +305,7 @@ func TestCostCheck(t *testing.T) { Fragment: "sum(foo)", Lines: []int{2}, Reporter: "query/cost", - Text: costText("prom", uri, 7) + memUsageText("7.0KiB") + maxSeriesText(1), + Text: costText("prom", uri, 7) + memUsageText("7.0KiB") + maxSeriesText(1) + ".", Severity: checks.Bug, }, } @@ -354,7 +354,7 @@ func TestCostCheck(t *testing.T) { Fragment: "sum(foo)", Lines: []int{2}, Reporter: "query/cost", - Text: costText("prom", uri, 6) + maxSeriesText(5), + Text: costText("prom", uri, 6) + maxSeriesText(5) + ".", Severity: checks.Bug, }, } @@ -398,7 +398,7 @@ func TestCostCheck(t *testing.T) { Fragment: "sum(foo)", Lines: []int{2}, Reporter: "query/cost", - Text: costText("prom", uri, 7) + maxSeriesText(5), + Text: costText("prom", uri, 7) + maxSeriesText(5) + ".", Severity: checks.Information, }, } @@ -446,7 +446,7 @@ func TestCostCheck(t *testing.T) { Fragment: `sum({__name__="foo"})`, Lines: []int{3}, Reporter: "query/cost", - Text: costText("prom", uri, 7) + memUsageText("707B"), + Text: costText("prom", uri, 7) + memUsageText("707B") + ".", Severity: checks.Information, }, } @@ -495,7 +495,7 @@ func TestCostCheck(t *testing.T) { Fragment: "sum(foo)", Lines: []int{2}, Reporter: "query/cost", - Text: costText("prom", uri, 1) + memUsageText("4.0KiB"), + Text: costText("prom", uri, 1) + memUsageText("4.0KiB") + ".", Severity: checks.Information, }, } @@ -541,7 +541,7 @@ func TestCostCheck(t *testing.T) { Fragment: "sum(foo)", Lines: []int{2}, Reporter: "query/cost", - Text: costText("prom", uri, 1) + memUsageText("4.0KiB"), + Text: costText("prom", uri, 1) + memUsageText("4.0KiB") + ".", Severity: checks.Information, }, { @@ -612,7 +612,7 @@ func TestCostCheck(t *testing.T) { Fragment: "sum(foo)", Lines: []int{2}, Reporter: "query/cost", - Text: costText("prom", uri, 1) + memUsageText("4.0KiB"), + Text: costText("prom", uri, 1) + memUsageText("4.0KiB") + ".", Severity: checks.Information, }, { diff --git a/internal/checks/rule_duplicate.go b/internal/checks/rule_duplicate.go index d859ecb0..afdec0e8 100644 --- a/internal/checks/rule_duplicate.go +++ b/internal/checks/rule_duplicate.go @@ -75,7 +75,7 @@ func (c RuleDuplicateCheck) compareRules(_ context.Context, rule *parser.Recordi Fragment: fmt.Sprintf("%s: %s", rule.Record.Key.Value, rule.Record.Value.Value), Lines: rule.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("duplicated rule, identical rule found at %s:%d", entry.ReportedPath, entry.Rule.RecordingRule.Record.Key.Position.FirstLine()), + Text: fmt.Sprintf("Duplicated rule, identical rule found at %s:%d.", entry.ReportedPath, entry.Rule.RecordingRule.Record.Key.Position.FirstLine()), Severity: Bug, }) } diff --git a/internal/checks/rule_duplicate_test.go b/internal/checks/rule_duplicate_test.go index a035d624..574a5fee 100644 --- a/internal/checks/rule_duplicate_test.go +++ b/internal/checks/rule_duplicate_test.go @@ -11,7 +11,7 @@ import ( ) func textDuplicateRule(path string, line int) string { - return fmt.Sprintf("duplicated rule, identical rule found at %s:%d", path, line) + return fmt.Sprintf("Duplicated rule, identical rule found at %s:%d.", path, line) } func TestRuleDuplicateCheck(t *testing.T) { @@ -156,8 +156,9 @@ func TestRuleDuplicateCheck(t *testing.T) { prometheus: func(uri string) *promapi.FailoverGroup { return promapi.NewFailoverGroup( "prom", + uri, []*promapi.Prometheus{ - promapi.NewPrometheus("prom", uri, map[string]string{}, time.Second, 4, 100, nil), + promapi.NewPrometheus("prom", uri, "", map[string]string{}, time.Second, 4, 100, nil), }, true, "up", diff --git a/internal/checks/rule_for.go b/internal/checks/rule_for.go index efe03ac9..bbfea95f 100644 --- a/internal/checks/rule_for.go +++ b/internal/checks/rule_for.go @@ -85,7 +85,7 @@ func (c RuleForCheck) Check(_ context.Context, _ string, rule parser.Rule, _ []d Fragment: fragment, Lines: lines, Reporter: c.Reporter(), - Text: fmt.Sprintf("this alert rule must have a '%s' field with a minimum duration of %s", c.key, output.HumanizeDuration(c.minFor)), + Text: fmt.Sprintf("This alert rule must have a `%s` field with a minimum duration of %s.", c.key, output.HumanizeDuration(c.minFor)), Severity: c.severity, }) } @@ -95,7 +95,7 @@ func (c RuleForCheck) Check(_ context.Context, _ string, rule parser.Rule, _ []d Fragment: fragment, Lines: lines, Reporter: c.Reporter(), - Text: fmt.Sprintf("this alert rule must have a '%s' field with a maximum duration of %s", c.key, output.HumanizeDuration(c.maxFor)), + Text: fmt.Sprintf("This alert rule must have a `%s` field with a maximum duration of %s.", c.key, output.HumanizeDuration(c.maxFor)), Severity: c.severity, }) } diff --git a/internal/checks/rule_for_test.go b/internal/checks/rule_for_test.go index 7628e8c2..f61f6e55 100644 --- a/internal/checks/rule_for_test.go +++ b/internal/checks/rule_for_test.go @@ -10,11 +10,11 @@ import ( ) func forMin(key, min string) string { - return fmt.Sprintf("this alert rule must have a '%s' field with a minimum duration of %s", key, min) + return fmt.Sprintf("This alert rule must have a `%s` field with a minimum duration of %s.", key, min) } func forMax(key, max string) string { - return fmt.Sprintf("this alert rule must have a '%s' field with a maximum duration of %s", key, max) + return fmt.Sprintf("This alert rule must have a `%s` field with a maximum duration of %s.", key, max) } func TestRuleForCheck(t *testing.T) { diff --git a/internal/checks/rule_label.go b/internal/checks/rule_label.go index 0d05de0f..20d55d85 100644 --- a/internal/checks/rule_label.go +++ b/internal/checks/rule_label.go @@ -54,7 +54,7 @@ func (c LabelCheck) checkRecordingRule(rule parser.Rule) (problems []Problem) { Fragment: fmt.Sprintf("%s: %s", rule.RecordingRule.Record.Key.Value, rule.RecordingRule.Record.Value.Value), Lines: rule.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("%s label is required", c.key), + Text: fmt.Sprintf("`%s` label is required.", c.key), Severity: c.severity, }) } @@ -68,7 +68,7 @@ func (c LabelCheck) checkRecordingRule(rule parser.Rule) (problems []Problem) { Fragment: fmt.Sprintf("%s:", rule.RecordingRule.Labels.Key.Value), Lines: rule.RecordingRule.Labels.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("%s label is required", c.key), + Text: fmt.Sprintf("`%s` label is required.", c.key), Severity: c.severity, }) } @@ -87,7 +87,7 @@ func (c LabelCheck) checkAlertingRule(rule parser.Rule) (problems []Problem) { Fragment: fmt.Sprintf("%s: %s", rule.AlertingRule.Alert.Key.Value, rule.AlertingRule.Alert.Value.Value), Lines: rule.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("%s label is required", c.key), + Text: fmt.Sprintf("`%s` label is required.", c.key), Severity: c.severity, }) } @@ -101,7 +101,7 @@ func (c LabelCheck) checkAlertingRule(rule parser.Rule) (problems []Problem) { Fragment: fmt.Sprintf("%s:", rule.AlertingRule.Labels.Key.Value), Lines: rule.AlertingRule.Labels.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("%s label is required", c.key), + Text: fmt.Sprintf("`%s` label is required.", c.key), Severity: c.severity, }) } @@ -119,7 +119,7 @@ func (c LabelCheck) checkValue(rule parser.Rule, val *parser.YamlNode) (problems Fragment: fmt.Sprintf("%s: %s", c.key, val.Value), Lines: val.Position.Lines, Reporter: c.Reporter(), - Text: fmt.Sprintf("%s label value must match %q", c.key, c.valueRe.anchored), + Text: fmt.Sprintf("`%s` label value must match `%s`.", c.key, c.valueRe.anchored), Severity: c.severity, }) } diff --git a/internal/checks/rule_label_test.go b/internal/checks/rule_label_test.go index d0822c99..90c5c8fe 100644 --- a/internal/checks/rule_label_test.go +++ b/internal/checks/rule_label_test.go @@ -22,7 +22,7 @@ func TestLabelCheck(t *testing.T) { Fragment: "record: foo", Lines: []int{1, 2}, Reporter: "rule/label", - Text: "severity label is required", + Text: "`severity` label is required.", Severity: checks.Warning, }, } @@ -41,7 +41,7 @@ func TestLabelCheck(t *testing.T) { Fragment: "record: foo", Lines: []int{1, 2}, Reporter: "rule/label", - Text: "severity label is required", + Text: "`severity` label is required.", Severity: checks.Warning, }, } @@ -69,7 +69,7 @@ func TestLabelCheck(t *testing.T) { Fragment: "labels:", Lines: []int{3, 4}, Reporter: "rule/label", - Text: "severity label is required", + Text: "`severity` label is required.", Severity: checks.Warning, }, } @@ -97,7 +97,7 @@ func TestLabelCheck(t *testing.T) { Fragment: "severity: warning", Lines: []int{4}, Reporter: "rule/label", - Text: `severity label value must match "^critical$"`, + Text: "`severity` label value must match `^critical$`.", Severity: checks.Warning, }, } @@ -116,7 +116,7 @@ func TestLabelCheck(t *testing.T) { Fragment: "severity: warning", Lines: []int{4}, Reporter: "rule/label", - Text: `severity label value must match "^critical$"`, + Text: "`severity` label value must match `^critical$`.", Severity: checks.Warning, }, } @@ -135,7 +135,7 @@ func TestLabelCheck(t *testing.T) { Fragment: "priority: 2a", Lines: []int{4}, Reporter: "rule/label", - Text: `priority label value must match "^(1|2|3)$"`, + Text: "`priority` label value must match `^(1|2|3)$`.", Severity: checks.Warning, }, } @@ -154,7 +154,7 @@ func TestLabelCheck(t *testing.T) { Fragment: "priority: 2a", Lines: []int{4}, Reporter: "rule/label", - Text: `priority label value must match "^(1|2|3)$"`, + Text: "`priority` label value must match `^(1|2|3)$`.", Severity: checks.Warning, }, } @@ -173,7 +173,7 @@ func TestLabelCheck(t *testing.T) { Fragment: "alert: foo", Lines: []int{1, 2}, Reporter: "rule/label", - Text: "severity label is required", + Text: "`severity` label is required.", Severity: checks.Warning, }, } @@ -201,7 +201,7 @@ func TestLabelCheck(t *testing.T) { Fragment: "labels:", Lines: []int{3, 4}, Reporter: "rule/label", - Text: "severity label is required", + Text: "`severity` label is required.", Severity: checks.Warning, }, } @@ -229,7 +229,7 @@ func TestLabelCheck(t *testing.T) { Fragment: "severity: warning", Lines: []int{4}, Reporter: "rule/label", - Text: `severity label value must match "^critical|info$"`, + Text: "`severity` label value must match `^critical|info$`.", Severity: checks.Warning, }, } @@ -248,7 +248,7 @@ func TestLabelCheck(t *testing.T) { Fragment: "severity: warning", Lines: []int{4}, Reporter: "rule/label", - Text: `severity label value must match "^critical|info$"`, + Text: "`severity` label value must match `^critical|info$`.", Severity: checks.Warning, }, } @@ -312,7 +312,7 @@ func TestLabelCheck(t *testing.T) { Fragment: "for: must wait 5m to fire", Lines: []int{5}, Reporter: "rule/label", - Text: `for label value must match "^must wait {{$for}} to fire$"`, + Text: "`for` label value must match `^must wait {{$for}} to fire$`.", Severity: checks.Warning, }, } diff --git a/internal/checks/rule_link.go b/internal/checks/rule_link.go index 0034757c..50e8bb5e 100644 --- a/internal/checks/rule_link.go +++ b/internal/checks/rule_link.go @@ -102,7 +102,7 @@ func (c RuleLinkCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ Fragment: ann.Value.Value, Lines: ann.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("GET request for %s returned an error: %s", uri, err), + Text: fmt.Sprintf("GET request for %s returned an error: %s.", uri, err), Severity: c.severity, }) slog.Debug("Link request returned an error", slog.String("uri", uri), slog.Any("err", err)) @@ -116,7 +116,7 @@ func (c RuleLinkCheck) Check(ctx context.Context, _ string, rule parser.Rule, _ Fragment: ann.Value.Value, Lines: ann.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("GET request for %s returned invalid status code: %s", uri, resp.Status), + Text: fmt.Sprintf("GET request for %s returned invalid status code: `%s`.", uri, resp.Status), Severity: c.severity, }) slog.Debug("Link request returned invalid status code", slog.String("uri", uri), slog.String("status", resp.Status)) diff --git a/internal/checks/rule_link_test.go b/internal/checks/rule_link_test.go index 20689ed8..fba8189b 100644 --- a/internal/checks/rule_link_test.go +++ b/internal/checks/rule_link_test.go @@ -96,7 +96,7 @@ func TestRuleLinkCheck(t *testing.T) { Fragment: "http://", Lines: []int{4}, Reporter: "rule/link", - Text: `GET request for http: returned an error: Get "http:": http: no Host in request URL`, + Text: `GET request for http: returned an error: Get "http:": http: no Host in request URL.`, Severity: checks.Bug, }, } @@ -136,7 +136,7 @@ func TestRuleLinkCheck(t *testing.T) { Fragment: fmt.Sprintf("%s/dashboard", srv.URL), Lines: []int{4}, Reporter: "rule/link", - Text: fmt.Sprintf(`GET request for %s/dashboard returned invalid status code: 400 Bad Request`, srv.URL), + Text: fmt.Sprintf("GET request for %s/dashboard returned invalid status code: `400 Bad Request`.", srv.URL), Severity: checks.Bug, }, } @@ -161,14 +161,14 @@ func TestRuleLinkCheck(t *testing.T) { Fragment: fmt.Sprintf("%s/dashboard", srv.URL), Lines: []int{4}, Reporter: "rule/link", - Text: fmt.Sprintf(`GET request for %s/dashboard returned invalid status code: 400 Bad Request`, srv.URL), + Text: fmt.Sprintf("GET request for %s/dashboard returned invalid status code: `400 Bad Request`.", srv.URL), Severity: checks.Warning, }, { Fragment: fmt.Sprintf("%s/graph", srv.URL), Lines: []int{5}, Reporter: "rule/link", - Text: fmt.Sprintf(`GET request for %s/graph returned invalid status code: 400 Bad Request`, srv.URL), + Text: fmt.Sprintf("GET request for %s/graph returned invalid status code: `400 Bad Request`.", srv.URL), Severity: checks.Warning, }, } diff --git a/internal/checks/rule_reject.go b/internal/checks/rule_reject.go index 0135bdf9..1a528361 100644 --- a/internal/checks/rule_reject.go +++ b/internal/checks/rule_reject.go @@ -47,17 +47,17 @@ func (c Reject) Reporter() string { func (c Reject) Check(_ context.Context, _ string, rule parser.Rule, _ []discovery.Entry) (problems []Problem) { if c.checkLabels && rule.AlertingRule != nil && rule.AlertingRule.Labels != nil { for _, label := range rule.AlertingRule.Labels.Items { - problems = append(problems, c.reject(rule, label, "label")...) + problems = append(problems, c.reject(rule, label, "Label")...) } } if c.checkLabels && rule.RecordingRule != nil && rule.RecordingRule.Labels != nil { for _, label := range rule.RecordingRule.Labels.Items { - problems = append(problems, c.reject(rule, label, "label")...) + problems = append(problems, c.reject(rule, label, "Label")...) } } if c.checkAnnotations && rule.AlertingRule != nil && rule.AlertingRule.Annotations != nil { for _, ann := range rule.AlertingRule.Annotations.Items { - problems = append(problems, c.reject(rule, ann, "annotation")...) + problems = append(problems, c.reject(rule, ann, "Annotation")...) } } return problems @@ -69,7 +69,7 @@ func (c Reject) reject(rule parser.Rule, label *parser.YamlKeyValue, kind string Fragment: label.Key.Value, Lines: label.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("%s key %s is not allowed to match %q", kind, label.Key.Value, c.keyRe.anchored), + Text: fmt.Sprintf("%s key `%s` is not allowed to match `%s`.", kind, label.Key.Value, c.keyRe.anchored), Severity: c.severity, }) } @@ -78,7 +78,7 @@ func (c Reject) reject(rule parser.Rule, label *parser.YamlKeyValue, kind string Fragment: label.Value.Value, Lines: label.Lines(), Reporter: c.Reporter(), - Text: fmt.Sprintf("%s value %s is not allowed to match %q", kind, label.Value.Value, c.valueRe.anchored), + Text: fmt.Sprintf("%s value `%s` is not allowed to match `%s`.", kind, label.Value.Value, c.valueRe.anchored), Severity: c.severity, }) } diff --git a/internal/checks/rule_reject_test.go b/internal/checks/rule_reject_test.go index f239661c..96021a55 100644 --- a/internal/checks/rule_reject_test.go +++ b/internal/checks/rule_reject_test.go @@ -86,7 +86,7 @@ func TestRejectCheck(t *testing.T) { Fragment: `bad`, Lines: []int{4}, Reporter: "rule/reject", - Text: `label key bad is not allowed to match "^bad$"`, + Text: "Label key `bad` is not allowed to match `^bad$`.", Severity: checks.Bug, }, } @@ -105,7 +105,7 @@ func TestRejectCheck(t *testing.T) { Fragment: `bad`, Lines: []int{4}, Reporter: "rule/reject", - Text: `label value bad is not allowed to match "^bad$"`, + Text: "Label value `bad` is not allowed to match `^bad$`.", Severity: checks.Warning, }, } @@ -124,7 +124,7 @@ func TestRejectCheck(t *testing.T) { Fragment: `bad`, Lines: []int{4}, Reporter: "rule/reject", - Text: `label key bad is not allowed to match "^bad$"`, + Text: "Label key `bad` is not allowed to match `^bad$`.", Severity: checks.Bug, }, } @@ -143,7 +143,7 @@ func TestRejectCheck(t *testing.T) { Fragment: `bad`, Lines: []int{4}, Reporter: "rule/reject", - Text: `label value bad is not allowed to match "^bad$"`, + Text: "Label value `bad` is not allowed to match `^bad$`.", Severity: checks.Bug, }, } @@ -181,7 +181,7 @@ func TestRejectCheck(t *testing.T) { Fragment: `bad`, Lines: []int{4}, Reporter: "rule/reject", - Text: `annotation key bad is not allowed to match "^bad$"`, + Text: "Annotation key `bad` is not allowed to match `^bad$`.", Severity: checks.Information, }, } @@ -200,7 +200,7 @@ func TestRejectCheck(t *testing.T) { Fragment: `bad`, Lines: []int{4}, Reporter: "rule/reject", - Text: `annotation value bad is not allowed to match "^bad$"`, + Text: "Annotation value `bad` is not allowed to match `^bad$`.", Severity: checks.Bug, }, } @@ -228,7 +228,7 @@ func TestRejectCheck(t *testing.T) { Fragment: `foo`, Lines: []int{4}, Reporter: "rule/reject", - Text: `annotation value foo is not allowed to match "^{{ $alert }}$"`, + Text: "Annotation value `foo` is not allowed to match `^{{ $alert }}$`.", Severity: checks.Bug, }, } diff --git a/internal/config/discovery.go b/internal/config/discovery.go index 8e897137..bc9179d5 100644 --- a/internal/config/discovery.go +++ b/internal/config/discovery.go @@ -120,6 +120,7 @@ func (d *Discovery) merge(dst, src []*promapi.FailoverGroup) ([]*promapi.Failove type PrometheusTemplate struct { Name string `hcl:"name" json:"name"` URI string `hcl:"uri" json:"uri"` + PublicURI string `hcl:"publicURI,optional" json:"publicURI,omitempty"` Headers map[string]string `hcl:"headers,optional" json:"headers,omitempty"` Failover []string `hcl:"failover,optional" json:"failover,omitempty"` Timeout string `hcl:"timeout,optional" json:"timeout"` @@ -159,13 +160,20 @@ func (pt PrometheusTemplate) validate() (err error) { func (pt PrometheusTemplate) Render(data map[string]string) (*promapi.FailoverGroup, error) { var err error - var name, uri string + var name, uri, publicURI string if name, err = renderTemplate(pt.Name, data); err != nil { return nil, fmt.Errorf("bad name template %q: %w", pt.Name, err) } if uri, err = renderTemplate(pt.URI, data); err != nil { return nil, fmt.Errorf("bad uri template %q: %w", pt.URI, err) } + if pt.PublicURI != "" { + if publicURI, err = renderTemplate(pt.PublicURI, data); err != nil { + return nil, fmt.Errorf("bad publicURI template %q: %w", pt.PublicURI, err) + } + } else { + publicURI = uri + } failover := make([]string, 0, len(pt.Failover)) var furi string @@ -225,7 +233,8 @@ func (pt PrometheusTemplate) Render(data map[string]string) (*promapi.FailoverGr prom := PrometheusConfig{ Name: name, - URI: uri, + URI: strings.TrimSuffix(uri, "/"), + PublicURI: strings.TrimSuffix(publicURI, "/"), Headers: headers, Failover: failover, Timeout: pt.Timeout, @@ -378,7 +387,7 @@ func (pq PrometheusQuery) Discover(ctx context.Context) ([]*promapi.FailoverGrou timeout, _ := parseDuration(pq.Timeout) tls, _ := pq.TLS.toHTTPConfig() - prom := promapi.NewPrometheus("discovery", pq.URI, pq.Headers, timeout, 1, 100, tls) + prom := promapi.NewPrometheus("discovery", pq.URI, "", pq.Headers, timeout, 1, 100, tls) prom.StartWorkers() defer prom.Close() diff --git a/internal/config/discovery_test.go b/internal/config/discovery_test.go index edc384db..f426f713 100644 --- a/internal/config/discovery_test.go +++ b/internal/config/discovery_test.go @@ -90,8 +90,9 @@ func TestDiscoveryConfig(t *testing.T) { Match: "foo-(.+).yaml", Template: []PrometheusTemplate{ { - Name: "foo", - URI: "http://localhost", + Name: "foo", + URI: "http://localhost", + PublicURI: "http://localhost", }, }, }, @@ -259,6 +260,14 @@ func TestPrometheusTemplateRender(t *testing.T) { data: map[string]string{}, err: `bad uri template "http://{{ $name }}": template: discovery:1: undefined variable "$name"`, }, + { + template: PrometheusTemplate{ + URI: "http://{{ $name }}", + PublicURI: "http://{{ $foo }}", + }, + data: map[string]string{"name": "foo"}, + err: `bad publicURI template "http://{{ $foo }}": template: discovery:1: undefined variable "$foo"`, + }, { template: PrometheusTemplate{ Name: "foo", diff --git a/internal/config/prometheus.go b/internal/config/prometheus.go index 497962db..f7d33405 100644 --- a/internal/config/prometheus.go +++ b/internal/config/prometheus.go @@ -81,6 +81,7 @@ func (t *TLSConfig) toHTTPConfig() (*tls.Config, error) { type PrometheusConfig struct { Name string `hcl:",label" json:"name"` URI string `hcl:"uri" json:"uri"` + PublicURI string `hcl:"publicURI,optional" json:"publicURI,omitempty"` Headers map[string]string `hcl:"headers,optional" json:"headers,omitempty"` Failover []string `hcl:"failover,optional" json:"failover,omitempty"` Timeout string `hcl:"timeout,optional" json:"timeout"` @@ -167,10 +168,10 @@ func newFailoverGroup(prom PrometheusConfig) *promapi.FailoverGroup { var tlsConf *tls.Config tlsConf, _ = prom.TLS.toHTTPConfig() upstreams := []*promapi.Prometheus{ - promapi.NewPrometheus(prom.Name, prom.URI, prom.Headers, timeout, prom.Concurrency, prom.RateLimit, tlsConf), + promapi.NewPrometheus(prom.Name, prom.URI, prom.PublicURI, prom.Headers, timeout, prom.Concurrency, prom.RateLimit, tlsConf), } for _, uri := range prom.Failover { - upstreams = append(upstreams, promapi.NewPrometheus(prom.Name, uri, prom.Headers, timeout, prom.Concurrency, prom.RateLimit, tlsConf)) + upstreams = append(upstreams, promapi.NewPrometheus(prom.Name, uri, prom.PublicURI, prom.Headers, timeout, prom.Concurrency, prom.RateLimit, tlsConf)) } include := make([]*regexp.Regexp, 0, len(prom.Include)) for _, path := range prom.Include { @@ -182,7 +183,7 @@ func newFailoverGroup(prom PrometheusConfig) *promapi.FailoverGroup { } tags := make([]string, 0, len(prom.Tags)) tags = append(tags, prom.Tags...) - return promapi.NewFailoverGroup(prom.Name, upstreams, prom.Required, prom.Uptime, include, exclude, tags) + return promapi.NewFailoverGroup(prom.Name, prom.PublicURI, upstreams, prom.Required, prom.Uptime, include, exclude, tags) } func NewPrometheusGenerator(cfg Config, metricsRegistry *prometheus.Registry) *PrometheusGenerator { diff --git a/internal/promapi/config.go b/internal/promapi/config.go index d3d4228c..acaa77ed 100644 --- a/internal/promapi/config.go +++ b/internal/promapi/config.go @@ -27,8 +27,9 @@ type PrometheusConfig struct { } type ConfigResult struct { - URI string - Config PrometheusConfig + URI string + PublicURI string + Config PrometheusConfig } type configQuery struct { @@ -100,7 +101,11 @@ func (p *Prometheus) Config(ctx context.Context) (*ConfigResult, error) { return nil, QueryError{err: result.err, msg: decodeError(result.err)} } - r := ConfigResult{URI: p.safeURI, Config: result.value.(PrometheusConfig)} + r := ConfigResult{ + URI: p.safeURI, + PublicURI: p.publicURI, + Config: result.value.(PrometheusConfig), + } return &r, nil } diff --git a/internal/promapi/config_test.go b/internal/promapi/config_test.go index 41dbf2f0..9d597b36 100644 --- a/internal/promapi/config_test.go +++ b/internal/promapi/config_test.go @@ -76,23 +76,26 @@ func TestConfig(t *testing.T) { prefix: "/default", timeout: time.Second, cfg: promapi.ConfigResult{ - URI: srv.URL + "/default", - Config: defaults, + URI: srv.URL + "/default", + PublicURI: srv.URL + "/default", + Config: defaults, }, }, { prefix: "/1m", timeout: time.Second, cfg: promapi.ConfigResult{ - URI: srv.URL + "/1m", - Config: defaults, + URI: srv.URL + "/1m", + PublicURI: srv.URL + "/1m", + Config: defaults, }, }, { prefix: "/30s", timeout: time.Second, cfg: promapi.ConfigResult{ - URI: srv.URL + "/30s", + URI: srv.URL + "/30s", + PublicURI: srv.URL + "/30s", Config: promapi.PrometheusConfig{ Global: promapi.ConfigSectionGlobal{ ScrapeInterval: time.Second * 30, @@ -122,7 +125,7 @@ func TestConfig(t *testing.T) { for _, tc := range testCases { t.Run(strings.TrimPrefix(tc.prefix, "/"), func(t *testing.T) { - prom := promapi.NewPrometheus("test", srv.URL+tc.prefix, nil, tc.timeout, 1, 100, nil) + prom := promapi.NewPrometheus("test", srv.URL+tc.prefix, "", nil, tc.timeout, 1, 100, nil) prom.StartWorkers() defer prom.Close() @@ -176,8 +179,8 @@ func TestConfigHeaders(t *testing.T) { })) defer srv.Close() - fg := promapi.NewFailoverGroup("test", []*promapi.Prometheus{ - promapi.NewPrometheus("test", srv.URL, tc.config, time.Second, 1, 100, nil), + fg := promapi.NewFailoverGroup("test", srv.URL, []*promapi.Prometheus{ + promapi.NewPrometheus("test", srv.URL, "", tc.config, time.Second, 1, 100, nil), }, true, "up", nil, nil, nil) reg := prometheus.NewRegistry() diff --git a/internal/promapi/failover.go b/internal/promapi/failover.go index 936653d9..aeafa1b0 100644 --- a/internal/promapi/failover.go +++ b/internal/promapi/failover.go @@ -45,6 +45,7 @@ func cacheCleaner(cache *queryCache, interval time.Duration, quit chan bool) { type FailoverGroup struct { name string + publicURI string servers []*Prometheus uptimeMetric string cacheCollector *cacheCollector @@ -57,9 +58,10 @@ type FailoverGroup struct { strictErrors bool } -func NewFailoverGroup(name string, servers []*Prometheus, strictErrors bool, uptimeMetric string, include, exclude []*regexp.Regexp, tags []string) *FailoverGroup { +func NewFailoverGroup(name, publicURI string, servers []*Prometheus, strictErrors bool, uptimeMetric string, include, exclude []*regexp.Regexp, tags []string) *FailoverGroup { return &FailoverGroup{ name: name, + publicURI: publicURI, servers: servers, strictErrors: strictErrors, uptimeMetric: uptimeMetric, @@ -73,6 +75,10 @@ func (fg *FailoverGroup) Name() string { return fg.name } +func (fg *FailoverGroup) PublicURI() string { + return fg.publicURI +} + func (fg *FailoverGroup) Include() []string { sl := []string{} for _, re := range fg.pathsInclude { diff --git a/internal/promapi/flags.go b/internal/promapi/flags.go index 299b7881..76708961 100644 --- a/internal/promapi/flags.go +++ b/internal/promapi/flags.go @@ -15,8 +15,9 @@ import ( ) type FlagsResult struct { - URI string - Flags v1.FlagsResult + URI string + PublicURI string + Flags v1.FlagsResult } type flagsQuery struct { @@ -85,7 +86,11 @@ func (p *Prometheus) Flags(ctx context.Context) (*FlagsResult, error) { return nil, QueryError{err: result.err, msg: decodeError(result.err)} } - r := FlagsResult{URI: p.safeURI, Flags: result.value.(v1.FlagsResult)} + r := FlagsResult{ + URI: p.safeURI, + PublicURI: p.publicURI, + Flags: result.value.(v1.FlagsResult), + } return &r, nil } diff --git a/internal/promapi/flags_test.go b/internal/promapi/flags_test.go index 5a1e6723..1bbe30b5 100644 --- a/internal/promapi/flags_test.go +++ b/internal/promapi/flags_test.go @@ -62,16 +62,18 @@ func TestFlags(t *testing.T) { prefix: "/default", timeout: time.Second, flags: promapi.FlagsResult{ - URI: srv.URL + "/default", - Flags: v1.FlagsResult{}, + URI: srv.URL + "/default", + PublicURI: srv.URL + "/default", + Flags: v1.FlagsResult{}, }, }, { prefix: "/foo", timeout: time.Second, flags: promapi.FlagsResult{ - URI: srv.URL + "/foo", - Flags: v1.FlagsResult{"foo": "bar"}, + URI: srv.URL + "/foo", + PublicURI: srv.URL + "/foo", + Flags: v1.FlagsResult{"foo": "bar"}, }, }, { @@ -93,8 +95,8 @@ func TestFlags(t *testing.T) { for _, tc := range testCases { t.Run(strings.TrimPrefix(tc.prefix, "/"), func(t *testing.T) { - fg := promapi.NewFailoverGroup("test", []*promapi.Prometheus{ - promapi.NewPrometheus("test", srv.URL+tc.prefix, nil, tc.timeout, 1, 100, nil), + fg := promapi.NewFailoverGroup("test", srv.URL+tc.prefix, []*promapi.Prometheus{ + promapi.NewPrometheus("test", srv.URL+tc.prefix, "", nil, tc.timeout, 1, 100, nil), }, true, "up", nil, nil, nil) reg := prometheus.NewRegistry() diff --git a/internal/promapi/metadata.go b/internal/promapi/metadata.go index 9090691a..ec599d4e 100644 --- a/internal/promapi/metadata.go +++ b/internal/promapi/metadata.go @@ -15,8 +15,9 @@ import ( ) type MetadataResult struct { - URI string - Metadata []v1.Metadata + URI string + PublicURI string + Metadata []v1.Metadata } type metadataQuery struct { @@ -91,7 +92,11 @@ func (p *Prometheus) Metadata(ctx context.Context, metric string) (*MetadataResu return nil, QueryError{err: result.err, msg: decodeError(result.err)} } - metadata := MetadataResult{URI: p.safeURI, Metadata: result.value.(map[string][]v1.Metadata)[metric]} + metadata := MetadataResult{ + URI: p.safeURI, + PublicURI: p.publicURI, + Metadata: result.value.(map[string][]v1.Metadata)[metric], + } return &metadata, nil } diff --git a/internal/promapi/metadata_test.go b/internal/promapi/metadata_test.go index 60679830..cdfca99e 100644 --- a/internal/promapi/metadata_test.go +++ b/internal/promapi/metadata_test.go @@ -71,23 +71,26 @@ func TestMetadata(t *testing.T) { metric: "gauge", timeout: time.Second, metadata: promapi.MetadataResult{ - URI: srv.URL, - Metadata: []v1.Metadata{{Type: "gauge", Help: "Text", Unit: ""}}, + URI: srv.URL, + PublicURI: srv.URL, + Metadata: []v1.Metadata{{Type: "gauge", Help: "Text", Unit: ""}}, }, }, { metric: "counter", timeout: time.Second, metadata: promapi.MetadataResult{ - URI: srv.URL, - Metadata: []v1.Metadata{{Type: "counter", Help: "Text", Unit: ""}}, + URI: srv.URL, + PublicURI: srv.URL, + Metadata: []v1.Metadata{{Type: "counter", Help: "Text", Unit: ""}}, }, }, { metric: "mixed", timeout: time.Second, metadata: promapi.MetadataResult{ - URI: srv.URL, + URI: srv.URL, + PublicURI: srv.URL, Metadata: []v1.Metadata{ {Type: "gauge", Help: "Text1", Unit: "abc"}, {Type: "counter", Help: "Text2", Unit: ""}, @@ -108,16 +111,17 @@ func TestMetadata(t *testing.T) { metric: "once", timeout: time.Second, metadata: promapi.MetadataResult{ - URI: srv.URL, - Metadata: []v1.Metadata{{Type: "gauge", Help: "Text", Unit: ""}}, + URI: srv.URL, + PublicURI: srv.URL, + Metadata: []v1.Metadata{{Type: "gauge", Help: "Text", Unit: ""}}, }, }, } for _, tc := range testCases { t.Run(tc.metric, func(t *testing.T) { - fg := promapi.NewFailoverGroup("test", []*promapi.Prometheus{ - promapi.NewPrometheus("test", srv.URL, nil, tc.timeout, 1, 100, nil), + fg := promapi.NewFailoverGroup("test", srv.URL, []*promapi.Prometheus{ + promapi.NewPrometheus("test", srv.URL, "", nil, tc.timeout, 1, 100, nil), }, true, "up", nil, nil, nil) reg := prometheus.NewRegistry() fg.StartWorkers(reg) diff --git a/internal/promapi/prometheus.go b/internal/promapi/prometheus.go index 53a26ac6..92df9016 100644 --- a/internal/promapi/prometheus.go +++ b/internal/promapi/prometheus.go @@ -93,6 +93,7 @@ type Prometheus struct { name string unsafeURI string safeURI string + publicURI string headers map[string]string timeout time.Duration concurrency int @@ -104,15 +105,22 @@ type Prometheus struct { queries chan queryRequest } -func NewPrometheus(name, uri string, headers map[string]string, timeout time.Duration, concurrency, rl int, tlsConf *tls.Config) *Prometheus { +func NewPrometheus(name, uri, publicURI string, headers map[string]string, timeout time.Duration, concurrency, rl int, tlsConf *tls.Config) *Prometheus { transport := http.DefaultTransport.(*http.Transport).Clone() if tlsConf != nil { transport.TLSClientConfig = tlsConf } + uri = strings.TrimSuffix(uri, "/") + publicURI = strings.TrimSuffix(publicURI, "/") + if publicURI == "" { + publicURI = uri + } + prom := Prometheus{ name: name, unsafeURI: uri, + publicURI: publicURI, safeURI: sanitizeURI(uri), headers: headers, timeout: timeout, diff --git a/internal/promapi/query.go b/internal/promapi/query.go index 43078a26..0072d8ff 100644 --- a/internal/promapi/query.go +++ b/internal/promapi/query.go @@ -18,9 +18,10 @@ import ( ) type QueryResult struct { - URI string - Series []Sample - Stats QueryStats + URI string + PublicURI string + Series []Sample + Stats QueryStats } type instantQuery struct { @@ -97,9 +98,10 @@ func (p *Prometheus) Query(ctx context.Context, expr string) (*QueryResult, erro } qr := QueryResult{ - URI: p.safeURI, - Series: result.value.([]Sample), - Stats: result.stats, + URI: p.safeURI, + PublicURI: p.publicURI, + Series: result.value.([]Sample), + Stats: result.stats, } slog.Debug("Parsed response", slog.String("uri", p.safeURI), slog.String("query", expr), slog.Int("series", len(qr.Series))) diff --git a/internal/promapi/query_test.go b/internal/promapi/query_test.go index 981f79ed..d1dfa756 100644 --- a/internal/promapi/query_test.go +++ b/internal/promapi/query_test.go @@ -246,8 +246,8 @@ func TestQuery(t *testing.T) { for _, tc := range testCases { t.Run(tc.query, func(t *testing.T) { - fg := promapi.NewFailoverGroup("test", []*promapi.Prometheus{ - promapi.NewPrometheus("test", srv.URL, nil, tc.timeout, 1, 100, nil), + fg := promapi.NewFailoverGroup("test", srv.URL, []*promapi.Prometheus{ + promapi.NewPrometheus("test", srv.URL, srv.URL, nil, tc.timeout, 1, 100, nil), }, true, "up", nil, nil, nil) reg := prometheus.NewRegistry() fg.StartWorkers(reg) diff --git a/internal/promapi/range.go b/internal/promapi/range.go index e6033df2..e93a317f 100644 --- a/internal/promapi/range.go +++ b/internal/promapi/range.go @@ -23,9 +23,10 @@ import ( ) type RangeQueryResult struct { - URI string - Series SeriesTimeRanges - Stats QueryStats + URI string + PublicURI string + Series SeriesTimeRanges + Stats QueryStats } type rangeQuery struct { @@ -162,7 +163,8 @@ func (p *Prometheus) RangeQuery(ctx context.Context, expr string, params RangeQu }() merged := RangeQueryResult{ - URI: p.safeURI, + URI: p.safeURI, + PublicURI: p.publicURI, Series: SeriesTimeRanges{ From: start, Until: end, diff --git a/internal/promapi/range_test.go b/internal/promapi/range_test.go index 48d8ad00..c5bed9cc 100644 --- a/internal/promapi/range_test.go +++ b/internal/promapi/range_test.go @@ -638,8 +638,8 @@ func TestRange(t *testing.T) { })) defer srv.Close() - fg := promapi.NewFailoverGroup("test", []*promapi.Prometheus{ - promapi.NewPrometheus("test", srv.URL, nil, tc.timeout, 1, 100, nil), + fg := promapi.NewFailoverGroup("test", srv.URL, []*promapi.Prometheus{ + promapi.NewPrometheus("test", srv.URL, "", nil, tc.timeout, 1, 100, nil), }, true, "up", nil, nil, nil) reg := prometheus.NewRegistry() fg.StartWorkers(reg) diff --git a/internal/reporter/bitbucket.go b/internal/reporter/bitbucket.go index c73c384d..579567ef 100644 --- a/internal/reporter/bitbucket.go +++ b/internal/reporter/bitbucket.go @@ -83,7 +83,7 @@ func (r BitBucketReporter) Submit(summary Summary) (err error) { r.api.pruneComments(pr, existingComments, pendingComments) slog.Info("Adding missing comments to BitBucket") - if err = r.api.addComments(pr, existingComments, pendingComments, changes); err != nil { + if err = r.api.addComments(pr, existingComments, pendingComments); err != nil { return fmt.Errorf("failed to create BitBucket pull request comments: %w", err) } diff --git a/internal/reporter/bitbucket_api.go b/internal/reporter/bitbucket_api.go index 193fc16e..500a8371 100644 --- a/internal/reporter/bitbucket_api.go +++ b/internal/reporter/bitbucket_api.go @@ -190,9 +190,11 @@ func (pc pendingComment) toBitBucketComment(changes *bitBucketPRChanges) BitBuck c.Anchor.LineType = "ADDED" c.Anchor.FileType = "TO" } - if m, ok := changes.pathLineMapping[pc.path]; ok { - if v, found := m[pc.line]; found { - c.Anchor.Line = v + if c.Anchor.FileType == "FROM" { + if m, ok := changes.pathLineMapping[pc.path]; ok { + if v, found := m[pc.line]; found { + c.Anchor.Line = v + } } } } @@ -548,8 +550,8 @@ func (bb bitBucketAPI) getPullRequestComments(pr *bitBucketPR) ([]bitBucketComme return comments, nil } -func (bb bitBucketAPI) makeComments(summary Summary, changes *bitBucketPRChanges) []pendingComment { - comments := []pendingComment{} +func (bb bitBucketAPI) makeComments(summary Summary, changes *bitBucketPRChanges) []BitBucketPendingComment { + comments := []BitBucketPendingComment{} for _, report := range summary.reports { if _, ok := changes.pathModifiedLines[report.ReportedPath]; !ok { continue @@ -568,6 +570,10 @@ func (bb bitBucketAPI) makeComments(summary Summary, changes *bitBucketPRChanges buf.WriteString("** check.") buf.WriteString("\n\n------\n\n") buf.WriteString(report.Problem.Text) + if report.Problem.Details != "" { + buf.WriteString("\n\n") + buf.WriteString(report.Problem.Details) + } buf.WriteString("\n\n------\n\n") if report.ReportedPath != report.SourcePath { buf.WriteString(":leftwards_arrow_with_hook: This problem was detected on a symlinked file ") @@ -579,20 +585,21 @@ func (bb bitBucketAPI) makeComments(summary Summary, changes *bitBucketPRChanges buf.WriteString(report.Problem.Reporter) buf.WriteString(".html).\n") - comments = append(comments, pendingComment{ + pending := pendingComment{ path: report.ReportedPath, line: report.Problem.Lines[0], text: buf.String(), - }) + } + comments = append(comments, pending.toBitBucketComment(changes)) } return comments } -func (bb bitBucketAPI) pruneComments(pr *bitBucketPR, currentComments []bitBucketComment, pendingComments []pendingComment) { +func (bb bitBucketAPI) pruneComments(pr *bitBucketPR, currentComments []bitBucketComment, pendingComments []BitBucketPendingComment) { for _, cur := range currentComments { var keep bool for _, pend := range pendingComments { - if cur.path == pend.path && cur.line == pend.line && cur.text == pend.text { + if cur.path == pend.Anchor.Path && cur.line == pend.Anchor.Line && cur.text == pend.Text { keep = true break } @@ -601,6 +608,12 @@ func (bb bitBucketAPI) pruneComments(pr *bitBucketPR, currentComments []bitBucke } } if !keep { + slog.Debug( + "Deleting stale comment", + slog.Int("id", cur.id), + slog.String("path", cur.path), + slog.Int("line", cur.line), + ) _, err := bb.request( http.MethodDelete, fmt.Sprintf("/rest/api/1.0/projects/%s/repos/%s/pull-requests/%d/comments/%d?version=%d", @@ -621,12 +634,12 @@ func (bb bitBucketAPI) pruneComments(pr *bitBucketPR, currentComments []bitBucke } } -func (bb bitBucketAPI) addComments(pr *bitBucketPR, currentComments []bitBucketComment, pendingComments []pendingComment, changes *bitBucketPRChanges) error { +func (bb bitBucketAPI) addComments(pr *bitBucketPR, currentComments []bitBucketComment, pendingComments []BitBucketPendingComment) error { var added int for _, pend := range pendingComments { add := true for _, cur := range currentComments { - if cur.path == pend.path && cur.line == pend.line && cur.text == pend.text { + if cur.path == pend.Anchor.Path && cur.line == pend.Anchor.Line && cur.text == pend.Text { add = false } if cur.onCommit { @@ -634,7 +647,15 @@ func (bb bitBucketAPI) addComments(pr *bitBucketPR, currentComments []bitBucketC } } if add { - payload, _ := json.Marshal(pend.toBitBucketComment(changes)) + slog.Debug( + "Adding missing comment", + slog.String("path", pend.Anchor.Path), + slog.Int("line", pend.Anchor.Line), + slog.String("diffType", pend.Anchor.DiffType), + slog.String("lineType", pend.Anchor.LineType), + slog.String("fileType", pend.Anchor.FileType), + ) + payload, _ := json.Marshal(pend) _, err := bb.request( http.MethodPost, fmt.Sprintf("/rest/api/1.0/projects/%s/repos/%s/pull-requests/%d/comments", diff --git a/internal/reporter/bitbucket_api_test.go b/internal/reporter/bitbucket_api_test.go index 50ce0bdf..de3318d3 100644 --- a/internal/reporter/bitbucket_api_test.go +++ b/internal/reporter/bitbucket_api_test.go @@ -74,7 +74,7 @@ func TestPendingCommentToBitBucketComment(t *testing.T) { Severity: "NORMAL", Anchor: BitBucketPendingCommentAnchor{ Path: "foo.yaml", - Line: 4, + Line: 5, DiffType: "EFFECTIVE", LineType: "ADDED", FileType: "TO", @@ -114,6 +114,7 @@ func TestReportToAnnotation(t *testing.T) { Lines: []int{5}, Reporter: "mock", Text: "report text", + Details: "mock details", Severity: checks.Fatal, }, }, diff --git a/internal/reporter/bitbucket_test.go b/internal/reporter/bitbucket_test.go index 4d6d3a7d..3900afc9 100644 --- a/internal/reporter/bitbucket_test.go +++ b/internal/reporter/bitbucket_test.go @@ -832,6 +832,7 @@ func TestBitBucketReporter(t *testing.T) { Lines: []int{2}, Reporter: "mock", Text: "mock text", + Details: "mock details", Severity: checks.Bug, }, }, @@ -887,7 +888,7 @@ func TestBitBucketReporter(t *testing.T) { }, }, { - Text: ":stop_sign: **Bug** reported by [pint](https://cloudflare.github.io/pint/) **mock** check.\n\n------\n\nmock text\n\n------\n\n:information_source: To see documentation covering this check and instructions on how to resolve it [click here](https://cloudflare.github.io/pint/checks/mock.html).\n", + Text: ":stop_sign: **Bug** reported by [pint](https://cloudflare.github.io/pint/) **mock** check.\n\n------\n\nmock text\n\nmock details\n\n------\n\n:information_source: To see documentation covering this check and instructions on how to resolve it [click here](https://cloudflare.github.io/pint/checks/mock.html).\n", Severity: "NORMAL", Anchor: reporter.BitBucketPendingCommentAnchor{ Path: "foo.txt", diff --git a/internal/reporter/github.go b/internal/reporter/github.go index a5777258..825063bd 100644 --- a/internal/reporter/github.go +++ b/internal/reporter/github.go @@ -272,21 +272,25 @@ func formatGHReviewBody(version string, summary Summary) string { } func reportToGitHubComment(headCommit string, rep Report) *github.PullRequestComment { - var msgPrefix string + var msgPrefix, msgSuffix string reportLine, srcLine := moveReportedLine(rep) if reportLine != srcLine { msgPrefix = fmt.Sprintf("Problem reported on unmodified line %d, annotation moved here: ", srcLine) } + if rep.Problem.Details != "" { + msgSuffix = "\n\n" + rep.Problem.Details + } c := github.PullRequestComment{ CommitID: github.String(headCommit), Path: github.String(rep.ReportedPath), Body: github.String(fmt.Sprintf( - "[%s](https://cloudflare.github.io/pint/checks/%s.html): %s%s", + "[%s](https://cloudflare.github.io/pint/checks/%s.html): %s%s%s", rep.Problem.Reporter, rep.Problem.Reporter, msgPrefix, rep.Problem.Text, + msgSuffix, )), Line: github.Int(reportLine), } diff --git a/internal/reporter/github_test.go b/internal/reporter/github_test.go index a5dc303c..63de2a12 100644 --- a/internal/reporter/github_test.go +++ b/internal/reporter/github_test.go @@ -112,6 +112,7 @@ filename %s Lines: []int{2}, Reporter: "mock", Text: "syntax error", + Details: "syntax details", Severity: checks.Fatal, }, }, diff --git a/internal/reporter/teamcity_test.go b/internal/reporter/teamcity_test.go index fd5d7b7f..be851ff8 100644 --- a/internal/reporter/teamcity_test.go +++ b/internal/reporter/teamcity_test.go @@ -46,6 +46,7 @@ func TestTeamCityReporter(t *testing.T) { Lines: []int{5, 6}, Reporter: "mock", Text: "mock text", + Details: "mock details", Severity: checks.Information, }, }, diff --git a/tools/gofumpt/go.mod b/tools/gofumpt/go.mod index 28d8530a..ece07058 100644 --- a/tools/gofumpt/go.mod +++ b/tools/gofumpt/go.mod @@ -1,6 +1,6 @@ module _ -go 1.21.3 +go 1.21.4 require mvdan.cc/gofumpt v0.5.0 diff --git a/tools/goimports/go.mod b/tools/goimports/go.mod index ffd0d8d5..f787c2dd 100644 --- a/tools/goimports/go.mod +++ b/tools/goimports/go.mod @@ -1,6 +1,6 @@ module _ -go 1.21.3 +go 1.21.4 require golang.org/x/tools v0.14.0 diff --git a/tools/golangci-lint/go.mod b/tools/golangci-lint/go.mod index 7fc689d0..ef69f91a 100644 --- a/tools/golangci-lint/go.mod +++ b/tools/golangci-lint/go.mod @@ -1,6 +1,6 @@ module _ -go 1.21.3 +go 1.21.4 require github.com/golangci/golangci-lint v1.55.2