From cfb6436be5ad320b5f18b4420175e465176821f3 Mon Sep 17 00:00:00 2001 From: Roman Khavronenko Date: Tue, 31 Aug 2021 14:57:47 +0300 Subject: [PATCH] Vmalert extra params (#1587) * vmalert: allow extra GET params in datasource package ExtraParams will be added as GET params to every HTTP request made by datasource. The `roundDigits` param, for example, was substituted by corresponding extra param. * vmalert: add nocache=1 param for replay process The `nocache=1` param is VictoriaMetrics specific parameter which prevents it from caching and boundaries aligning for queries. We set it to avoid cache pollution in `replay` mode and also to avoid unnecessary time range boundaries alignment. * vmalert: mention nocache=1 in replay description * vmalert: fix bug with unused param --- app/vmalert/README.md | 2 ++ app/vmalert/datasource/init.go | 17 +++++++++++++---- app/vmalert/datasource/vm.go | 2 +- app/vmalert/datasource/vm_prom_api.go | 6 +++--- app/vmalert/datasource/vm_test.go | 16 +++++++++++++++- app/vmalert/main.go | 7 +++++-- 6 files changed, 39 insertions(+), 11 deletions(-) diff --git a/app/vmalert/README.md b/app/vmalert/README.md index 067834650..c5cad17f3 100644 --- a/app/vmalert/README.md +++ b/app/vmalert/README.md @@ -311,6 +311,8 @@ to [/query_range](https://prometheus.io/docs/prometheus/latest/querying/api/#ran of the configured `-datasource.url`. Returned data then processed according to the rule type and backfilled to `-remoteWrite.url` via [Remote Write protocol](https://prometheus.io/docs/prometheus/latest/storage/#remote-storage-integrations). Vmalert respects `evaluationInterval` value set by flag or per-group during the replay. +Vmalert automatically disables caching on VictoriaMetrics side by sending `nocache=1` param. It allows +to prevent cache pollution and unwanted time range boundaries adjustment during backfilling. #### Recording rules diff --git a/app/vmalert/datasource/init.go b/app/vmalert/datasource/init.go index 671b0ee9e..95029744e 100644 --- a/app/vmalert/datasource/init.go +++ b/app/vmalert/datasource/init.go @@ -31,8 +31,15 @@ var ( `In VM "round_digits" limits the number of digits after the decimal point in response values.`) ) +// Param represents an HTTP GET param +type Param struct { + Key, Value string +} + // Init creates a Querier from provided flag values. -func Init() (QuerierBuilder, error) { +// Provided extraParams will be added as GET params to +// each request. +func Init(extraParams []Param) (QuerierBuilder, error) { if *addr == "" { return nil, fmt.Errorf("datasource.url is empty") } @@ -43,9 +50,11 @@ func Init() (QuerierBuilder, error) { } tr.MaxIdleConnsPerHost = *maxIdleConnections - var rd string if *roundDigits > 0 { - rd = fmt.Sprintf("%d", *roundDigits) + extraParams = append(extraParams, Param{ + Key: "round_digits", + Value: fmt.Sprintf("%d", *roundDigits), + }) } return &VMStorage{ @@ -56,7 +65,7 @@ func Init() (QuerierBuilder, error) { appendTypePrefix: *appendTypePrefix, lookBack: *lookBack, queryStep: *queryStep, - roundDigits: rd, dataSourceType: NewPrometheusType(), + extraParams: extraParams, }, nil } diff --git a/app/vmalert/datasource/vm.go b/app/vmalert/datasource/vm.go index cda418852..389a60ba2 100644 --- a/app/vmalert/datasource/vm.go +++ b/app/vmalert/datasource/vm.go @@ -18,11 +18,11 @@ type VMStorage struct { appendTypePrefix bool lookBack time.Duration queryStep time.Duration - roundDigits string dataSourceType Type evaluationInterval time.Duration extraLabels []string + extraParams []Param } // Clone makes clone of VMStorage, shares http client. diff --git a/app/vmalert/datasource/vm_prom_api.go b/app/vmalert/datasource/vm_prom_api.go index e1e1b4937..62154c313 100644 --- a/app/vmalert/datasource/vm_prom_api.go +++ b/app/vmalert/datasource/vm_prom_api.go @@ -155,11 +155,11 @@ func (s *VMStorage) setPrometheusReqParams(r *http.Request, query string) { // override step with user-specified value q.Set("step", s.queryStep.String()) } - if s.roundDigits != "" { - q.Set("round_digits", s.roundDigits) - } for _, l := range s.extraLabels { q.Add("extra_label", l) } + for _, p := range s.extraParams { + q.Add(p.Key, p.Value) + } r.URL.RawQuery = q.Encode() } diff --git a/app/vmalert/datasource/vm_test.go b/app/vmalert/datasource/vm_test.go index c86deb3cd..8dbf61698 100644 --- a/app/vmalert/datasource/vm_test.go +++ b/app/vmalert/datasource/vm_test.go @@ -385,7 +385,7 @@ func TestRequestParams(t *testing.T) { "round digits", false, &VMStorage{ - roundDigits: "10", + extraParams: []Param{{"round_digits", "10"}}, }, func(t *testing.T, r *http.Request) { exp := fmt.Sprintf("query=%s&round_digits=10&time=%d", query, timestamp.Unix()) @@ -421,6 +421,20 @@ func TestRequestParams(t *testing.T) { checkEqualString(t, exp, r.URL.RawQuery) }, }, + { + "extra params", + false, + &VMStorage{ + extraParams: []Param{ + {Key: "nocache", Value: "1"}, + {Key: "max_lookback", Value: "1h"}, + }, + }, + func(t *testing.T, r *http.Request) { + exp := fmt.Sprintf("max_lookback=1h&nocache=1&query=%s&time=%d", query, timestamp.Unix()) + checkEqualString(t, exp, r.URL.RawQuery) + }, + }, } for _, tc := range testCases { diff --git a/app/vmalert/main.go b/app/vmalert/main.go index db21b9900..27a47b538 100644 --- a/app/vmalert/main.go +++ b/app/vmalert/main.go @@ -91,7 +91,10 @@ func main() { if err != nil { logger.Fatalf("cannot parse configuration file: %s", err) } - q, err := datasource.Init() + // prevent queries from caching and boundaries aligning + // when querying VictoriaMetrics datasource. + noCache := datasource.Param{Key: "nocache", Value: "1"} + q, err := datasource.Init([]datasource.Param{noCache}) if err != nil { logger.Fatalf("failed to init datasource: %s", err) } @@ -139,7 +142,7 @@ var ( ) func newManager(ctx context.Context) (*manager, error) { - q, err := datasource.Init() + q, err := datasource.Init(nil) if err != nil { return nil, fmt.Errorf("failed to init datasource: %w", err) }