Skip to content
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

Add silence logging option #2536

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmd/alertmanager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ func run() int {
dataDir = kingpin.Flag("storage.path", "Base path for data storage.").Default("data/").String()
retention = kingpin.Flag("data.retention", "How long to keep data for.").Default("120h").Duration()
alertGCInterval = kingpin.Flag("alerts.gc-interval", "Interval between alert GC.").Default("30m").Duration()
silenceLogging = kingpin.Flag("silences.logging", "Enable logging silences. If it is enabled, the status change of silence will be logged").Bool()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should match the existing log-related flags like --log.level, so how about "log.silences"?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in #4163


webConfig = webflag.AddFlags(kingpin.CommandLine)
externalURL = kingpin.Flag("web.external-url", "The URL under which Alertmanager is externally reachable (for example, if Alertmanager is served via a reverse proxy). Used for generating relative and absolute links back to Alertmanager itself. If the URL has a path portion, it will be used to prefix all HTTP endpoints served by Alertmanager. If omitted, relevant URL components will be derived automatically.").String()
Expand Down Expand Up @@ -278,6 +279,7 @@ func run() int {
Retention: *retention,
Logger: log.With(logger, "component", "silences"),
Metrics: prometheus.DefaultRegisterer,
Logging: *silenceLogging,
}

silences, err := silence.New(silenceOpts)
Expand Down
43 changes: 43 additions & 0 deletions silence/silence.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"reflect"
"regexp"
"sort"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -183,6 +184,7 @@ type Silences struct {
metrics *metrics
now func() time.Time
retention time.Duration
logging bool

mtx sync.RWMutex
st state
Expand Down Expand Up @@ -289,6 +291,8 @@ type Options struct {
// garbage collected after the given duration after they ended.
Retention time.Duration

Logging bool

// A logger used by background processing.
Logger log.Logger
Metrics prometheus.Registerer
Expand Down Expand Up @@ -319,6 +323,7 @@ func New(o Options) (*Silences, error) {
mc: matcherCache{},
logger: log.NewNopLogger(),
retention: o.Retention,
logging: o.Logging,
now: utcNow,
broadcast: func([]byte) {},
st: state{},
Expand Down Expand Up @@ -530,6 +535,9 @@ func (s *Silences) Set(sil *pb.Silence) (string, error) {
}
if ok {
if canUpdate(prev, sil, now) {
if s.logging {
s.logginSilences("update silence", sil)
}
return sil.Id, s.setSilence(sil, now)
}
if getState(prev, s.now()) != types.SilenceStateExpired {
Expand All @@ -550,6 +558,10 @@ func (s *Silences) Set(sil *pb.Silence) (string, error) {
sil.StartsAt = now
}

if s.logging {
s.logginSilences("create silence", sil)
}

return sil.Id, s.setSilence(sil, now)
}

Expand Down Expand Up @@ -607,6 +619,10 @@ func (s *Silences) expire(id string) error {
sil.EndsAt = now
}

if s.logging {
s.logginSilences("expire silence", sil)
}

return s.setSilence(sil, now)
}

Expand Down Expand Up @@ -943,3 +959,30 @@ func openReplace(filename string) (*replaceFile, error) {
}
return rf, nil
}

// logging silence status changes.
func (s *Silences) logginSilences(msg string, sil *pb.Silence) {
var listMatchers []string
var matcher_type_operator = map[string]string{
"EQUAL": "=",
"REGEXP": "=~",
"NOT_EQUAL": "!=",
"NOT_REGEXP": "!~",
}
for _, matcher := range sil.Matchers {
ms := []string{matcher.Name, matcher_type_operator[matcher.Type.String()], matcher.Pattern}
m := strings.Join(ms, ``)
listMatchers = append(listMatchers, m)
}
strMatchers := strings.Join(listMatchers, `,`)

level.Info(s.logger).Log(
"msg", msg,
"Id", sil.Id,
"CreatedBy", sil.CreatedBy,
"Comment", sil.Comment,
"StartsAt", sil.StartsAt,
"EndsAt", sil.EndsAt,
"Matchers", strMatchers,
)
}