mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2025-01-20 15:16:42 +00:00
adds external_labels per group for vmalert (#1485)
* adds external_label per group for vmalert https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1471
This commit is contained in:
parent
eff940aa76
commit
7c70dcbe3b
9 changed files with 70 additions and 20 deletions
|
@ -95,6 +95,13 @@ name: <string>
|
||||||
extra_filter_labels:
|
extra_filter_labels:
|
||||||
[ <labelname>: <labelvalue> ... ]
|
[ <labelname>: <labelvalue> ... ]
|
||||||
|
|
||||||
|
# Optional list of labels added to every rule within a group.
|
||||||
|
# It has priority over the external labels.
|
||||||
|
# Labels are commonly used for adding environment
|
||||||
|
# or tenant-specific tag.
|
||||||
|
labels:
|
||||||
|
[ <labelname>: <labelvalue> ... ]
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
[ - <rule> ... ]
|
[ - <rule> ... ]
|
||||||
```
|
```
|
||||||
|
|
|
@ -31,6 +31,9 @@ type Group struct {
|
||||||
// request withing a group. Is compatible only with VM datasources.
|
// request withing a group. Is compatible only with VM datasources.
|
||||||
// See https://docs.victoriametrics.com#prometheus-querying-api-enhancements
|
// See https://docs.victoriametrics.com#prometheus-querying-api-enhancements
|
||||||
ExtraFilterLabels map[string]string `yaml:"extra_filter_labels"`
|
ExtraFilterLabels map[string]string `yaml:"extra_filter_labels"`
|
||||||
|
// Labels is a set of label value pairs, that will be added to every rule.
|
||||||
|
// It has priority over the external labels.
|
||||||
|
Labels map[string]string `yaml:"labels"`
|
||||||
// Checksum stores the hash of yaml definition for this group.
|
// Checksum stores the hash of yaml definition for this group.
|
||||||
// May be used to detect any changes like rules re-ordering etc.
|
// May be used to detect any changes like rules re-ordering etc.
|
||||||
Checksum string
|
Checksum string
|
||||||
|
|
|
@ -3,6 +3,8 @@ groups:
|
||||||
interval: 2s
|
interval: 2s
|
||||||
concurrency: 2
|
concurrency: 2
|
||||||
type: prometheus
|
type: prometheus
|
||||||
|
labels:
|
||||||
|
cluster: main
|
||||||
rules:
|
rules:
|
||||||
- alert: up
|
- alert: up
|
||||||
expr: up == 0
|
expr: up == 0
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
groups:
|
groups:
|
||||||
- name: duplicatedGroupDiffFiles
|
- name: duplicatedGroupDiffFiles
|
||||||
|
labels:
|
||||||
|
dc: gcp
|
||||||
rules:
|
rules:
|
||||||
- alert: VMRows
|
- alert: VMRows
|
||||||
for: 5m
|
for: 5m
|
||||||
|
|
|
@ -18,15 +18,17 @@ import (
|
||||||
|
|
||||||
// Group is an entity for grouping rules
|
// Group is an entity for grouping rules
|
||||||
type Group struct {
|
type Group struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
Name string
|
Name string
|
||||||
File string
|
File string
|
||||||
Rules []Rule
|
Rules []Rule
|
||||||
Type datasource.Type
|
Type datasource.Type
|
||||||
Interval time.Duration
|
Interval time.Duration
|
||||||
Concurrency int
|
Concurrency int
|
||||||
Checksum string
|
Checksum string
|
||||||
|
|
||||||
ExtraFilterLabels map[string]string
|
ExtraFilterLabels map[string]string
|
||||||
|
Labels map[string]string
|
||||||
|
|
||||||
doneCh chan struct{}
|
doneCh chan struct{}
|
||||||
finishedCh chan struct{}
|
finishedCh chan struct{}
|
||||||
|
@ -50,6 +52,23 @@ func newGroupMetrics(name, file string) *groupMetrics {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// merges group rule labels into result map
|
||||||
|
// set2 has priority over set1.
|
||||||
|
func mergeLabels(groupName, ruleName string, set1, set2 map[string]string) map[string]string {
|
||||||
|
r := map[string]string{}
|
||||||
|
for k, v := range set1 {
|
||||||
|
r[k] = v
|
||||||
|
}
|
||||||
|
for k, v := range set2 {
|
||||||
|
if prevV, ok := r[k]; ok {
|
||||||
|
logger.Infof("label %q=%q for rule %q.%q overwritten with external label %q=%q",
|
||||||
|
k, prevV, groupName, ruleName, k, v)
|
||||||
|
}
|
||||||
|
r[k] = v
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
func newGroup(cfg config.Group, qb datasource.QuerierBuilder, defaultInterval time.Duration, labels map[string]string) *Group {
|
func newGroup(cfg config.Group, qb datasource.QuerierBuilder, defaultInterval time.Duration, labels map[string]string) *Group {
|
||||||
g := &Group{
|
g := &Group{
|
||||||
Type: cfg.Type,
|
Type: cfg.Type,
|
||||||
|
@ -59,6 +78,7 @@ func newGroup(cfg config.Group, qb datasource.QuerierBuilder, defaultInterval ti
|
||||||
Concurrency: cfg.Concurrency,
|
Concurrency: cfg.Concurrency,
|
||||||
Checksum: cfg.Checksum,
|
Checksum: cfg.Checksum,
|
||||||
ExtraFilterLabels: cfg.ExtraFilterLabels,
|
ExtraFilterLabels: cfg.ExtraFilterLabels,
|
||||||
|
Labels: cfg.Labels,
|
||||||
|
|
||||||
doneCh: make(chan struct{}),
|
doneCh: make(chan struct{}),
|
||||||
finishedCh: make(chan struct{}),
|
finishedCh: make(chan struct{}),
|
||||||
|
@ -73,17 +93,20 @@ func newGroup(cfg config.Group, qb datasource.QuerierBuilder, defaultInterval ti
|
||||||
}
|
}
|
||||||
rules := make([]Rule, len(cfg.Rules))
|
rules := make([]Rule, len(cfg.Rules))
|
||||||
for i, r := range cfg.Rules {
|
for i, r := range cfg.Rules {
|
||||||
// override rule labels with external labels
|
var extraLabels map[string]string
|
||||||
for k, v := range labels {
|
// apply external labels
|
||||||
if prevV, ok := r.Labels[k]; ok {
|
if len(labels) > 0 {
|
||||||
logger.Infof("label %q=%q for rule %q.%q overwritten with external label %q=%q",
|
extraLabels = labels
|
||||||
k, prevV, g.Name, r.Name(), k, v)
|
|
||||||
}
|
|
||||||
if r.Labels == nil {
|
|
||||||
r.Labels = map[string]string{}
|
|
||||||
}
|
|
||||||
r.Labels[k] = v
|
|
||||||
}
|
}
|
||||||
|
// apply group labels, it has priority on external labels
|
||||||
|
if len(cfg.Labels) > 0 {
|
||||||
|
extraLabels = mergeLabels(g.Name, r.Name(), extraLabels, g.Labels)
|
||||||
|
}
|
||||||
|
// apply rules labels, it has priority on other labels
|
||||||
|
if len(extraLabels) > 0 {
|
||||||
|
r.Labels = mergeLabels(g.Name, r.Name(), extraLabels, r.Labels)
|
||||||
|
}
|
||||||
|
|
||||||
rules[i] = g.newRule(qb, r)
|
rules[i] = g.newRule(qb, r)
|
||||||
}
|
}
|
||||||
g.Rules = rules
|
g.Rules = rules
|
||||||
|
@ -110,6 +133,7 @@ func (g *Group) ID() uint64 {
|
||||||
|
|
||||||
// Restore restores alerts state for group rules
|
// Restore restores alerts state for group rules
|
||||||
func (g *Group) Restore(ctx context.Context, qb datasource.QuerierBuilder, lookback time.Duration, labels map[string]string) error {
|
func (g *Group) Restore(ctx context.Context, qb datasource.QuerierBuilder, lookback time.Duration, labels map[string]string) error {
|
||||||
|
labels = mergeLabels(g.Name, "", labels, g.Labels)
|
||||||
for _, rule := range g.Rules {
|
for _, rule := range g.Rules {
|
||||||
rr, ok := rule.(*AlertingRule)
|
rr, ok := rule.(*AlertingRule)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -169,6 +193,7 @@ func (g *Group) updateWith(newGroup *Group) error {
|
||||||
g.Type = newGroup.Type
|
g.Type = newGroup.Type
|
||||||
g.Concurrency = newGroup.Concurrency
|
g.Concurrency = newGroup.Concurrency
|
||||||
g.ExtraFilterLabels = newGroup.ExtraFilterLabels
|
g.ExtraFilterLabels = newGroup.ExtraFilterLabels
|
||||||
|
g.Labels = newGroup.Labels
|
||||||
g.Checksum = newGroup.Checksum
|
g.Checksum = newGroup.Checksum
|
||||||
g.Rules = newRules
|
g.Rules = newRules
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -148,6 +148,7 @@ func (g *Group) toAPI() APIGroup {
|
||||||
Interval: g.Interval.String(),
|
Interval: g.Interval.String(),
|
||||||
Concurrency: g.Concurrency,
|
Concurrency: g.Concurrency,
|
||||||
ExtraFilterLabels: g.ExtraFilterLabels,
|
ExtraFilterLabels: g.ExtraFilterLabels,
|
||||||
|
Labels: g.Labels,
|
||||||
}
|
}
|
||||||
for _, r := range g.Rules {
|
for _, r := range g.Rules {
|
||||||
switch v := r.(type) {
|
switch v := r.(type) {
|
||||||
|
|
|
@ -148,7 +148,7 @@ func TestManagerUpdate(t *testing.T) {
|
||||||
Name: "VMRows",
|
Name: "VMRows",
|
||||||
Expr: "vm_rows > 0",
|
Expr: "vm_rows > 0",
|
||||||
For: 5 * time.Minute,
|
For: 5 * time.Minute,
|
||||||
Labels: map[string]string{"label": "bar"},
|
Labels: map[string]string{"dc": "gcp", "label": "bar"},
|
||||||
Annotations: map[string]string{
|
Annotations: map[string]string{
|
||||||
"summary": "{{ $value }}",
|
"summary": "{{ $value }}",
|
||||||
"description": "{{$labels}}",
|
"description": "{{$labels}}",
|
||||||
|
|
|
@ -27,6 +27,7 @@ type APIGroup struct {
|
||||||
Interval string `json:"interval"`
|
Interval string `json:"interval"`
|
||||||
Concurrency int `json:"concurrency"`
|
Concurrency int `json:"concurrency"`
|
||||||
ExtraFilterLabels map[string]string `json:"extra_filter_labels"`
|
ExtraFilterLabels map[string]string `json:"extra_filter_labels"`
|
||||||
|
Labels map[string]string `json:"labels,omitempty"`
|
||||||
AlertingRules []APIAlertingRule `json:"alerting_rules"`
|
AlertingRules []APIAlertingRule `json:"alerting_rules"`
|
||||||
RecordingRules []APIRecordingRule `json:"recording_rules"`
|
RecordingRules []APIRecordingRule `json:"recording_rules"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,13 @@ name: <string>
|
||||||
extra_filter_labels:
|
extra_filter_labels:
|
||||||
[ <labelname>: <labelvalue> ... ]
|
[ <labelname>: <labelvalue> ... ]
|
||||||
|
|
||||||
|
# Optional list of labels added to every rule within a group.
|
||||||
|
# It has priority over the external labels.
|
||||||
|
# Labels are commonly used for adding environment
|
||||||
|
# or tenant-specific tag.
|
||||||
|
labels:
|
||||||
|
[ <labelname>: <labelvalue> ... ]
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
[ - <rule> ... ]
|
[ - <rule> ... ]
|
||||||
```
|
```
|
||||||
|
@ -509,7 +516,9 @@ The shortlist of configuration flags is the following:
|
||||||
-remoteWrite.tlsServerName string
|
-remoteWrite.tlsServerName string
|
||||||
Optional TLS server name to use for connections to -remoteWrite.url. By default the server name from -remoteWrite.url is used
|
Optional TLS server name to use for connections to -remoteWrite.url. By default the server name from -remoteWrite.url is used
|
||||||
-remoteWrite.url string
|
-remoteWrite.url string
|
||||||
Optional URL to VictoriaMetrics or vminsert where to persist alerts state and recording rules results in form of timeseries. For example, if -remoteWrite.url=http://127.0.0.1:8428 is specified, then the alerts state will be written to http://127.0.0.1:8428/api/v1/write . See also -remoteWrite.disablePathAppend
|
Optional URL to VictoriaMetrics or vminsert where to persist alerts state and recording rules results in form of timeseries. For example, if -remoteWrite.url=http://127.0.0.1:8428 is specified, then the alerts state will be written to http://127.0.0.1:8428/api/v1/write . See also -remoteWrite.disablePathAppend
|
||||||
|
-remoteWrite.disablePathAppend
|
||||||
|
Whether to disable automatic appending of '/api/v1/write' path to the configured -remoteWrite.url.
|
||||||
-replay.maxDatapointsPerQuery int
|
-replay.maxDatapointsPerQuery int
|
||||||
Max number of data points expected in one request. The higher the value, the less requests will be made during replay. (default 1000)
|
Max number of data points expected in one request. The higher the value, the less requests will be made during replay. (default 1000)
|
||||||
-replay.ruleRetryAttempts int
|
-replay.ruleRetryAttempts int
|
||||||
|
|
Loading…
Reference in a new issue