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
This commit is contained in:
Roman Khavronenko 2021-08-31 14:57:47 +03:00 committed by GitHub
parent 7c70dcbe3b
commit cfb6436be5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 39 additions and 11 deletions

View File

@ -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 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). 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 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 #### Recording rules

View File

@ -31,8 +31,15 @@ var (
`In VM "round_digits" limits the number of digits after the decimal point in response values.`) `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. // 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 == "" { if *addr == "" {
return nil, fmt.Errorf("datasource.url is empty") return nil, fmt.Errorf("datasource.url is empty")
} }
@ -43,9 +50,11 @@ func Init() (QuerierBuilder, error) {
} }
tr.MaxIdleConnsPerHost = *maxIdleConnections tr.MaxIdleConnsPerHost = *maxIdleConnections
var rd string
if *roundDigits > 0 { if *roundDigits > 0 {
rd = fmt.Sprintf("%d", *roundDigits) extraParams = append(extraParams, Param{
Key: "round_digits",
Value: fmt.Sprintf("%d", *roundDigits),
})
} }
return &VMStorage{ return &VMStorage{
@ -56,7 +65,7 @@ func Init() (QuerierBuilder, error) {
appendTypePrefix: *appendTypePrefix, appendTypePrefix: *appendTypePrefix,
lookBack: *lookBack, lookBack: *lookBack,
queryStep: *queryStep, queryStep: *queryStep,
roundDigits: rd,
dataSourceType: NewPrometheusType(), dataSourceType: NewPrometheusType(),
extraParams: extraParams,
}, nil }, nil
} }

View File

@ -18,11 +18,11 @@ type VMStorage struct {
appendTypePrefix bool appendTypePrefix bool
lookBack time.Duration lookBack time.Duration
queryStep time.Duration queryStep time.Duration
roundDigits string
dataSourceType Type dataSourceType Type
evaluationInterval time.Duration evaluationInterval time.Duration
extraLabels []string extraLabels []string
extraParams []Param
} }
// Clone makes clone of VMStorage, shares http client. // Clone makes clone of VMStorage, shares http client.

View File

@ -155,11 +155,11 @@ func (s *VMStorage) setPrometheusReqParams(r *http.Request, query string) {
// override step with user-specified value // override step with user-specified value
q.Set("step", s.queryStep.String()) q.Set("step", s.queryStep.String())
} }
if s.roundDigits != "" {
q.Set("round_digits", s.roundDigits)
}
for _, l := range s.extraLabels { for _, l := range s.extraLabels {
q.Add("extra_label", l) q.Add("extra_label", l)
} }
for _, p := range s.extraParams {
q.Add(p.Key, p.Value)
}
r.URL.RawQuery = q.Encode() r.URL.RawQuery = q.Encode()
} }

View File

@ -385,7 +385,7 @@ func TestRequestParams(t *testing.T) {
"round digits", "round digits",
false, false,
&VMStorage{ &VMStorage{
roundDigits: "10", extraParams: []Param{{"round_digits", "10"}},
}, },
func(t *testing.T, r *http.Request) { func(t *testing.T, r *http.Request) {
exp := fmt.Sprintf("query=%s&round_digits=10&time=%d", query, timestamp.Unix()) 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) 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 { for _, tc := range testCases {

View File

@ -91,7 +91,10 @@ func main() {
if err != nil { if err != nil {
logger.Fatalf("cannot parse configuration file: %s", err) 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 { if err != nil {
logger.Fatalf("failed to init datasource: %s", err) logger.Fatalf("failed to init datasource: %s", err)
} }
@ -139,7 +142,7 @@ var (
) )
func newManager(ctx context.Context) (*manager, error) { func newManager(ctx context.Context) (*manager, error) {
q, err := datasource.Init() q, err := datasource.Init(nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to init datasource: %w", err) return nil, fmt.Errorf("failed to init datasource: %w", err)
} }