...

Source file src/github.com/prometheus/alertmanager/notify/discord/discord.go

Documentation: github.com/prometheus/alertmanager/notify/discord

     1  // Copyright 2021 Prometheus Team
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package discord
    15  
    16  import (
    17  	"bytes"
    18  	"context"
    19  	"encoding/json"
    20  	"net/http"
    21  
    22  	"github.com/go-kit/log"
    23  	"github.com/go-kit/log/level"
    24  	commoncfg "github.com/prometheus/common/config"
    25  	"github.com/prometheus/common/model"
    26  
    27  	"github.com/prometheus/alertmanager/config"
    28  	"github.com/prometheus/alertmanager/notify"
    29  	"github.com/prometheus/alertmanager/template"
    30  	"github.com/prometheus/alertmanager/types"
    31  )
    32  
    33  const (
    34  	colorRed   = 0x992D22
    35  	colorGreen = 0x2ECC71
    36  	colorGrey  = 0x95A5A6
    37  )
    38  
    39  // Notifier implements a Notifier for Discord notifications.
    40  type Notifier struct {
    41  	conf       *config.DiscordConfig
    42  	tmpl       *template.Template
    43  	logger     log.Logger
    44  	client     *http.Client
    45  	retrier    *notify.Retrier
    46  	webhookURL *config.SecretURL
    47  }
    48  
    49  // New returns a new Discord notifier.
    50  func New(c *config.DiscordConfig, t *template.Template, l log.Logger, httpOpts ...commoncfg.HTTPClientOption) (*Notifier, error) {
    51  	client, err := commoncfg.NewClientFromConfig(*c.HTTPConfig, "discord", httpOpts...)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  	n := &Notifier{
    56  		conf:       c,
    57  		tmpl:       t,
    58  		logger:     l,
    59  		client:     client,
    60  		retrier:    &notify.Retrier{},
    61  		webhookURL: c.WebhookURL,
    62  	}
    63  	return n, nil
    64  }
    65  
    66  type webhook struct {
    67  	Content string         `json:"content"`
    68  	Embeds  []webhookEmbed `json:"embeds"`
    69  }
    70  
    71  type webhookEmbed struct {
    72  	Title       string `json:"title"`
    73  	Description string `json:"description"`
    74  	Color       int    `json:"color"`
    75  }
    76  
    77  // Notify implements the Notifier interface.
    78  func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
    79  	key, err := notify.ExtractGroupKey(ctx)
    80  	if err != nil {
    81  		return false, err
    82  	}
    83  
    84  	level.Debug(n.logger).Log("incident", key)
    85  
    86  	alerts := types.Alerts(as...)
    87  	data := notify.GetTemplateData(ctx, n.tmpl, as, n.logger)
    88  	tmpl := notify.TmplText(n.tmpl, data, &err)
    89  	if err != nil {
    90  		return false, err
    91  	}
    92  
    93  	title := tmpl(n.conf.Title)
    94  	if err != nil {
    95  		return false, err
    96  	}
    97  	description := tmpl(n.conf.Message)
    98  	if err != nil {
    99  		return false, err
   100  	}
   101  
   102  	color := colorGrey
   103  	if alerts.Status() == model.AlertFiring {
   104  		color = colorRed
   105  	}
   106  	if alerts.Status() == model.AlertResolved {
   107  		color = colorGreen
   108  	}
   109  
   110  	w := webhook{
   111  		Embeds: []webhookEmbed{{
   112  			Title:       title,
   113  			Description: description,
   114  			Color:       color,
   115  		}},
   116  	}
   117  
   118  	var payload bytes.Buffer
   119  	if err = json.NewEncoder(&payload).Encode(w); err != nil {
   120  		return false, err
   121  	}
   122  
   123  	resp, err := notify.PostJSON(ctx, n.client, n.webhookURL.String(), &payload)
   124  	if err != nil {
   125  		return true, notify.RedactURL(err)
   126  	}
   127  
   128  	shouldRetry, err := n.retrier.Check(resp.StatusCode, resp.Body)
   129  	if err != nil {
   130  		return shouldRetry, err
   131  	}
   132  	return false, nil
   133  }
   134  

View as plain text