From 3b2b39a3f0998bdcc5bef1c7f28bf60690224045 Mon Sep 17 00:00:00 2001 From: Joerg Lehmann Date: Fri, 7 Aug 2020 21:23:53 +0200 Subject: [PATCH] fix alerting bug --- check_mini_beieli_nodes/main.go | 147 ++++++++++++++++++++------------ 1 file changed, 92 insertions(+), 55 deletions(-) diff --git a/check_mini_beieli_nodes/main.go b/check_mini_beieli_nodes/main.go index e80c035..8107654 100644 --- a/check_mini_beieli_nodes/main.go +++ b/check_mini_beieli_nodes/main.go @@ -5,68 +5,39 @@ import ( "bytes" "fmt" "github.com/gomodule/redigo/redis" + "github.com/jordan-wright/email" "io/ioutil" "log" "net/http" - "net/smtp" "strconv" "strings" "time" ) -func sendEmailAccu(username string, alias string, deveui string, accu_percent string) { - c, err := smtp.Dial("127.0.0.1:25") - if err != nil { - log.Fatal(err) - } - defer c.Close() - // Set the sender and recipient. - c.Mail("info@mini-beieli.ch") - c.Rcpt(username) - // Send the email body. - wc, err := c.Data() - if err != nil { - log.Fatal(err) - } - defer wc.Close() - mail_message := "To: " + username + ` -Subject: mini-beieli.ch: Bitte Akku laden (` + alias + `) +func sendEmailAccu(username string, alias string, deveui string, accu_percent string, threshold int, level string) { + fmt.Printf("SEND EMAIL ACCU (%s) - %s:%s\n", level, username, deveui) + mail_message := `Lieber Benutzer von mini-beieli.ch -Lieber Benutzer von mini-beieli.ch +Der Akku von "` + alias + `" (DevEUI: ` + deveui + `) ist noch zu ` + accu_percent + ` Prozent geladen. -Der Akku von "` + alias + `" (DevEUI: ` + deveui + `) ist nur noch zu ` + accu_percent + ` Prozent geladen. - -Bitte bei nächster Gelegenheit laden. +Bitte rechtzeitig wieder laden! Bei 10%-er Ladung erscheint die letzte Warnung. Mit freundlichen Grüssen -- mini-beieli.ch` - buf := bytes.NewBufferString(mail_message) - if _, err = buf.WriteTo(wc); err != nil { - log.Fatal(err) - } + e := email.NewEmail() + e.From = "mini-beieli.ch " + e.To = []string{username} + e.Bcc = []string{"joerg.lehmann@nbit.ch"} + e.Subject = level + " - mini-beieli.ch: Akku Ladezustand (" + alias + ")" + e.Text = []byte(mail_message) + e.Send("127.0.0.1:25", nil) } -func sendEmailAbo(username string, alias string, deveui string, days_left int) { - c, err := smtp.Dial("127.0.0.1:25") - if err != nil { - log.Fatal(err) - } - defer c.Close() - // Set the sender and recipient. - c.Mail("info@mini-beieli.ch") - c.Rcpt(username) - // Send the email body. - wc, err := c.Data() - if err != nil { - log.Fatal(err) - } - defer wc.Close() - mail_message := "To: " + username + ` -Subject: mini-beieli.ch: Abo laeuft ab (` + alias + `) - -Lieber Benutzer von mini-beieli.ch +func sendEmailAbo(username string, alias string, deveui string, days_left int, level string) { + fmt.Printf("SEND EMAIL ABO (%s) - %s:%s\n", level, username, deveui) + mail_message := `Lieber Benutzer von mini-beieli.ch Das Abo von "` + alias + `" (DevEUI: ` + deveui + `) laeuft in ` + strconv.Itoa(days_left) + ` Tagen ab. @@ -76,10 +47,13 @@ Mit freundlichen Grüssen -- mini-beieli.ch` - buf := bytes.NewBufferString(mail_message) - if _, err = buf.WriteTo(wc); err != nil { - log.Fatal(err) - } + e := email.NewEmail() + e.From = "mini-beieli.ch " + e.To = []string{username} + e.Bcc = []string{"joerg.lehmann@nbit.ch"} + e.Subject = level + " - mini-beieli.ch: Abo laeuft ab (" + alias + ")" + e.Text = []byte(mail_message) + e.Send("127.0.0.1:25", nil) } var globalPool *redis.Pool @@ -232,6 +206,42 @@ func getActiveUntil(deveui string) string { return res } +func InsertAlert(prefix string, deveui string, email string, threshold int) { + conn := globalPool.Get() + defer conn.Close() + + _, err := conn.Do("SET", prefix+deveui+":"+email, threshold) + if err != nil { + logit("InsertAlert: Error inserting: " + prefix + deveui + ":" + email) + } +} + +func DeleteAlert(prefix string, deveui string, email string) { + conn := globalPool.Get() + defer conn.Close() + + exists, _ := redis.Bool(conn.Do("EXISTS", prefix+deveui+":"+email)) + + if exists { + _, err := conn.Do("DEL", prefix+deveui+":"+email) + if err != nil { + logit("DeleteAlert: Error deleting: " + prefix + deveui + ":" + email) + } + } +} + +func AlarmNotAlreadySent(prefix string, deveui string, email string, threshold int) bool { + conn := globalPool.Get() + defer conn.Close() + + exists, _ := redis.Bool(conn.Do("EXISTS", prefix+deveui+":"+email)) + if !exists { + return true + } + alarm_threshold, _ := redis.Int(conn.Do("GET", prefix+deveui+":"+email)) + return threshold != alarm_threshold +} + type OneMetric struct { Deveui string Alias string @@ -260,7 +270,7 @@ func getLastMetrics(deveui string) OneMetric { url := "http://localhost:9999/api/v2/query?org=beieliorg" data := []byte(fmt.Sprintf(`from(bucket:"beielibucket") |> range(start:-5d) - |> filter(fn: (r) => r.deveui == "%s") + |> filter(fn: (r) => r._measurement == "measurement" and r.deveui == "%s") |> filter(fn: (r) => r._field == "vp") |> last() |> yield(name: "last")`, deveui)) @@ -317,6 +327,35 @@ func getLastMetrics(deveui string) OneMetric { return res } +func CheckThreshold(d string, vp int, u2 string, last_metric OneMetric, info_threshold int, warning_threshold int, alert_threshold int) bool { + var alias string + if vp <= info_threshold { + alias = getDevAlias(d) + } + if vp <= alert_threshold { + if AlarmNotAlreadySent("alarm_sent_accu:", d, u2, alert_threshold) { + sendEmailAccu(u2, alias, d, last_metric.BatteryPercent, alert_threshold, "ALARM") + InsertAlert("alarm_sent_accu:", d , u2, alert_threshold) + } + return false + } + if vp <= warning_threshold { + if AlarmNotAlreadySent("alarm_sent_accu:", d, u2, warning_threshold) { + sendEmailAccu(u2, alias, d, last_metric.BatteryPercent, warning_threshold, "WARNING") + InsertAlert("alarm_sent_accu:", d, u2, warning_threshold) + } + return false + } + if vp <= info_threshold { + if AlarmNotAlreadySent("alarm_sent_accu:", d, u2, info_threshold) { + sendEmailAccu(u2, alias, d, last_metric.BatteryPercent, alert_threshold, "INFO") + InsertAlert("alarm_sent_accu:", d, u2, info_threshold) + } + return false + } + return true +} + func logit(log_message string) { log.Println(log_message) } @@ -339,17 +378,15 @@ func main() { if last_metric.BatteryPercent != "" { fmt.Printf("%s:%s:%s Percent:%s:%d\n", u2, d, last_metric.BatteryPercent, last_metric.ActiveUntil, last_metric.DaysUntilDeactivated) vp, _ := strconv.Atoi(last_metric.BatteryPercent) - if vp < 90 { - fmt.Printf("SEND EMAIL %s:%s:%s Percent:%s:%d\n", u2, d, last_metric.BatteryPercent, last_metric.ActiveUntil, last_metric.DaysUntilDeactivated) - alias := getDevAlias(d) - sendEmailAccu("joerg.lehmann@nbit.ch", alias, d, last_metric.BatteryPercent) + if CheckThreshold(d, vp, u2, last_metric, 50, 20, 10) { + DeleteAlert("alarm_sent_accu:", d, u2) } } // Jetzt der Alarm wegen der Abodauer if last_metric.DaysUntilDeactivated < 30 { fmt.Printf("SEND EMAIL %s:%s:%s Percent:%s:%d\n", u2, d, last_metric.BatteryPercent, last_metric.ActiveUntil, last_metric.DaysUntilDeactivated) alias := getDevAlias(d) - sendEmailAbo("joerg.lehmann@nbit.ch", alias, d, last_metric.DaysUntilDeactivated) + sendEmailAbo("joerg.lehmann@nbit.ch", alias, d, last_metric.DaysUntilDeactivated, "INFO") } } }