Compare commits

..

1 Commits

Author SHA1 Message Date
Ian Fijolek
e4e6618af1 Adds ability to run specified alerts on startup
This is helpful to determine if your alerts are valid before an actual failure
2024-04-03 11:50:49 -07:00
2 changed files with 99 additions and 0 deletions
+38
View File
@@ -4,6 +4,7 @@ import (
"errors"
"flag"
"fmt"
"strings"
"time"
"git.iamthefij.com/iamthefij/slog"
@@ -91,9 +92,38 @@ func checkMonitors(config *Config) error {
return nil
}
func sendFirstRunAlerts(config *Config, alertNames []string) error {
for _, alertName := range alertNames {
var err error
alert, ok := config.Alerts[alertName]
if !ok {
err = fmt.Errorf("unknown alert %s: %w", alertName, errUnknownAlert)
}
if err == nil {
_, err = alert.Send(AlertNotice{
AlertCount: 0,
FailureCount: 0,
IsUp: true,
LastSuccess: time.Now(),
MonitorName: fmt.Sprintf("First Run Alert Test: %s", alert.Name),
LastCheckOutput: "",
})
}
if err != nil {
return err
}
}
return nil
}
func main() {
showVersion := flag.Bool("version", false, "Display the version of minitor and exit")
configPath := flag.String("config", "config.yml", "Alternate configuration path (default: config.yml)")
firstRunAlerts := flag.String("first-run-alerts", "", "List of alerts to run on startup. This can help determine unhealthy alerts early on. (default \"\")")
flag.BoolVar(&slog.DebugLevel, "debug", false, "Enables debug logs (default: false)")
flag.BoolVar(&ExportMetrics, "metrics", false, "Enables prometheus metrics exporting (default: false)")
@@ -119,6 +149,14 @@ func main() {
go ServeMetrics()
}
if *firstRunAlerts != "" {
alertNames := strings.Split(*firstRunAlerts, ",")
err = sendFirstRunAlerts(&config, alertNames)
slog.OnErrPanicf(err, "Error running first run alerts")
}
// Start main loop
for {
err = checkMonitors(&config)
+61
View File
@@ -134,3 +134,64 @@ func TestCheckMonitors(t *testing.T) {
}
}
}
func TestFirstRunAlerts(t *testing.T) {
cases := []struct {
config Config
expectErr bool
firstRunAlerts []string
name string
}{
{
config: Config{},
expectErr: false,
firstRunAlerts: []string{},
name: "Empty",
},
{
config: Config{},
expectErr: true,
firstRunAlerts: []string{"missing"},
name: "Unknown",
},
{
config: Config{
Alerts: map[string]*Alert{
"good": {
Command: CommandOrShell{Command: []string{"true"}},
},
},
},
expectErr: false,
firstRunAlerts: []string{"good"},
name: "Successful alert",
},
{
config: Config{
Alerts: map[string]*Alert{
"bad": {
Name: "bad",
Command: CommandOrShell{Command: []string{"false"}},
},
},
},
expectErr: true,
firstRunAlerts: []string{"bad"},
name: "Failed alert",
},
}
for _, c := range cases {
err := c.config.Init()
if err != nil {
t.Errorf("sendFirstRunAlerts(%s): unexpected error reading config: %v", c.name, err)
}
err = sendFirstRunAlerts(&c.config, c.firstRunAlerts)
if err == nil && c.expectErr {
t.Errorf("sendFirstRunAlerts(%s): Expected error, the code did not error", c.name)
} else if err != nil && !c.expectErr {
t.Errorf("sendFirstRunAlerts(%s): Did not expect an error, but we got one anyway: %v", c.name, err)
}
}
}