diff --git a/cmd/cmd_root.go b/cmd/cmd_root.go index 1460b14..9f82a01 100644 --- a/cmd/cmd_root.go +++ b/cmd/cmd_root.go @@ -116,8 +116,8 @@ var cfgFile string func init() { var ( - shouldNotify bool debug bool + shouldNotify string logFormat string api string ) @@ -128,8 +128,9 @@ func init() { rootCmd.PersistentFlags().StringVarP(&api, "api", "a", "https://api.opensensemap.org", "openSenseMap API to query against") rootCmd.PersistentFlags().StringVarP(&logFormat, "logformat", "l", "plain", "log format, can be plain or json") rootCmd.PersistentFlags().BoolVarP(&debug, "debug", "d", false, "enable verbose logging") - rootCmd.PersistentFlags().BoolVarP(&shouldNotify, "notify", "n", false, `if set, will send out notifications, + rootCmd.PersistentFlags().StringVarP(&shouldNotify, "notify", "n", "", `if set, will send out notifications for the specified type of check result, Otherwise results are printed to stdout only. +Allowed values are "all", "error", "ok". You might want to run 'osem_notify debug notifications' first to verify everything works. Notifications for failing checks are sent only once, diff --git a/cmd/shared.go b/cmd/shared.go index a5b9505..b017330 100644 --- a/cmd/shared.go +++ b/cmd/shared.go @@ -3,6 +3,7 @@ package cmd import ( "fmt" "regexp" + "strings" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -49,8 +50,21 @@ func checkAndNotify(boxIds []string) error { results.Log() - if viper.GetBool("notify") { - return results.SendNotifications() + notify := strings.ToLower(viper.GetString("notify")) + if notify != "" { + types := []string{} + switch notify { + case "all": + types = []string{core.CheckErr, core.CheckOk} + case "error", "err": + types = []string{core.CheckErr} + case "ok": + types = []string{core.CheckOk} + default: + return fmt.Errorf("invalid value %s for \"notify\"", notify) + } + + return results.SendNotifications(types) } return nil } diff --git a/core/checkrunner.go b/core/checkrunner.go index f6db352..9f78d90 100644 --- a/core/checkrunner.go +++ b/core/checkrunner.go @@ -10,11 +10,11 @@ import ( type BoxCheckResults map[*Box][]CheckResult -func (results BoxCheckResults) Size(status string) int { +func (results BoxCheckResults) Size(statusToCheck []string) int { size := 0 for _, boxResults := range results { for _, result := range boxResults { - if status == result.Status || status == "" { + if result.HasStatus(statusToCheck) { size++ } } diff --git a/core/healthchecks.go b/core/healthchecks.go index 94839e5..36792cb 100644 --- a/core/healthchecks.go +++ b/core/healthchecks.go @@ -37,6 +37,15 @@ type CheckResult struct { Threshold string } +func (r CheckResult) HasStatus(statusToCheck []string) bool { + for _, status := range statusToCheck { + if status == r.Status { + return true + } + } + return false +} + func (r CheckResult) EventID() string { s := fmt.Sprintf("%s%s%s", r.Event, r.Target, r.Threshold) hasher := sha256.New() diff --git a/core/notifiers.go b/core/notifiers.go index 4f157d2..127bc27 100644 --- a/core/notifiers.go +++ b/core/notifiers.go @@ -39,25 +39,23 @@ func (box Box) GetNotifier() (AbstractNotifier, error) { return notifier.New(box.NotifyConf.Notifications.Options) } -func (results BoxCheckResults) SendNotifications() error { - // TODO: expose flags to not use cache, and to notify for checks turned CheckOk as well - +func (results BoxCheckResults) SendNotifications(notifyTypes []string) error { + // TODO: expose flag to not use cache results = results.filterChangedFromCache() - nErr := results.Size(CheckErr) - if nErr == 0 { + toCheck := results.Size(notifyTypes) + if toCheck == 0 { log.Info("No notifications due.") } else { - log.Infof("Notifying for %v checks turned bad in total...", nErr) + log.Infof("Notifying for %v checks changing state to %v...", toCheck, notifyTypes) } - log.Debugf("%v checks turned OK!", results.Size(CheckOk)) errs := []string{} for box, resultsBox := range results { // only submit results which are errors resultsDue := []CheckResult{} for _, result := range resultsBox { - if result.Status != CheckOk { + if result.HasStatus(notifyTypes) { resultsDue = append(resultsDue, result) } } @@ -91,7 +89,7 @@ func (results BoxCheckResults) SendNotifications() error { } } - // update cache (also with CheckOk results to reset status) + // update cache (with /all/ changed results to reset status) notifyLog.Debug("updating cache") cacheError := updateCache(box, resultsBox) if cacheError != nil { @@ -100,7 +98,7 @@ func (results BoxCheckResults) SendNotifications() error { } if len(resultsDue) != 0 { - notifyLog.Infof("Sent notification for %s via %s with %v new issues", box.Name, transport, len(resultsDue)) + notifyLog.Infof("Sent notification for %s via %s with %v updated issues", box.Name, transport, len(resultsDue)) } }