summaryrefslogtreecommitdiff
path: root/internal/run.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/run.go')
-rw-r--r--internal/run.go38
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 {