-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#3513: Add GroupMarker interface #3792
Changes from all commits
ebf147f
3c8dc62
eca889b
6b056cc
64a03b8
d6055ea
cbe0128
47e952c
3132f61
88dfcdb
4a2781c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -52,9 +52,17 @@ type AlertStatus struct { | |||||||||||||||||||||||||||||||||||
silencesVersion int | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Marker helps to mark alerts as silenced and/or inhibited. | ||||||||||||||||||||||||||||||||||||
// groupStatus stores the state of the group, and, as applicable, the names | ||||||||||||||||||||||||||||||||||||
// of all active and mute time intervals that are muting it. | ||||||||||||||||||||||||||||||||||||
type groupStatus struct { | ||||||||||||||||||||||||||||||||||||
// mutedBy contains the names of all active and mute time intervals that | ||||||||||||||||||||||||||||||||||||
// are muting it. | ||||||||||||||||||||||||||||||||||||
mutedBy []string | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// AlertMarker helps to mark alerts as silenced and/or inhibited. | ||||||||||||||||||||||||||||||||||||
// All methods are goroutine-safe. | ||||||||||||||||||||||||||||||||||||
type Marker interface { | ||||||||||||||||||||||||||||||||||||
type AlertMarker interface { | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I renamed this interface to |
||||||||||||||||||||||||||||||||||||
// SetActiveOrSilenced replaces the previous SilencedBy by the provided IDs of | ||||||||||||||||||||||||||||||||||||
// active and pending silences, including the version number of the | ||||||||||||||||||||||||||||||||||||
// silences state. The set of provided IDs is supposed to represent the | ||||||||||||||||||||||||||||||||||||
|
@@ -92,24 +100,65 @@ type Marker interface { | |||||||||||||||||||||||||||||||||||
Inhibited(model.Fingerprint) ([]string, bool) | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// NewMarker returns an instance of a Marker implementation. | ||||||||||||||||||||||||||||||||||||
func NewMarker(r prometheus.Registerer) Marker { | ||||||||||||||||||||||||||||||||||||
m := &memMarker{ | ||||||||||||||||||||||||||||||||||||
m: map[model.Fingerprint]*AlertStatus{}, | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
// GroupMarker helps to mark groups as active or muted. | ||||||||||||||||||||||||||||||||||||
// All methods are goroutine-safe. | ||||||||||||||||||||||||||||||||||||
// | ||||||||||||||||||||||||||||||||||||
// TODO(grobinson): routeID is used in Muted and SetMuted because groupKey | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added a TODO in the source code to make it clear that this is not how I want the interface to look, but fixing this is blocked due to #3817 that we will fix in another PR. |
||||||||||||||||||||||||||||||||||||
// is not unique (see #3817). Once groupKey uniqueness is fixed routeID can | ||||||||||||||||||||||||||||||||||||
// be removed from the GroupMarker interface. | ||||||||||||||||||||||||||||||||||||
type GroupMarker interface { | ||||||||||||||||||||||||||||||||||||
// Muted returns true if the group is muted, otherwise false. If the group | ||||||||||||||||||||||||||||||||||||
// is muted then it also returns the names of the time intervals that muted | ||||||||||||||||||||||||||||||||||||
// it. | ||||||||||||||||||||||||||||||||||||
Muted(routeID, groupKey string) ([]string, bool) | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added |
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// SetMuted marks the group as muted, and sets the names of the time | ||||||||||||||||||||||||||||||||||||
// intervals that mute it. If the list of names is nil or the empty slice | ||||||||||||||||||||||||||||||||||||
// then the muted marker is removed. | ||||||||||||||||||||||||||||||||||||
SetMuted(routeID, groupKey string, timeIntervalNames []string) | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// NewMarker returns an instance of a AlertMarker implementation. | ||||||||||||||||||||||||||||||||||||
func NewMarker(r prometheus.Registerer) *MemMarker { | ||||||||||||||||||||||||||||||||||||
m := &MemMarker{ | ||||||||||||||||||||||||||||||||||||
alerts: map[model.Fingerprint]*AlertStatus{}, | ||||||||||||||||||||||||||||||||||||
groups: map[string]*groupStatus{}, | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is this gargage collected? As in, how does the marker now that it no longer needs to store the status of an alert. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See #3793 (comment). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. |
||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
m.registerMetrics(r) | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
return m | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
type memMarker struct { | ||||||||||||||||||||||||||||||||||||
m map[model.Fingerprint]*AlertStatus | ||||||||||||||||||||||||||||||||||||
type MemMarker struct { | ||||||||||||||||||||||||||||||||||||
alerts map[model.Fingerprint]*AlertStatus | ||||||||||||||||||||||||||||||||||||
groups map[string]*groupStatus | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
mtx sync.RWMutex | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
func (m *memMarker) registerMetrics(r prometheus.Registerer) { | ||||||||||||||||||||||||||||||||||||
// Muted implements GroupMarker. | ||||||||||||||||||||||||||||||||||||
func (m *MemMarker) Muted(routeID, groupKey string) ([]string, bool) { | ||||||||||||||||||||||||||||||||||||
m.mtx.Lock() | ||||||||||||||||||||||||||||||||||||
defer m.mtx.Unlock() | ||||||||||||||||||||||||||||||||||||
status, ok := m.groups[routeID+groupKey] | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since |
||||||||||||||||||||||||||||||||||||
if !ok { | ||||||||||||||||||||||||||||||||||||
return nil, false | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
return status.mutedBy, len(status.mutedBy) > 0 | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// SetMuted implements GroupMarker. | ||||||||||||||||||||||||||||||||||||
func (m *MemMarker) SetMuted(routeID, groupKey string, timeIntervalNames []string) { | ||||||||||||||||||||||||||||||||||||
m.mtx.Lock() | ||||||||||||||||||||||||||||||||||||
defer m.mtx.Unlock() | ||||||||||||||||||||||||||||||||||||
status, ok := m.groups[routeID+groupKey] | ||||||||||||||||||||||||||||||||||||
if !ok { | ||||||||||||||||||||||||||||||||||||
status = &groupStatus{} | ||||||||||||||||||||||||||||||||||||
m.groups[routeID+groupKey] = status | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
status.mutedBy = timeIntervalNames | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't we need to aggregate all the time-intervals that this has been muted by? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't – the reason is that the alertmanager/timeinterval/timeinterval.go Lines 37 to 53 in dacbf00
|
||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
func (m *MemMarker) registerMetrics(r prometheus.Registerer) { | ||||||||||||||||||||||||||||||||||||
newMarkedAlertMetricByState := func(st AlertState) prometheus.GaugeFunc { | ||||||||||||||||||||||||||||||||||||
return prometheus.NewGaugeFunc( | ||||||||||||||||||||||||||||||||||||
prometheus.GaugeOpts{ | ||||||||||||||||||||||||||||||||||||
|
@@ -132,17 +181,17 @@ func (m *memMarker) registerMetrics(r prometheus.Registerer) { | |||||||||||||||||||||||||||||||||||
r.MustRegister(alertStateUnprocessed) | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Count implements Marker. | ||||||||||||||||||||||||||||||||||||
func (m *memMarker) Count(states ...AlertState) int { | ||||||||||||||||||||||||||||||||||||
// Count implements AlertMarker. | ||||||||||||||||||||||||||||||||||||
func (m *MemMarker) Count(states ...AlertState) int { | ||||||||||||||||||||||||||||||||||||
m.mtx.RLock() | ||||||||||||||||||||||||||||||||||||
defer m.mtx.RUnlock() | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
if len(states) == 0 { | ||||||||||||||||||||||||||||||||||||
return len(m.m) | ||||||||||||||||||||||||||||||||||||
return len(m.alerts) | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
var count int | ||||||||||||||||||||||||||||||||||||
for _, status := range m.m { | ||||||||||||||||||||||||||||||||||||
for _, status := range m.alerts { | ||||||||||||||||||||||||||||||||||||
for _, state := range states { | ||||||||||||||||||||||||||||||||||||
if status.State == state { | ||||||||||||||||||||||||||||||||||||
count++ | ||||||||||||||||||||||||||||||||||||
|
@@ -152,15 +201,15 @@ func (m *memMarker) Count(states ...AlertState) int { | |||||||||||||||||||||||||||||||||||
return count | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// SetActiveOrSilenced implements Marker. | ||||||||||||||||||||||||||||||||||||
func (m *memMarker) SetActiveOrSilenced(alert model.Fingerprint, version int, activeIDs, pendingIDs []string) { | ||||||||||||||||||||||||||||||||||||
// SetActiveOrSilenced implements AlertMarker. | ||||||||||||||||||||||||||||||||||||
func (m *MemMarker) SetActiveOrSilenced(alert model.Fingerprint, version int, activeIDs, pendingIDs []string) { | ||||||||||||||||||||||||||||||||||||
m.mtx.Lock() | ||||||||||||||||||||||||||||||||||||
defer m.mtx.Unlock() | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
s, found := m.m[alert] | ||||||||||||||||||||||||||||||||||||
s, found := m.alerts[alert] | ||||||||||||||||||||||||||||||||||||
if !found { | ||||||||||||||||||||||||||||||||||||
s = &AlertStatus{} | ||||||||||||||||||||||||||||||||||||
m.m[alert] = s | ||||||||||||||||||||||||||||||||||||
m.alerts[alert] = s | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
s.SilencedBy = activeIDs | ||||||||||||||||||||||||||||||||||||
s.pendingSilences = pendingIDs | ||||||||||||||||||||||||||||||||||||
|
@@ -177,15 +226,15 @@ func (m *memMarker) SetActiveOrSilenced(alert model.Fingerprint, version int, ac | |||||||||||||||||||||||||||||||||||
s.State = AlertStateSuppressed | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// SetInhibited implements Marker. | ||||||||||||||||||||||||||||||||||||
func (m *memMarker) SetInhibited(alert model.Fingerprint, ids ...string) { | ||||||||||||||||||||||||||||||||||||
// SetInhibited implements AlertMarker. | ||||||||||||||||||||||||||||||||||||
func (m *MemMarker) SetInhibited(alert model.Fingerprint, ids ...string) { | ||||||||||||||||||||||||||||||||||||
m.mtx.Lock() | ||||||||||||||||||||||||||||||||||||
defer m.mtx.Unlock() | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
s, found := m.m[alert] | ||||||||||||||||||||||||||||||||||||
s, found := m.alerts[alert] | ||||||||||||||||||||||||||||||||||||
if !found { | ||||||||||||||||||||||||||||||||||||
s = &AlertStatus{} | ||||||||||||||||||||||||||||||||||||
m.m[alert] = s | ||||||||||||||||||||||||||||||||||||
m.alerts[alert] = s | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
s.InhibitedBy = ids | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
@@ -200,12 +249,12 @@ func (m *memMarker) SetInhibited(alert model.Fingerprint, ids ...string) { | |||||||||||||||||||||||||||||||||||
s.State = AlertStateSuppressed | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Status implements Marker. | ||||||||||||||||||||||||||||||||||||
func (m *memMarker) Status(alert model.Fingerprint) AlertStatus { | ||||||||||||||||||||||||||||||||||||
// Status implements AlertMarker. | ||||||||||||||||||||||||||||||||||||
func (m *MemMarker) Status(alert model.Fingerprint) AlertStatus { | ||||||||||||||||||||||||||||||||||||
m.mtx.RLock() | ||||||||||||||||||||||||||||||||||||
defer m.mtx.RUnlock() | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
if s, found := m.m[alert]; found { | ||||||||||||||||||||||||||||||||||||
if s, found := m.alerts[alert]; found { | ||||||||||||||||||||||||||||||||||||
return *s | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
return AlertStatus{ | ||||||||||||||||||||||||||||||||||||
|
@@ -215,26 +264,26 @@ func (m *memMarker) Status(alert model.Fingerprint) AlertStatus { | |||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Delete implements Marker. | ||||||||||||||||||||||||||||||||||||
func (m *memMarker) Delete(alert model.Fingerprint) { | ||||||||||||||||||||||||||||||||||||
// Delete implements AlertMarker. | ||||||||||||||||||||||||||||||||||||
func (m *MemMarker) Delete(alert model.Fingerprint) { | ||||||||||||||||||||||||||||||||||||
m.mtx.Lock() | ||||||||||||||||||||||||||||||||||||
defer m.mtx.Unlock() | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
delete(m.m, alert) | ||||||||||||||||||||||||||||||||||||
delete(m.alerts, alert) | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Unprocessed implements Marker. | ||||||||||||||||||||||||||||||||||||
func (m *memMarker) Unprocessed(alert model.Fingerprint) bool { | ||||||||||||||||||||||||||||||||||||
// Unprocessed implements AlertMarker. | ||||||||||||||||||||||||||||||||||||
func (m *MemMarker) Unprocessed(alert model.Fingerprint) bool { | ||||||||||||||||||||||||||||||||||||
return m.Status(alert).State == AlertStateUnprocessed | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Active implements Marker. | ||||||||||||||||||||||||||||||||||||
func (m *memMarker) Active(alert model.Fingerprint) bool { | ||||||||||||||||||||||||||||||||||||
// Active implements AlertMarker. | ||||||||||||||||||||||||||||||||||||
func (m *MemMarker) Active(alert model.Fingerprint) bool { | ||||||||||||||||||||||||||||||||||||
return m.Status(alert).State == AlertStateActive | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// Inhibited implements Marker. | ||||||||||||||||||||||||||||||||||||
func (m *memMarker) Inhibited(alert model.Fingerprint) ([]string, bool) { | ||||||||||||||||||||||||||||||||||||
// Inhibited implements AlertMarker. | ||||||||||||||||||||||||||||||||||||
func (m *MemMarker) Inhibited(alert model.Fingerprint) ([]string, bool) { | ||||||||||||||||||||||||||||||||||||
s := m.Status(alert) | ||||||||||||||||||||||||||||||||||||
return s.InhibitedBy, | ||||||||||||||||||||||||||||||||||||
s.State == AlertStateSuppressed && len(s.InhibitedBy) > 0 | ||||||||||||||||||||||||||||||||||||
|
@@ -243,7 +292,7 @@ func (m *memMarker) Inhibited(alert model.Fingerprint) ([]string, bool) { | |||||||||||||||||||||||||||||||||||
// Silenced returns whether the alert for the given Fingerprint is in the | ||||||||||||||||||||||||||||||||||||
// Silenced state, any associated silence IDs, and the silences state version | ||||||||||||||||||||||||||||||||||||
// the result is based on. | ||||||||||||||||||||||||||||||||||||
func (m *memMarker) Silenced(alert model.Fingerprint) (activeIDs, pendingIDs []string, version int, silenced bool) { | ||||||||||||||||||||||||||||||||||||
func (m *MemMarker) Silenced(alert model.Fingerprint) (activeIDs, pendingIDs []string, version int, silenced bool) { | ||||||||||||||||||||||||||||||||||||
s := m.Status(alert) | ||||||||||||||||||||||||||||||||||||
return s.SilencedBy, s.pendingSilences, s.silencesVersion, | ||||||||||||||||||||||||||||||||||||
s.State == AlertStateSuppressed && len(s.SilencedBy) > 0 | ||||||||||||||||||||||||||||||||||||
|
@@ -410,7 +459,7 @@ func (a *Alert) Merge(o *Alert) *Alert { | |||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// A Muter determines whether a given label set is muted. Implementers that | ||||||||||||||||||||||||||||||||||||
// maintain an underlying Marker are expected to update it during a call of | ||||||||||||||||||||||||||||||||||||
// maintain an underlying AlertMarker are expected to update it during a call of | ||||||||||||||||||||||||||||||||||||
// Mutes. | ||||||||||||||||||||||||||||||||||||
type Muter interface { | ||||||||||||||||||||||||||||||||||||
Mutes(model.LabelSet) bool | ||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This claims to store the state of the group but its only attribute is
mutedBy
is this correct?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! I copied it from here: