commit edced6e71a9ca83fd275e2b6dd0af64cf146cd5f
parent b3d1e9fdf8bf8bd2d4dc3650a41a4e8c7c53f962
Author: Thomas Maier <thomas.maier@leomedia.eu>
Date: Mon, 25 Sep 2017 17:58:44 +0200
WiP
Diffstat:
A | grafana.go | | | 50 | ++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | main.go | | | 50 | ++++++++++++++++++++++++++++++++++++++++---------- |
2 files changed, 90 insertions(+), 10 deletions(-)
diff --git a/grafana.go b/grafana.go
@@ -0,0 +1,50 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+)
+
+/*
+{
+ "title": "My alert",
+ "ruleId": 1,
+ "ruleName": "Load peaking!",
+ "ruleUrl": "http://url.to.grafana/db/dashboard/my_dashboard?panelId=2",
+ "state": "alerting",
+ "imageUrl": "http://s3.image.url",
+ "message": "Load is peaking. Make sure the traffic is real and spin up more webfronts",
+ "evalMatches": [
+ {
+ "metric": "requests",
+ "tags": {},
+ "value": 122
+ }
+ ]
+}
+*/
+
+type GrafanaAlert struct {
+ Title string `json:"title"`
+ RuleName string `json:"ruleName"`
+ RuleUrl string `json:"ruleUrl"`
+ State string `json:"state"`
+ Message string `json:"message"`
+}
+
+func makeGrafanaHandler(messages chan<- string) func(http.ResponseWriter, *http.Request) {
+ return func(w http.ResponseWriter, r *http.Request) {
+ body, err := ioutil.ReadAll(r.Body)
+ fmt.Printf("%v", string(body))
+ if err == nil {
+ var alert GrafanaAlert
+ err = json.Unmarshal(body, &alert)
+ if err == nil {
+ message := alert.State + ": " + alert.Title + "/" + alert.Message + "(" + alert.RuleUrl + ")"
+ messages <- message
+ }
+ }
+ }
+}
diff --git a/main.go b/main.go
@@ -2,19 +2,24 @@ package main
import (
"log"
+ "net/http"
"os"
+ "strings"
"time"
"github.com/emgee/go-xmpp/src/xmpp"
)
const (
- envXMPPID = "XMPP_ID"
- envXMPPPASS = "XMPP_PASS"
- errWrongArgs = "XMPP_ID or XMPP_PASS not set"
- xmppBotAnswer = "im a dumb bot"
- xmppConnErr = "failed to connect "
- xmppFailedPause = 30
+ envXMPPID = "XMPP_ID"
+ envXMPPPASS = "XMPP_PASS"
+ envXMPPReceivers = "XMPP_RECEIVERS"
+ errWrongArgs = "XMPP_ID, XMPP_PASS or XMPP_RECEIVERS not set"
+ xmppBotAnswer = "im a dumb bot"
+ xmppConnErr = "failed to connect "
+ xmppOfflineErr = "not connected to XMPP server, dropped message"
+ xmppFailedPause = 30
+ webHookAddr = ":4321"
)
// starts xmpp session and returns the xmpp client
@@ -75,9 +80,10 @@ func main() {
// get xmpp credentials from ENV
xi := os.Getenv(envXMPPID)
xp := os.Getenv(envXMPPPASS)
+ xr := os.Getenv(envXMPPReceivers)
- // check if xmpp credentials are supplied
- if len(xi) < 1 || len(xp) < 1 {
+ // check if xmpp credentials and receiver list are supplied
+ if len(xi) < 1 || len(xp) < 1 || len(xr) < 1 {
log.Fatal(errWrongArgs)
}
@@ -93,12 +99,36 @@ func main() {
log.Print(xmppConnErr, err)
time.Sleep(time.Second * time.Duration(xmppFailedPause))
} else {
- // send initial presence and dispatch channels to handler
+ // send initial presence and dispatch channels to handler for incoming messages
xc.Out <- xmpp.Presence{}
handleXMPPStanza(xc.In, xc.Out)
}
}
}()
- select {}
+ // create channel for alerts (Webhook -> XMPP)
+ alertChan := make(chan string)
+
+ // create handler for outgoing XMPP messages
+ go func() {
+ for message := range alertChan {
+ for _, r := range strings.Split(xr, ",") {
+ if xc != nil {
+ xc.Out <- xmpp.Message{
+ To: r,
+ Body: xmppBodyCreate(message),
+ }
+ } else {
+ log.Print(xmppOfflineErr)
+ }
+ }
+ }
+ }()
+
+ // initialize HTTP handlers with chan for alerts
+ grafanaHandler := makeGrafanaHandler(alertChan)
+ http.HandleFunc("/grafana", grafanaHandler)
+
+ // listen for requests
+ http.ListenAndServe(webHookAddr, nil)
}