diff --git a/core/notifier/notifiers.go b/core/notifier/notifiers.go index e84a6d7a..01c4475b 100644 --- a/core/notifier/notifiers.go +++ b/core/notifier/notifiers.go @@ -245,7 +245,7 @@ func Init(n Notifier) (*Notification, error) { if err == nil { notify, _ = SelectNotification(n) if notify.Delay.Seconds() == 0 { - notify.Delay = time.Duration(60 * time.Second) + notify.Delay = time.Duration(1 * time.Second) } notify.testable = isType(n, new(Tester)) notify.Form = n.Select().Form @@ -400,9 +400,6 @@ func (n *Notification) WithinLimits() (bool, error) { if n.SentLastMinute() >= n.Limits { return false, fmt.Errorf("notifier sent %v out of %v in last minute", n.SentLastMinute(), n.Limits) } - if n.Delay.Seconds() == 0 { - n.Delay = time.Duration(500 * time.Millisecond) - } if n.LastSent().Seconds() == 0 { return true, nil } diff --git a/core/services.go b/core/services.go index 234f7278..a5a74e75 100644 --- a/core/services.go +++ b/core/services.go @@ -227,14 +227,14 @@ func Dbtimestamp(group string, column string) string { // Downtime returns the amount of time of a offline service func (s *Service) Downtime() time.Duration { hits, _ := s.Hits() - fails := s.LimitedFailures() - if len(fails) == 0 { + fail := s.lastFailure() + if fail == nil { return time.Duration(0) } if len(hits) == 0 { - return time.Now().UTC().Sub(fails[len(fails)-1].CreatedAt.UTC()) + return time.Now().UTC().Sub(fail.CreatedAt.UTC()) } - since := fails[0].CreatedAt.UTC().Sub(hits[0].CreatedAt.UTC()) + since := fail.CreatedAt.UTC().Sub(fail.CreatedAt.UTC()) return since } diff --git a/handlers/services.go b/handlers/services.go index 88a4f559..801f1847 100644 --- a/handlers/services.go +++ b/handlers/services.go @@ -202,7 +202,7 @@ func servicesUpdateHandler(w http.ResponseWriter, r *http.Request) { service.Order = order service.Update(true) - service.Check(true) + go service.Check(true) executeResponse(w, r, "service.html", service, "/services") } diff --git a/notifiers/discord.go b/notifiers/discord.go index 9b1bc54f..3562a448 100644 --- a/notifiers/discord.go +++ b/notifiers/discord.go @@ -83,6 +83,7 @@ func (u *discord) OnFailure(s *types.Service, f *types.Failure) { // OnSuccess will trigger successful service func (u *discord) OnSuccess(s *types.Service) { if !u.Online { + u.ResetQueue() msg := fmt.Sprintf(`{"content": "Your service '%v' is back online!"}`, s.Name) u.AddQueue(msg) } diff --git a/notifiers/discord_test.go b/notifiers/discord_test.go index 5fe5dfb7..05273002 100644 --- a/notifiers/discord_test.go +++ b/notifiers/discord_test.go @@ -66,7 +66,7 @@ func TestDiscordNotifier(t *testing.T) { t.Run("discord OnFailure", func(t *testing.T) { discorder.OnFailure(TestService, TestFailure) - assert.Len(t, discorder.Queue, 1) + assert.Equal(t, 1, len(discorder.Queue)) }) t.Run("discord Check Offline", func(t *testing.T) { @@ -75,7 +75,7 @@ func TestDiscordNotifier(t *testing.T) { t.Run("discord OnSuccess", func(t *testing.T) { discorder.OnSuccess(TestService) - assert.Len(t, discorder.Queue, 2) + assert.Equal(t, 1, len(discorder.Queue)) }) t.Run("discord Check Back Online", func(t *testing.T) { @@ -84,7 +84,7 @@ func TestDiscordNotifier(t *testing.T) { t.Run("discord OnSuccess Again", func(t *testing.T) { discorder.OnSuccess(TestService) - assert.Len(t, discorder.Queue, 2) + assert.Equal(t, 1, len(discorder.Queue)) }) t.Run("discord Send", func(t *testing.T) { diff --git a/notifiers/email.go b/notifiers/email.go index 72df51d9..7424aa82 100644 --- a/notifiers/email.go +++ b/notifiers/email.go @@ -196,6 +196,7 @@ func (u *email) OnFailure(s *types.Service, f *types.Failure) { // OnSuccess will trigger successful service func (u *email) OnSuccess(s *types.Service) { if !u.Online { + u.ResetQueue() email := &emailOutgoing{ To: u.Var2, Subject: fmt.Sprintf("Service %v is Back Online", s.Name), diff --git a/notifiers/email_test.go b/notifiers/email_test.go index 9aff0bbc..38cc738c 100644 --- a/notifiers/email_test.go +++ b/notifiers/email_test.go @@ -102,7 +102,7 @@ func TestEmailNotifier(t *testing.T) { t.Run("email OnFailure", func(t *testing.T) { emailer.OnFailure(TestService, TestFailure) - assert.Len(t, emailer.Queue, 1) + assert.Equal(t, 1, len(emailer.Queue)) }) t.Run("email Check Offline", func(t *testing.T) { @@ -111,7 +111,7 @@ func TestEmailNotifier(t *testing.T) { t.Run("email OnSuccess", func(t *testing.T) { emailer.OnSuccess(TestService) - assert.Len(t, emailer.Queue, 2) + assert.Equal(t, 1, len(emailer.Queue)) }) t.Run("email Check Back Online", func(t *testing.T) { @@ -120,7 +120,7 @@ func TestEmailNotifier(t *testing.T) { t.Run("email OnSuccess Again", func(t *testing.T) { emailer.OnSuccess(TestService) - assert.Len(t, emailer.Queue, 2) + assert.Equal(t, 1, len(emailer.Queue)) }) t.Run("email Send", func(t *testing.T) { diff --git a/notifiers/line_notify.go b/notifiers/line_notify.go index 36f47a6a..46a2f46c 100644 --- a/notifiers/line_notify.go +++ b/notifiers/line_notify.go @@ -90,6 +90,7 @@ func (u *lineNotifier) OnFailure(s *types.Service, f *types.Failure) { // OnSuccess will trigger successful service func (u *lineNotifier) OnSuccess(s *types.Service) { if !u.Online { + u.ResetQueue() msg := fmt.Sprintf("Your service '%v' is back online!", s.Name) u.AddQueue(msg) } diff --git a/notifiers/notifiers_test.go b/notifiers/notifiers_test.go index e274d0c2..7934e66e 100644 --- a/notifiers/notifiers_test.go +++ b/notifiers/notifiers_test.go @@ -36,12 +36,12 @@ var TestService = &types.Service{ Name: "Interpol - All The Rage Back Home", Domain: "https://www.youtube.com/watch?v=-u6DvRyyKGU", ExpectedStatus: 200, + Expected: "test example", Interval: 30, Type: "http", Method: "GET", Timeout: 20, LastStatusCode: 404, - Expected: "test example", LastResponse: "this is an example response", CreatedAt: time.Now().Add(-24 * time.Hour), } diff --git a/notifiers/slack.go b/notifiers/slack.go index 35b1a6e3..0ab5a81b 100644 --- a/notifiers/slack.go +++ b/notifiers/slack.go @@ -30,7 +30,7 @@ import ( const ( slackMethod = "slack" failingTemplate = `{ "attachments": [ { "fallback": "Service {{.Service.Name}} - is currently failing", "text": "Your Statup service <{{.Service.Domain}}|{{.Service.Name}}> has just received a Failure notification based on your expected results. {{.Service.Name}} responded with a HTTP Status code of {{.Service.LastStatusCode}}.", "fields": [ { "title": "Expected", "value": "{{.Service.Expected}}", "short": true }, { "title": "Status Code", "value": "{{.Service.LastStatusCode}}", "short": true } ], "color": "#FF0000", "thumb_url": "https://statup.io", "footer": "Statup", "footer_icon": "https://img.cjx.io/statuplogo32.png" } ] }` - successTemplate = `{ "attachments": [ { "fallback": "Service {{.Service.Name}} - is now back online", "text": "Your Statup service <{{.Service.Domain}}|{{.Service.Name}}> is now back online and meets your expected responses.", "fields": [ { "title": "Issue", "value": "Awesome Project", "short": true }, { "title": "Status Code", "value": "{{.Service.LastStatusCode}}", "short": true } ], "color": "#00FF00", "thumb_url": "https://statup.io", "footer": "Statup", "footer_icon": "https://img.cjx.io/statuplogo32.png" } ] }` + successTemplate = `{ "attachments": [ { "fallback": "Service {{.Service.Name}} - is now back online", "text": "Your Statup service <{{.Service.Domain}}|{{.Service.Name}}> is now back online and meets your expected responses.", "color": "#00FF00", "thumb_url": "https://statup.io", "footer": "Statup", "footer_icon": "https://img.cjx.io/statuplogo32.png" } ] }` slackText = `{"text":"{{.}}"}` ) @@ -127,6 +127,7 @@ func (u *slack) OnFailure(s *types.Service, f *types.Failure) { // OnSuccess will trigger successful service func (u *slack) OnSuccess(s *types.Service) { if !u.Online { + u.ResetQueue() message := slackMessage{ Service: s, Template: successTemplate, diff --git a/notifiers/slack_test.go b/notifiers/slack_test.go index f2fa9bee..80393939 100644 --- a/notifiers/slack_test.go +++ b/notifiers/slack_test.go @@ -46,6 +46,7 @@ func TestSlackNotifier(t *testing.T) { t.Run("Load slack", func(t *testing.T) { slacker.Host = SLACK_URL slacker.Delay = time.Duration(100 * time.Millisecond) + slacker.Limits = 3 err := notifier.AddNotifier(slacker) assert.Nil(t, err) assert.Equal(t, "Hunter Long", slacker.Author) @@ -60,11 +61,11 @@ func TestSlackNotifier(t *testing.T) { assert.True(t, slacker.CanTest()) }) - t.Run("slack parse message", func(t *testing.T) { - err := parseSlackMessage(slackText, "this is a test!") - assert.Nil(t, err) - assert.Equal(t, 1, len(slacker.Queue)) - }) + //t.Run("slack parse message", func(t *testing.T) { + // err := parseSlackMessage(slackText, "this is a test!") + // assert.Nil(t, err) + // assert.Equal(t, 1, len(slacker.Queue)) + //}) t.Run("slack Within Limits", func(t *testing.T) { ok, err := slacker.WithinLimits() @@ -74,7 +75,14 @@ func TestSlackNotifier(t *testing.T) { t.Run("slack OnFailure", func(t *testing.T) { slacker.OnFailure(TestService, TestFailure) - assert.Len(t, slacker.Queue, 2) + assert.Equal(t, 1, len(slacker.Queue)) + }) + + t.Run("slack OnFailure multiple times", func(t *testing.T) { + for i := 0; i <= 50; i++ { + slacker.OnFailure(TestService, TestFailure) + } + assert.Equal(t, 52, len(slacker.Queue)) }) t.Run("slack Check Offline", func(t *testing.T) { @@ -83,22 +91,33 @@ func TestSlackNotifier(t *testing.T) { t.Run("slack OnSuccess", func(t *testing.T) { slacker.OnSuccess(TestService) - assert.Len(t, slacker.Queue, 3) + assert.Equal(t, 1, len(slacker.Queue)) }) - t.Run("slack Check Back Online", func(t *testing.T) { + t.Run("slack Queue after being online", func(t *testing.T) { assert.True(t, slacker.Online) + assert.Equal(t, 1, len(slacker.Queue)) }) t.Run("slack OnSuccess Again", func(t *testing.T) { + assert.True(t, slacker.Online) slacker.OnSuccess(TestService) - assert.Len(t, slacker.Queue, 3) + assert.Equal(t, 1, len(slacker.Queue)) + go notifier.Queue(slacker) + time.Sleep(5 * time.Second) + assert.Equal(t, 0, len(slacker.Queue)) + }) + + t.Run("slack Within Limits again", func(t *testing.T) { + ok, err := slacker.WithinLimits() + assert.Nil(t, err) + assert.True(t, ok) }) t.Run("slack Send", func(t *testing.T) { err := slacker.Send(slackTestMessage) assert.Nil(t, err) - assert.Len(t, slacker.Queue, 3) + assert.Equal(t, 0, len(slacker.Queue)) }) t.Run("slack Test", func(t *testing.T) { @@ -108,7 +127,7 @@ func TestSlackNotifier(t *testing.T) { t.Run("slack Queue", func(t *testing.T) { go notifier.Queue(slacker) - time.Sleep(4 * time.Second) + time.Sleep(5 * time.Second) assert.Equal(t, SLACK_URL, slacker.Host) assert.Equal(t, 0, len(slacker.Queue)) }) diff --git a/notifiers/twilio.go b/notifiers/twilio.go index d00ce496..6bc98ef5 100644 --- a/notifiers/twilio.go +++ b/notifiers/twilio.go @@ -122,6 +122,7 @@ func (u *twilio) OnFailure(s *types.Service, f *types.Failure) { // OnSuccess will trigger successful service func (u *twilio) OnSuccess(s *types.Service) { if !u.Online { + u.ResetQueue() msg := fmt.Sprintf("Your service '%v' is back online!", s.Name) u.AddQueue(msg) } diff --git a/notifiers/webhook.go b/notifiers/webhook.go index 429fca2d..da75c2c6 100644 --- a/notifiers/webhook.go +++ b/notifiers/webhook.go @@ -177,6 +177,7 @@ func (w *webhooker) OnFailure(s *types.Service, f *types.Failure) { // OnSuccess will trigger successful service func (w *webhooker) OnSuccess(s *types.Service) { if !w.Online { + w.ResetQueue() msg := replaceBodyText(w.Var2, s, nil) webhook.AddQueue(msg) }