mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(alerting): support for attached graphs in alert notifications
closes #6183
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
package notifiers
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
@@ -47,14 +46,6 @@ func (this *EmailNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
return err
|
||||
}
|
||||
|
||||
imageLink := evalContext.ImagePublicUrl
|
||||
if imageLink == "" {
|
||||
imageBytes, err := ioutil.ReadFile(evalContext.ImageOnDiskPath)
|
||||
if err == nil {
|
||||
imageLink = "data:image/jpg;base64," + base64.StdEncoding.EncodeToString(imageBytes)
|
||||
}
|
||||
}
|
||||
|
||||
cmd := &m.SendEmailCommandSync{
|
||||
SendEmailCommand: m.SendEmailCommand{
|
||||
Data: map[string]interface{}{
|
||||
@@ -64,15 +55,27 @@ func (this *EmailNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||
"StateModel": evalContext.GetStateModel(),
|
||||
"Message": evalContext.Rule.Message,
|
||||
"RuleUrl": ruleUrl,
|
||||
"ImageLink": evalContext.ImagePublicUrl,
|
||||
"ImageLink": "",
|
||||
"EmbededImage": "",
|
||||
"AlertPageUrl": setting.AppUrl + "alerting",
|
||||
"EvalMatches": evalContext.EvalMatches,
|
||||
},
|
||||
To: this.Addresses,
|
||||
Template: "alert_notification.html",
|
||||
To: this.Addresses,
|
||||
Template: "alert_notification.html",
|
||||
EmbededFiles: []string{},
|
||||
},
|
||||
}
|
||||
|
||||
if evalContext.ImagePublicUrl != "" {
|
||||
cmd.Data["ImageLink"] = evalContext.ImagePublicUrl
|
||||
} else {
|
||||
file, err := os.Stat(evalContext.ImageOnDiskPath)
|
||||
if err == nil {
|
||||
cmd.EmbededFiles = []string{evalContext.ImageOnDiskPath}
|
||||
cmd.Data["EmbededImage"] = file.Name()
|
||||
}
|
||||
}
|
||||
|
||||
err = bus.DispatchCtx(evalContext.Ctx, cmd)
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -37,9 +37,7 @@ func handleNotificationTestCommand(cmd *NotificationTestCommand) error {
|
||||
return err
|
||||
}
|
||||
|
||||
notifier.sendNotifications(createTestEvalContext(), []Notifier{notifiers})
|
||||
|
||||
return nil
|
||||
return notifier.sendNotifications(createTestEvalContext(), []Notifier{notifiers})
|
||||
}
|
||||
|
||||
func createTestEvalContext() *EvalContext {
|
||||
@@ -53,7 +51,6 @@ func createTestEvalContext() *EvalContext {
|
||||
|
||||
ctx := NewEvalContext(context.TODO(), testRule)
|
||||
ctx.ImagePublicUrl = "http://grafana.org/assets/img/blog/mixed_styles.png"
|
||||
|
||||
ctx.IsTestRun = true
|
||||
ctx.Firing = true
|
||||
ctx.Error = nil
|
||||
|
||||
@@ -6,12 +6,13 @@ import (
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
To []string
|
||||
From string
|
||||
Subject string
|
||||
Body string
|
||||
Massive bool
|
||||
Info string
|
||||
To []string
|
||||
From string
|
||||
Subject string
|
||||
Body string
|
||||
Massive bool
|
||||
Info string
|
||||
EmbededFiles []string
|
||||
}
|
||||
|
||||
// create mail content
|
||||
|
||||
@@ -14,12 +14,14 @@ import (
|
||||
"net/mail"
|
||||
"net/smtp"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/log"
|
||||
m "github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"gopkg.in/gomail.v2"
|
||||
)
|
||||
|
||||
var mailQueue chan *Message
|
||||
@@ -154,40 +156,102 @@ func sendToSmtpServer(recipients []string, msgContent []byte) error {
|
||||
}
|
||||
|
||||
func buildAndSend(msg *Message) (int, error) {
|
||||
log.Trace("Sending mails to: %s", strings.Join(msg.To, "; "))
|
||||
|
||||
// get message body
|
||||
content := msg.Content()
|
||||
|
||||
if len(msg.To) == 0 {
|
||||
return 0, fmt.Errorf("empty receive emails")
|
||||
} else if len(msg.Body) == 0 {
|
||||
return 0, fmt.Errorf("empty email body")
|
||||
m := gomail.NewMessage()
|
||||
m.SetHeader("From", msg.From)
|
||||
m.SetHeader("To", msg.To[0])
|
||||
m.SetHeader("Subject", msg.Subject)
|
||||
for _, file := range msg.EmbededFiles {
|
||||
m.Embed(file)
|
||||
}
|
||||
|
||||
if msg.Massive {
|
||||
// send mail to multiple emails one by one
|
||||
num := 0
|
||||
for _, to := range msg.To {
|
||||
body := []byte("To: " + to + "\r\n" + content)
|
||||
err := sendToSmtpServer([]string{to}, body)
|
||||
if err != nil {
|
||||
return num, err
|
||||
}
|
||||
num++
|
||||
}
|
||||
return num, nil
|
||||
} else {
|
||||
body := []byte("To: " + strings.Join(msg.To, ";") + "\r\n" + content)
|
||||
m.SetBody("text/html", msg.Body)
|
||||
|
||||
// send to multiple emails in one message
|
||||
err := sendToSmtpServer(msg.To, body)
|
||||
host, port, err := net.SplitHostPort(setting.Smtp.Host)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
iPort, err := strconv.Atoi(port)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
d := gomail.NewPlainDialer(host, iPort, setting.Smtp.User, setting.Smtp.Password)
|
||||
|
||||
tlsconfig := &tls.Config{
|
||||
InsecureSkipVerify: setting.Smtp.SkipVerify,
|
||||
ServerName: host,
|
||||
}
|
||||
|
||||
if setting.Smtp.CertFile != "" {
|
||||
cert, err := tls.LoadX509KeyPair(setting.Smtp.CertFile, setting.Smtp.KeyFile)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return 1, nil
|
||||
}
|
||||
tlsconfig.Certificates = []tls.Certificate{cert}
|
||||
}
|
||||
|
||||
d.TLSConfig = tlsconfig
|
||||
if err := d.DialAndSend(m); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
/*
|
||||
m := email.NewHTMLMessage(msg.Subject, msg.Body)
|
||||
m.From = mail.Address{Name: "From", Address: "alerting@grafana.org"}
|
||||
m.To = msg.To
|
||||
|
||||
log.Info2("Attaching file", "file", msg.Attachment)
|
||||
if err := m.Attach(msg.Attachment); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// send it
|
||||
host, _, _ := net.SplitHostPort(setting.Smtp.Host)
|
||||
|
||||
auth := smtp.PlainAuth("", setting.Smtp.User, setting.Smtp.Password, host)
|
||||
if err := email.Send(setting.Smtp.Host, auth, m); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
|
||||
log.Trace("Sending mails to: %s", strings.Join(msg.To, "; "))
|
||||
|
||||
// get message body
|
||||
content := msg.Content()
|
||||
|
||||
if len(msg.To) == 0 {
|
||||
return 0, fmt.Errorf("empty receive emails")
|
||||
} else if len(msg.Body) == 0 {
|
||||
return 0, fmt.Errorf("empty email body")
|
||||
}
|
||||
|
||||
if msg.Massive {
|
||||
// send mail to multiple emails one by one
|
||||
num := 0
|
||||
for _, to := range msg.To {
|
||||
body := []byte("To: " + to + "\r\n" + content)
|
||||
err := sendToSmtpServer([]string{to}, body)
|
||||
if err != nil {
|
||||
return num, err
|
||||
}
|
||||
num++
|
||||
}
|
||||
return num, nil
|
||||
} else {
|
||||
body := []byte("To: " + strings.Join(msg.To, ";") + "\r\n" + content)
|
||||
|
||||
// send to multiple emails in one message
|
||||
err := sendToSmtpServer(msg.To, body)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return 1, nil
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
func buildEmailMessage(cmd *m.SendEmailCommand) (*Message, error) {
|
||||
@@ -229,9 +293,10 @@ func buildEmailMessage(cmd *m.SendEmailCommand) (*Message, error) {
|
||||
}
|
||||
|
||||
return &Message{
|
||||
To: cmd.To,
|
||||
From: setting.Smtp.FromAddress,
|
||||
Subject: subjectBuffer.String(),
|
||||
Body: buffer.String(),
|
||||
To: cmd.To,
|
||||
From: setting.Smtp.FromAddress,
|
||||
Subject: subjectBuffer.String(),
|
||||
Body: buffer.String(),
|
||||
EmbededFiles: cmd.EmbededFiles,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -88,11 +88,12 @@ func subjectTemplateFunc(obj map[string]interface{}, value string) string {
|
||||
|
||||
func sendEmailCommandHandlerSync(ctx context.Context, cmd *m.SendEmailCommandSync) error {
|
||||
message, err := buildEmailMessage(&m.SendEmailCommand{
|
||||
Data: cmd.Data,
|
||||
Info: cmd.Info,
|
||||
Massive: cmd.Massive,
|
||||
Template: cmd.Template,
|
||||
To: cmd.To,
|
||||
Data: cmd.Data,
|
||||
Info: cmd.Info,
|
||||
Massive: cmd.Massive,
|
||||
Template: cmd.Template,
|
||||
To: cmd.To,
|
||||
EmbededFiles: cmd.EmbededFiles,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user