diff options
Diffstat (limited to 'internal/run.go')
| -rw-r--r-- | internal/run.go | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/internal/run.go b/internal/run.go index 9d1b21c..63ee16f 100644 --- a/internal/run.go +++ b/internal/run.go @@ -7,10 +7,10 @@ import ( "os" ) -func Run(ctx context.Context, configFile string, renotify, force bool) { +func Run(ctx context.Context, configFile string, renotify, force bool) error { conf, err := newConfig(configFile) if err != nil { - log.Fatal(err) + return err } if err := conf.sanityCheck(); err != nil { @@ -22,6 +22,13 @@ func Run(ctx context.Context, configFile string, renotify, force bool) { notifyError(conf, err) } + // Load notification state for batching (tracks when last email was sent + // and what the check states were at that time) + notifyStateData, err := newNotifyState(conf.StateDir) + if err != nil { + log.Println("warning: failed to load notification state:", err) + } + state = runChecks(ctx, state, conf) state = mergePrometheusAlerts(ctx, state, conf) state = mergeFederated(ctx, state, conf) @@ -31,12 +38,35 @@ func Run(ctx context.Context, configFile string, renotify, force bool) { } subject, body, doNotify := state.report(renotify, force, conf.StatusPageURL, conf) + + // Apply notification batching when MinNotifyIntervalS is configured. + // Force flag bypasses batching to allow immediate notifications when needed. + if doNotify && conf.MinNotifyIntervalS > 0 && !force { + if notifyStateData.intervalElapsed(conf.MinNotifyIntervalS) { + // Interval has elapsed - only notify if state changed since last notification + if !notifyStateData.hasChanges(state) { + doNotify = false + log.Println("Notification suppressed: interval elapsed but no state changes since last notification") + } + } else { + // Interval has not elapsed - suppress notification + doNotify = false + log.Println("Notification suppressed: minimum interval not elapsed") + } + } + if doNotify { if err := notify(conf, subject, body); err != nil { log.Println("error:", err) - return + return nil + } + // Record notification timestamp and state snapshot for batching + if err := notifyStateData.recordNotification(state); err != nil { + log.Println("warning: failed to save notification state:", err) } } + + // Text and HTML reports always update regardless of notification batching if err := persistReport(subject, body, conf); err != nil { notifyError(conf, err) } @@ -47,6 +77,8 @@ func Run(ctx context.Context, configFile string, renotify, force bool) { notifyError(conf, err) } } + + return nil } func persistReport(subject, body string, conf config) error { |
