-
Notifications
You must be signed in to change notification settings - Fork 0
/
alerter.go
83 lines (65 loc) · 1.44 KB
/
alerter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/url"
"time"
"github.com/boltdb/bolt"
)
func AlertWorker(urls []string, db *bolt.DB) {
alerts := make(map[string]int)
for {
for _, u := range urls {
status, err := IsOkUrl(u, db)
if err != nil {
//TODO: add logging here
continue
}
alert_for_url := alerts[u]
if !status && alert_for_url == 0 {
fmt.Printf("Imitating alert for %s\n", u)
alerts[u] = 1
} else if status && alert_for_url > 0 {
fmt.Printf("Imitating recovery for %s\n", u)
alerts[u] = 0
}
}
time.Sleep(30 * time.Second)
}
}
// Check last m minutes for url in database
// return true if StatusCode < 400 for m time
func IsOkUrl(u string, db *bolt.DB) (bool, error) {
r, err := url.Parse(u)
if err != nil {
return false, err
}
domain := r.Host
count := 0
fail_count := 0
db.View(func(tx *bolt.Tx) error {
c := tx.Bucket([]byte(domain)).Cursor()
t := time.Now()
ts := t.Add(-2 * time.Minute)
min := []byte(ts.Format(time.RFC3339))
max := []byte(t.Format(time.RFC3339))
for k, v := c.Seek(min); k != nil && bytes.Compare(k, max) <= 0; k, v = c.Next() {
count += 1
var sr StatRecord
if err := json.Unmarshal(v, &sr); err != nil {
//TODO: add logging
c.Next()
}
if sr.Rstatus > 400 {
fail_count += 1
}
}
return nil
})
// at least two checks
if count > 2 && count-fail_count <= 1 {
return false, nil
}
return true, nil
}