diff --git a/alerting/slack.go b/alerting/slack.go index cd2e5428..d5908091 100644 --- a/alerting/slack.go +++ b/alerting/slack.go @@ -13,8 +13,8 @@ type requestBody struct { } // SendSlackMessage sends a message to the given Slack webhook -func SendSlackMessage(webhookUrl, msg string) error { - body, _ := json.Marshal(requestBody{Text: msg}) +func SendSlackMessage(webhookUrl, service, description string) error { + body, _ := json.Marshal(requestBody{Text: fmt.Sprintf("*[Gatus]*\n*service:* %s\n*description:* %s", service, description)}) response, err := client.GetHttpClient().Post(webhookUrl, "application/json", bytes.NewBuffer(body)) if err != nil { return err diff --git a/core/service.go b/core/service.go index 02f294ef..18b684e5 100644 --- a/core/service.go +++ b/core/service.go @@ -26,6 +26,9 @@ type Service struct { Headers map[string]string `yaml:"headers,omitempty"` Interval time.Duration `yaml:"interval,omitempty"` Conditions []*Condition `yaml:"conditions"` + Alerts []*Alert `yaml:"alerts"` + + numberOfFailuresInARow int } func (service *Service) Validate() { @@ -68,9 +71,28 @@ func (service *Service) EvaluateConditions() *Result { } } result.Timestamp = time.Now() + if result.Success { + service.numberOfFailuresInARow = 0 + } else { + service.numberOfFailuresInARow++ + } return result } +func (service *Service) GetAlertsTriggered() []Alert { + var alerts []Alert + if service.numberOfFailuresInARow == 0 { + return alerts + } + for _, alert := range service.Alerts { + if alert.Enabled && alert.Threshold == service.numberOfFailuresInARow { + alerts = append(alerts, *alert) + continue + } + } + return alerts +} + func (service *Service) getIp(result *Result) { urlObject, err := url.Parse(service.Url) if err != nil { diff --git a/watchdog/watchdog.go b/watchdog/watchdog.go index 347341c0..abb93eeb 100644 --- a/watchdog/watchdog.go +++ b/watchdog/watchdog.go @@ -2,6 +2,7 @@ package watchdog import ( "fmt" + "github.com/TwinProduction/gatus/alerting" "github.com/TwinProduction/gatus/config" "github.com/TwinProduction/gatus/core" "github.com/TwinProduction/gatus/metric" @@ -54,6 +55,21 @@ func monitor(service *core.Service) { result.Duration.Round(time.Millisecond), extra, ) + + cfg := config.Get() + if cfg.Alerting != nil { + for _, alertTriggered := range service.GetAlertsTriggered() { + if alertTriggered.Type == core.SlackAlert { + if len(cfg.Alerting.Slack) > 0 { + log.Printf("[watchdog][monitor] Sending Slack alert because alert with description=%s has been triggered", alertTriggered.Description) + alerting.SendSlackMessage(cfg.Alerting.Slack, service.Name, alertTriggered.Description) + } else { + log.Printf("[watchdog][monitor] Not sending Slack alert despite being triggered, because there is no Slack webhook configured") + } + } + } + } + log.Printf("[watchdog][monitor] Waiting for interval=%s before monitoring serviceName=%s", service.Interval, service.Name) time.Sleep(service.Interval) }