From 5b8c8c2ebd3d12b225ba5e1862f5af4b75bc1748 Mon Sep 17 00:00:00 2001 From: Lukasz Mierzwa Date: Fri, 9 Aug 2024 09:46:01 +0100 Subject: [PATCH] Validate ignoreLabelsValue --- docs/changelog.md | 6 ++++++ docs/checks/promql/series.md | 29 +++++++++++++++++++++++++++++ internal/checks/promql_series.go | 6 ++++++ internal/config/config_test.go | 16 ++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index 7094093c..e53623b8 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,5 +1,11 @@ # Changelog +## v0.64.1 + +### Fixed + +- Validate `ignoreLabelsValue` option values in the pint config. + ## v0.64.0 ### Added diff --git a/docs/checks/promql/series.md b/docs/checks/promql/series.md index c4caac16..3d43f53d 100644 --- a/docs/checks/promql/series.md +++ b/docs/checks/promql/series.md @@ -164,6 +164,8 @@ check "promql/series" { should **NOT** report problems if there's a query that uses a **value** that does not exist. This can be also set per rule using `# pint rule/set promql/series ignore/label-value $labelName` comments, see below. + The value of this option is a map where the key is a metric selector to match on and the value + is the list of label names. Example: @@ -193,6 +195,33 @@ check "promql/series" { } ``` +You can use any metric selectors as keys in `ignoreLabelsValue` if you want apply it only +to metric selectors in queries that match the selector in `ignoreLabelsValue`. +For example if you have a rule that uses the same metric with two different selectors: + +```yaml +- alerts: ... + expr: | + rate(http_requests_total{env="prod", code="401"}[5m]) > 0 + or + rate(http_requests_total{env="dev", code="401"}[5m]) > 0 +``` + +And you want to disable pint warnings only for the second selector (`http_requests_total{env="dev", code="401"}`) +but not the first one (`http_requests_total{env="prod", code="401"}`) you can do that by adding any label matcher +used in the query: + +```js +check "promql/series" { + ignoreLabelsValue = { + "http_requests_total{env=\"dev\"}" = [ "code" ] + } +} +``` + +You can only use label matchers that would match the selector from the query itself, not from the time series +the query would return. This whole logic applies only to the query, not to the results of it. + ### min-age But default this check will report a problem if a metric was present diff --git a/internal/checks/promql_series.go b/internal/checks/promql_series.go index a832a387..7c76a50d 100644 --- a/internal/checks/promql_series.go +++ b/internal/checks/promql_series.go @@ -60,6 +60,12 @@ func (c *PromqlSeriesSettings) Validate() error { c.lookbackStepDuration = time.Duration(dur) } + for selector := range c.IgnoreLabelsValue { + if _, err := promParser.ParseMetricSelector(selector); err != nil { + return fmt.Errorf("%q is not a valid PromQL metric selector: %w", selector, err) + } + } + return nil } diff --git a/internal/config/config_test.go b/internal/config/config_test.go index cb39a4b1..3e2fb757 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -2148,6 +2148,22 @@ func TestConfigErrors(t *testing.T) { config: `check "promql/series" { ignoreMetrics = [".+++"] }`, err: "error parsing regexp: invalid nested repetition operator: `++`", }, + { + config: `check "promql/series" { + ignoreLabelsValue = { + "foo bar" = [ "abc" ] + } +}`, + err: `"foo bar" is not a valid PromQL metric selector: 1:5: parse error: unexpected identifier "bar"`, + }, + { + config: `check "promql/series" { + ignoreLabelsValue = { + "foo{" = [ "abc" ] + } +}`, + err: `"foo{" is not a valid PromQL metric selector: 1:5: parse error: unexpected end of input inside braces`, + }, { config: `rule { link ".+++" {}