alertmanager/types/types.go

167 lines
4.0 KiB
Go
Raw Normal View History

2015-10-11 15:24:49 +00:00
// Copyright 2015 Prometheus Team
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2015-09-25 12:38:22 +00:00
package types
2015-09-25 16:14:46 +00:00
import (
"fmt"
"hash/fnv"
2015-10-11 10:40:43 +00:00
"strings"
2015-09-25 16:14:46 +00:00
"time"
"github.com/prometheus/common/model"
)
2015-10-11 10:40:43 +00:00
type MultiError []error
func (e MultiError) Error() string {
var es []string
for _, err := range e {
es = append(es, err.Error())
}
return strings.Join(es, "; ")
}
2015-10-01 12:53:49 +00:00
// Alert wraps a model.Alert with additional information relevant
// to internal of the Alertmanager.
// The type is never exposed to external communication and the
// embedded alert has to be sanitized beforehand.
2015-09-25 12:38:22 +00:00
type Alert struct {
2015-10-01 12:53:49 +00:00
model.Alert
2015-09-25 12:38:22 +00:00
// The authoritative timestamp.
2015-10-01 15:50:15 +00:00
UpdatedAt time.Time `json:"-"`
Timeout bool `json:"-"`
}
// Alerts turns a sequence of internal alerts into a list of
// exposable model.Alert structures.
func Alerts(alerts ...*Alert) model.Alerts {
var res model.Alerts
for _, a := range alerts {
v := a.Alert
// If the end timestamp was set as the expected value in case
// of a timeout but is not reached yet, do not expose it.
if a.Timeout && !a.Resolved() {
v.EndsAt = time.Time{}
}
res = append(res, &v)
}
return res
2015-09-25 12:38:22 +00:00
}
2015-09-28 12:13:01 +00:00
// Merges the timespan of two alerts based and overwrites annotations
// based on the authoritative timestamp.
// A new alert is returned, the labels are assumed to be equal.
2015-10-02 14:52:04 +00:00
func (a *Alert) Merge(o *Alert) *Alert {
// Let o always be the younger alert.
if !a.UpdatedAt.Before(o.UpdatedAt) {
return o.Merge(a)
}
res := *o
// Always pick the earliest starting time.
if a.StartsAt.Before(o.StartsAt) {
res.StartsAt = a.StartsAt
}
// An non-timeout resolved timestamp always rules.
// The latest explicit resolved timestamp wins.
if a.EndsAt.After(o.EndsAt) && !a.Timeout {
res.EndsAt = a.EndsAt
}
return &res
}
2015-09-25 12:38:22 +00:00
2015-09-25 16:14:46 +00:00
// A Silencer determines whether a given label set is muted.
2015-09-28 12:13:01 +00:00
type Muter interface {
2015-09-25 16:14:46 +00:00
Mutes(model.LabelSet) bool
}
2015-09-28 12:13:01 +00:00
type MuteFunc func(model.LabelSet) bool
func (f MuteFunc) Mutes(lset model.LabelSet) bool { return f(lset) }
2015-09-25 16:14:46 +00:00
// A Silence determines whether a given label set is muted
// at the current time.
type Silence struct {
2015-10-01 15:50:15 +00:00
model.Silence
2015-09-25 16:14:46 +00:00
2015-09-27 12:07:04 +00:00
// A set of matchers determining if an alert is affected
// by the silence.
2015-10-01 15:50:15 +00:00
Matchers Matchers `json:"-"`
2015-09-25 16:14:46 +00:00
// timeFunc provides the time against which to evaluate
// the silence.
timeFunc func() time.Time
}
2015-10-01 15:50:15 +00:00
// NewSilence creates a new internal Silence from a public silence
// object.
func NewSilence(s *model.Silence) *Silence {
sil := &Silence{
Silence: *s,
timeFunc: time.Now,
2015-09-27 12:25:56 +00:00
}
2015-10-01 15:50:15 +00:00
for _, m := range s.Matchers {
2015-09-27 12:25:56 +00:00
if !m.IsRegex {
sil.Matchers = append(sil.Matchers, NewMatcher(m.Name, m.Value))
continue
}
rem, err := NewRegexMatcher(m.Name, m.Value)
if err != nil {
2015-10-01 15:50:15 +00:00
// Must have been sanitized beforehand.
panic(err)
2015-09-27 12:25:56 +00:00
}
sil.Matchers = append(sil.Matchers, rem)
}
2015-10-01 15:50:15 +00:00
return sil
2015-09-27 12:25:56 +00:00
}
2015-10-01 15:50:15 +00:00
func (sil *Silence) Mutes(lset model.LabelSet) bool {
t := sil.timeFunc()
2015-09-27 12:25:56 +00:00
2015-10-01 15:50:15 +00:00
if t.Before(sil.StartsAt) || t.After(sil.EndsAt) {
return false
2015-09-27 12:25:56 +00:00
}
2015-10-01 15:50:15 +00:00
b := sil.Matchers.Match(lset)
return b
2015-09-27 12:25:56 +00:00
}
2015-10-01 15:50:15 +00:00
// Notify holds information about the last notification state
// of an Alert.
type Notify struct {
Alert model.Fingerprint
SendTo string
Resolved bool
Delivered bool
Timestamp time.Time
}
func (n *Notify) String() string {
return fmt.Sprintf("<Notify:%q@%s to=%v res=%v deli=%v>", n.Alert, n.Timestamp, n.SendTo, n.Resolved, n.Delivered)
}
func (n *Notify) Fingerprint() model.Fingerprint {
h := fnv.New64a()
h.Write([]byte(n.SendTo))
fp := model.Fingerprint(h.Sum64())
return fp ^ n.Alert
}