diff --git a/cmd/alertmanager/main.go b/cmd/alertmanager/main.go index 06d697a0..74703e94 100644 --- a/cmd/alertmanager/main.go +++ b/cmd/alertmanager/main.go @@ -271,7 +271,7 @@ func run() int { silenceOpts := silence.Options{ SnapshotFile: filepath.Join(*dataDir, "silences"), Retention: *retention, - Limits: silence.Limits{ + Limits: &silence.Limits{ MaxSilences: func() int { return *maxSilences }, MaxSilenceSizeBytes: func() int { return *maxSilenceSizeBytes }, }, diff --git a/silence/silence.go b/silence/silence.go index ee975519..2d38392e 100644 --- a/silence/silence.go +++ b/silence/silence.go @@ -193,7 +193,7 @@ type Silences struct { logger log.Logger metrics *metrics retention time.Duration - limits Limits + limits *Limits mtx sync.RWMutex st state @@ -202,6 +202,12 @@ type Silences struct { mc matcherCache } +// NoopLimits are the default limits. All limits are disabled. +var NoopLimits = &Limits{ + MaxSilences: func() int { return 0 }, + MaxSilenceSizeBytes: func() int { return 0 }, +} + // Limits contains the limits for silences. type Limits struct { // MaxSilences limits the maximum number of silences, including expired @@ -329,7 +335,7 @@ type Options struct { // Retention time for newly created Silences. Silences may be // garbage collected after the given duration after they ended. Retention time.Duration - Limits Limits + Limits *Limits // A logger used by background processing. Logger log.Logger @@ -354,7 +360,7 @@ func New(o Options) (*Silences, error) { mc: matcherCache{}, logger: log.NewNopLogger(), retention: o.Retention, - limits: o.Limits, + limits: NoopLimits, broadcast: func([]byte) {}, st: state{}, } @@ -364,6 +370,10 @@ func New(o Options) (*Silences, error) { s.logger = o.Logger } + if o.Limits != nil { + s.limits = o.Limits + } + if o.SnapshotFile != "" { if r, err := os.Open(o.SnapshotFile); err != nil { if !os.IsNotExist(err) { @@ -551,11 +561,9 @@ func cloneSilence(sil *pb.Silence) *pb.Silence { } func (s *Silences) checkSizeLimits(msil *pb.MeshSilence) error { - if s.limits.MaxSilenceSizeBytes != nil { - n := msil.Size() - if m := s.limits.MaxSilenceSizeBytes(); m > 0 && n > m { - return fmt.Errorf("silence exceeded maximum size: %d bytes (limit: %d bytes)", n, m) - } + n := msil.Size() + if m := s.limits.MaxSilenceSizeBytes(); m > 0 && n > m { + return fmt.Errorf("silence exceeded maximum size: %d bytes (limit: %d bytes)", n, m) } return nil } @@ -619,10 +627,8 @@ func (s *Silences) Set(sil *pb.Silence) error { // If we got here it's either a new silence or a replacing one (which would // also create a new silence) so we need to make sure we have capacity for // the new silence. - if s.limits.MaxSilences != nil { - if m := s.limits.MaxSilences(); m > 0 && len(s.st)+1 > m { - return fmt.Errorf("exceeded maximum number of silences: %d (limit: %d)", len(s.st), m) - } + if m := s.limits.MaxSilences(); m > 0 && len(s.st)+1 > m { + return fmt.Errorf("exceeded maximum number of silences: %d (limit: %d)", len(s.st), m) } uid, err := uuid.NewV4() diff --git a/silence/silence_test.go b/silence/silence_test.go index 6fe536e5..4074228a 100644 --- a/silence/silence_test.go +++ b/silence/silence_test.go @@ -485,7 +485,7 @@ func TestSilenceSet(t *testing.T) { func TestSilenceLimits(t *testing.T) { s, err := New(Options{ - Limits: Limits{ + Limits: &Limits{ MaxSilences: func() int { return 1 }, MaxSilenceSizeBytes: func() int { return 2 << 11 }, // 4KB }, @@ -606,7 +606,8 @@ func TestSilenceLimits(t *testing.T) { func TestSilenceNoLimits(t *testing.T) { s, err := New(Options{ - Limits: Limits{}, + // Should be replaced with NoopLimits. + Limits: nil, }) require.NoError(t, err)