Merge pull request #80 from t0mk/html_template
HTML template for notifications with FlowDock
This commit is contained in:
commit
80743177b8
|
@ -20,6 +20,7 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"html"
|
||||
htmltemplate "html/template"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
|
@ -62,6 +63,23 @@ Payload labels:
|
|||
{{range $label, $value := .Alert.Payload}}
|
||||
{{$label}} = "{{$value}}"{{end}}`))
|
||||
|
||||
var contentTmpl = htmltemplate.Must(htmltemplate.New("content").Parse(
|
||||
`<p><b><i>{{.Alert.Description}}</i></b></p>
|
||||
|
||||
<div><i>Grouping labels</i></div>
|
||||
<ul>
|
||||
{{range $label, $value := .Alert.Labels}}
|
||||
<li><b>{{$label}}:</b> {{$value}}</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
|
||||
<div><i>Payload labels</i></div>
|
||||
<ul>
|
||||
{{range $label, $value := .Alert.Payload}}
|
||||
<li><b>{{$label}}:</b> {{$value}}</li>
|
||||
{{end}}
|
||||
</ul>`))
|
||||
|
||||
var (
|
||||
notificationBufferSize = flag.Int("notification.buffer-size", 1000, "Size of buffer for pending notifications.")
|
||||
pagerdutyAPIURL = flag.String("notification.pagerduty.url", "https://events.pagerduty.com/generic/2010-04-15/create_event.json", "PagerDuty API URL.")
|
||||
|
@ -356,7 +374,10 @@ type flowdockMessage struct {
|
|||
}
|
||||
|
||||
func (n *notifier) sendFlowdockNotification(op notificationOp, config *pb.FlowdockConfig, a *Alert) error {
|
||||
flowdockMessage := newFlowdockMessage(op, config, a)
|
||||
flowdockMessage, err := newFlowdockMessage(op, config, a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
url := strings.TrimRight(*flowdockURL, "/") + "/" + config.GetApiToken()
|
||||
jsonMessage, err := json.Marshal(flowdockMessage)
|
||||
if err != nil {
|
||||
|
@ -372,7 +393,7 @@ func (n *notifier) sendFlowdockNotification(op notificationOp, config *pb.Flowdo
|
|||
return nil
|
||||
}
|
||||
|
||||
func newFlowdockMessage(op notificationOp, config *pb.FlowdockConfig, a *Alert) *flowdockMessage {
|
||||
func newFlowdockMessage(op notificationOp, config *pb.FlowdockConfig, a *Alert) (*flowdockMessage, error) {
|
||||
status := ""
|
||||
switch op {
|
||||
case notificationOpTrigger:
|
||||
|
@ -380,17 +401,22 @@ func newFlowdockMessage(op notificationOp, config *pb.FlowdockConfig, a *Alert)
|
|||
case notificationOpResolve:
|
||||
status = "resolved"
|
||||
}
|
||||
contentBuf := &bytes.Buffer{}
|
||||
err := contentTmpl.Execute(contentBuf, struct{ Alert *Alert }{Alert: a})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msg := &flowdockMessage{
|
||||
Source: "Prometheus",
|
||||
FromAddress: config.GetFromAddress(),
|
||||
Subject: html.EscapeString(a.Summary),
|
||||
Format: "html",
|
||||
Content: fmt.Sprintf("*%s %s*: %s (<%s|view>)", html.EscapeString(a.Labels["alertname"]), status, html.EscapeString(a.Summary), a.Payload["generatorURL"]),
|
||||
Content: contentBuf.String(),
|
||||
Link: a.Payload["generatorURL"],
|
||||
Tags: append(config.GetTag(), status),
|
||||
}
|
||||
return msg
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
type webhookMessage struct {
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
@ -225,3 +226,74 @@ func TestSendWebhookNotification(t *testing.T) {
|
|||
t.Errorf("incorrect webhook notification: Expected: %s Actual: %s", expected, msg)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSendFlowdockNotification(t *testing.T) {
|
||||
var body []byte
|
||||
var url string
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var err error
|
||||
url = r.URL.String()
|
||||
body, err = ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
t.Errorf("error reading flowdock notification: %s", err)
|
||||
}
|
||||
}))
|
||||
defer ts.Close()
|
||||
flowdockURL = &ts.URL
|
||||
testApiToken := "123"
|
||||
testFromAddress := "from@prometheus.io"
|
||||
testTag := []string{"T1", "T2"}
|
||||
|
||||
config := &pb.FlowdockConfig{
|
||||
ApiToken: &testApiToken,
|
||||
FromAddress: &testFromAddress,
|
||||
Tag: testTag,
|
||||
}
|
||||
alert := &Alert{
|
||||
Summary: "Testsummary",
|
||||
Description: "Test alert description, something went wrong here.",
|
||||
Labels: AlertLabelSet{
|
||||
"alertname": "TestAlert",
|
||||
},
|
||||
Payload: AlertPayload{
|
||||
"payload_label1": "payload_value1",
|
||||
"generatorURL": "http://graph",
|
||||
},
|
||||
}
|
||||
n := ¬ifier{}
|
||||
err := n.sendFlowdockNotification(notificationOpTrigger, config, alert)
|
||||
if err != nil {
|
||||
t.Errorf("error sending flowdock notification: %s", err)
|
||||
}
|
||||
|
||||
var msg flowdockMessage
|
||||
|
||||
expectedUrl := "/" + testApiToken
|
||||
if url != expectedUrl {
|
||||
t.Error("Flowdock message POSTed to wrong URL, expected %s and got %s", expectedUrl, url)
|
||||
}
|
||||
err = json.Unmarshal(body, &msg)
|
||||
if err != nil {
|
||||
t.Errorf("error unmarshalling flowdock notification: %s", err)
|
||||
}
|
||||
|
||||
contentBuf := &bytes.Buffer{}
|
||||
err = contentTmpl.Execute(contentBuf, struct{ Alert *Alert }{Alert: alert})
|
||||
if err != nil {
|
||||
t.Errorf("error expanding expected HTML content for Flowdock message: %s", err)
|
||||
}
|
||||
|
||||
expected := flowdockMessage{
|
||||
Source: "Prometheus",
|
||||
FromAddress: testFromAddress,
|
||||
Subject: html.EscapeString(alert.Summary),
|
||||
Format: "html",
|
||||
Content: contentBuf.String(),
|
||||
Link: "http://graph",
|
||||
Tags: append(testTag, "firing"),
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(msg, expected) {
|
||||
t.Errorf("incorrect Flowdock notification: Expected: %s Actual: %s", expected, msg)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue