Alerting: Attach image URL to alerts in Webhook notifier format. (#49378)

Attaches an imageURL field to any alert messages that have a screenshot
token whose URL we can successfully read from disk.
This commit is contained in:
Joe Blubaugh
2022-05-23 16:44:19 +08:00
committed by GitHub
parent 11a908cc91
commit 26a206cce2
3 changed files with 31 additions and 3 deletions
@@ -29,6 +29,7 @@ type ExtendedAlert struct {
DashboardURL string `json:"dashboardURL"`
PanelURL string `json:"panelURL"`
ValueString string `json:"valueString"`
ImageURL string `json:"imageURL,omitempty"`
}
type ExtendedAlerts []ExtendedAlert
@@ -25,6 +25,7 @@ type WebhookNotifier struct {
MaxAlerts int
log log.Logger
ns notifications.WebhookSender
images ImageStore
tmpl *template.Template
orgID int64
}
@@ -46,7 +47,7 @@ func WebHookFactory(fc FactoryConfig) (NotificationChannel, error) {
Cfg: *fc.Config,
}
}
return NewWebHookNotifier(cfg, fc.NotificationService, fc.Template), nil
return NewWebHookNotifier(cfg, fc.NotificationService, fc.ImageStore, fc.Template), nil
}
func NewWebHookConfig(config *NotificationChannelConfig, decryptFunc GetDecryptedValueFn) (*WebhookConfig, error) {
@@ -66,7 +67,7 @@ func NewWebHookConfig(config *NotificationChannelConfig, decryptFunc GetDecrypte
// NewWebHookNotifier is the constructor for
// the WebHook notifier.
func NewWebHookNotifier(config *WebhookConfig, ns notifications.WebhookSender, t *template.Template) *WebhookNotifier {
func NewWebHookNotifier(config *WebhookConfig, ns notifications.WebhookSender, images ImageStore, t *template.Template) *WebhookNotifier {
return &WebhookNotifier{
Base: NewBase(&models.AlertNotification{
Uid: config.UID,
@@ -83,6 +84,7 @@ func NewWebHookNotifier(config *WebhookConfig, ns notifications.WebhookSender, t
MaxAlerts: config.MaxAlerts,
log: log.New("alerting.notifier.webhook"),
ns: ns,
images: images,
tmpl: t,
}
}
@@ -111,9 +113,34 @@ func (wn *WebhookNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool
return false, err
}
// Get screenshot reference tokens out of data before private annotations are cleared.
imgTokens := make([]string, 0, len(as))
for i := range as {
imgTokens = append(imgTokens, getTokenFromAnnotations(as[i].Annotations))
}
as, numTruncated := truncateAlerts(wn.MaxAlerts, as)
var tmplErr error
tmpl, data := TmplText(ctx, wn.tmpl, as, wn.log, &tmplErr)
// Augment our Alert data with ImageURLs if available.
for i := range data.Alerts {
imgURL := ""
if len(imgTokens[i]) != 0 {
timeoutCtx, cancel := context.WithTimeout(ctx, ImageStoreTimeout)
imgURL, err = wn.images.GetURL(timeoutCtx, imgTokens[i])
cancel()
if err != nil {
if !errors.Is(err, ErrImagesUnavailable) {
// Ignore errors. Don't log "ImageUnavailable", which means the storage doesn't exist.
wn.log.Warn("failed to retrieve image url from store", "error", err)
}
} else if len(imgURL) != 0 {
data.Alerts[i].ImageURL = imgURL
}
}
}
msg := &webhookMessage{
Version: "1",
ExtendedData: data,
@@ -204,7 +204,7 @@ func TestWebhookNotifier(t *testing.T) {
ctx := notify.WithGroupKey(context.Background(), "alertname")
ctx = notify.WithGroupLabels(ctx, model.LabelSet{"alertname": ""})
ctx = notify.WithReceiverName(ctx, "my_receiver")
pn := NewWebHookNotifier(cfg, webhookSender, tmpl)
pn := NewWebHookNotifier(cfg, webhookSender, &UnavailableImageStore{}, tmpl)
ok, err := pn.Notify(ctx, c.alerts...)
if c.expMsgError != nil {
require.False(t, ok)