mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Add support for images in Kafka alerts (#50758)
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
"github.com/grafana/grafana/pkg/services/notifications"
|
||||
)
|
||||
|
||||
@@ -23,6 +24,7 @@ type KafkaNotifier struct {
|
||||
Endpoint string
|
||||
Topic string
|
||||
log log.Logger
|
||||
images ImageStore
|
||||
ns notifications.WebhookSender
|
||||
tmpl *template.Template
|
||||
}
|
||||
@@ -41,7 +43,7 @@ func KafkaFactory(fc FactoryConfig) (NotificationChannel, error) {
|
||||
Cfg: *fc.Config,
|
||||
}
|
||||
}
|
||||
return NewKafkaNotifier(cfg, fc.NotificationService, fc.Template), nil
|
||||
return NewKafkaNotifier(cfg, fc.ImageStore, fc.NotificationService, fc.Template), nil
|
||||
}
|
||||
|
||||
func NewKafkaConfig(config *NotificationChannelConfig) (*KafkaConfig, error) {
|
||||
@@ -61,7 +63,7 @@ func NewKafkaConfig(config *NotificationChannelConfig) (*KafkaConfig, error) {
|
||||
}
|
||||
|
||||
// NewKafkaNotifier is the constructor function for the Kafka notifier.
|
||||
func NewKafkaNotifier(config *KafkaConfig, ns notifications.WebhookSender, t *template.Template) *KafkaNotifier {
|
||||
func NewKafkaNotifier(config *KafkaConfig, images ImageStore, ns notifications.WebhookSender, t *template.Template) *KafkaNotifier {
|
||||
return &KafkaNotifier{
|
||||
Base: NewBase(&models.AlertNotification{
|
||||
Uid: config.UID,
|
||||
@@ -73,6 +75,7 @@ func NewKafkaNotifier(config *KafkaConfig, ns notifications.WebhookSender, t *te
|
||||
Endpoint: config.Endpoint,
|
||||
Topic: config.Topic,
|
||||
log: log.New("alerting.notifier.kafka"),
|
||||
images: images,
|
||||
ns: ns,
|
||||
tmpl: t,
|
||||
}
|
||||
@@ -102,6 +105,21 @@ func (kn *KafkaNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
|
||||
ruleURL := joinUrlPath(kn.tmpl.ExternalURL.String(), "/alerting/list", kn.log)
|
||||
bodyJSON.Set("client_url", ruleURL)
|
||||
|
||||
var contexts []interface{}
|
||||
_ = withStoredImages(ctx, kn.log, kn.images,
|
||||
func(index int, image *ngmodels.Image) error {
|
||||
if image != nil && image.URL != "" {
|
||||
imageJSON := simplejson.New()
|
||||
imageJSON.Set("type", "image")
|
||||
imageJSON.Set("src", image.URL)
|
||||
contexts = append(contexts, imageJSON)
|
||||
}
|
||||
return nil
|
||||
}, as...)
|
||||
if len(contexts) > 0 {
|
||||
bodyJSON.Set("contexts", contexts)
|
||||
}
|
||||
|
||||
groupKey, err := notify.ExtractGroupKey(ctx)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
||||
@@ -16,6 +16,8 @@ import (
|
||||
func TestKafkaNotifier(t *testing.T) {
|
||||
tmpl := templateForTests(t)
|
||||
|
||||
images := newFakeImageStore(2)
|
||||
|
||||
externalURL, err := url.Parse("http://localhost")
|
||||
require.NoError(t, err)
|
||||
tmpl.ExternalURL = externalURL
|
||||
@@ -29,7 +31,7 @@ func TestKafkaNotifier(t *testing.T) {
|
||||
expMsgError error
|
||||
}{
|
||||
{
|
||||
name: "One alert",
|
||||
name: "A single alert with image",
|
||||
settings: `{
|
||||
"kafkaRestProxy": "http://localhost",
|
||||
"kafkaTopic": "sometopic"
|
||||
@@ -38,7 +40,7 @@ func TestKafkaNotifier(t *testing.T) {
|
||||
{
|
||||
Alert: model.Alert{
|
||||
Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val1"},
|
||||
Annotations: model.LabelSet{"ann1": "annv1", "__dashboardUid__": "abcd", "__panelId__": "efgh"},
|
||||
Annotations: model.LabelSet{"ann1": "annv1", "__dashboardUid__": "abcd", "__panelId__": "efgh", "__alertScreenshotToken__": "test-image-1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -50,6 +52,7 @@ func TestKafkaNotifier(t *testing.T) {
|
||||
"alert_state": "alerting",
|
||||
"client": "Grafana",
|
||||
"client_url": "http://localhost/alerting/list",
|
||||
"contexts": [{"type": "image", "src": "https://www.example.com/test-image-1.jpg"}],
|
||||
"description": "[FIRING:1] (val1)",
|
||||
"details": "**Firing**\n\nValue: [no value]\nLabels:\n - alertname = alert1\n - lbl1 = val1\nAnnotations:\n - ann1 = annv1\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval1\nDashboard: http://localhost/d/abcd\nPanel: http://localhost/d/abcd?viewPanel=efgh\n",
|
||||
"incident_key": "6e3538104c14b583da237e9693b76debbc17f0f8058ef20492e5853096cf8733"
|
||||
@@ -59,7 +62,7 @@ func TestKafkaNotifier(t *testing.T) {
|
||||
}`,
|
||||
expMsgError: nil,
|
||||
}, {
|
||||
name: "Multiple alerts",
|
||||
name: "Multiple alerts with images",
|
||||
settings: `{
|
||||
"kafkaRestProxy": "http://localhost",
|
||||
"kafkaTopic": "sometopic"
|
||||
@@ -68,12 +71,12 @@ func TestKafkaNotifier(t *testing.T) {
|
||||
{
|
||||
Alert: model.Alert{
|
||||
Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val1"},
|
||||
Annotations: model.LabelSet{"ann1": "annv1"},
|
||||
Annotations: model.LabelSet{"ann1": "annv1", "__alertScreenshotToken__": "test-image-1"},
|
||||
},
|
||||
}, {
|
||||
Alert: model.Alert{
|
||||
Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val2"},
|
||||
Annotations: model.LabelSet{"ann1": "annv2"},
|
||||
Annotations: model.LabelSet{"ann1": "annv2", "__alertScreenshotToken__": "test-image-2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -85,6 +88,7 @@ func TestKafkaNotifier(t *testing.T) {
|
||||
"alert_state": "alerting",
|
||||
"client": "Grafana",
|
||||
"client_url": "http://localhost/alerting/list",
|
||||
"contexts": [{"type": "image", "src": "https://www.example.com/test-image-1.jpg"}, {"type": "image", "src": "https://www.example.com/test-image-2.jpg"}],
|
||||
"description": "[FIRING:2] ",
|
||||
"details": "**Firing**\n\nValue: [no value]\nLabels:\n - alertname = alert1\n - lbl1 = val1\nAnnotations:\n - ann1 = annv1\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval1\n\nValue: [no value]\nLabels:\n - alertname = alert1\n - lbl1 = val2\nAnnotations:\n - ann1 = annv2\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval2\n",
|
||||
"incident_key": "6e3538104c14b583da237e9693b76debbc17f0f8058ef20492e5853096cf8733"
|
||||
@@ -127,7 +131,7 @@ func TestKafkaNotifier(t *testing.T) {
|
||||
ctx := notify.WithGroupKey(context.Background(), "alertname")
|
||||
ctx = notify.WithGroupLabels(ctx, model.LabelSet{"alertname": ""})
|
||||
|
||||
pn := NewKafkaNotifier(cfg, webhookSender, tmpl)
|
||||
pn := NewKafkaNotifier(cfg, images, webhookSender, tmpl)
|
||||
ok, err := pn.Notify(ctx, c.alerts...)
|
||||
if c.expMsgError != nil {
|
||||
require.False(t, ok)
|
||||
|
||||
Reference in New Issue
Block a user