Repository: prometheus/alertmanager
File: types/types.go (Go)

Code before:

	// Count alerts of the given state(s). With no state provided, count all
	// alerts.
	Count(...AlertState) int

	// Status of the given alert.
	Status(model.Fingerprint) AlertStatus
	// Delete the given alert.
	Delete(model.Fingerprint)

	// Various methods to inquire if the given alert is in a certain
	// AlertState. Silenced also returns all the active and pending
	// silences, while Inhibited may return only a subset of inhibiting
	// alerts. Silenced also returns the version of the silences state the
	// result is based on.
	Unprocessed(model.Fingerprint) bool
	Active(model.Fingerprint) bool
	Silenced(model.Fingerprint) (activeIDs, pendingIDs []string, version int, silenced bool)
	Inhibited(model.Fingerprint) ([]string, bool)
}

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(groupKey string) ([]string, bool)

	// 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(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{},
	}
	m.registerMetrics(r)
	return m
}

type MemMarker struct {
	alerts map[model.Fingerprint]*AlertStatus
	groups map[string]*groupStatus

	mtx sync.RWMutex
}

// Muted implements GroupMarker.

Review comment (suggestion):
In the original version of `GroupMarker` I had:

```go
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(groupKey string, fingerprint model.Fingerprint) ([]string, bool)
	...
}
```

but then I realized we didn't need to store the fingerprint at all.

The reason here is that active and mute timings work against routes. That means either all alerts in an aggregation group are suppressed because of time intervals, or none of them are. It is not possible to have two alerts A and B in the same aggregation group, where A is muted from a mute time interval and B is not.

Code after:

	// Count alerts of the given state(s). With no state provided, count all
	// alerts.
	Count(...AlertState) int

	// Status of the given alert.
	Status(model.Fingerprint) AlertStatus
	// Delete the given alert.
	Delete(model.Fingerprint)

	// Various methods to inquire if the given alert is in a certain
	// AlertState. Silenced also returns all the active and pending
	// silences, while Inhibited may return only a subset of inhibiting
	// alerts. Silenced also returns the version of the silences state the
	// result is based on.
	Unprocessed(model.Fingerprint) bool
	Active(model.Fingerprint) bool
	Silenced(model.Fingerprint) (activeIDs, pendingIDs []string, version int, silenced bool)
	Inhibited(model.Fingerprint) ([]string, bool)
}

// 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
// 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)

	// 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{},
	}
	m.registerMetrics(r)
	return m
}

type MemMarker struct {
	alerts map[model.Fingerprint]*AlertStatus