...

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

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

     1  // Copyright 2019 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 pushover
    15  
    16  import (
    17  	"context"
    18  	"fmt"
    19  	"net/http"
    20  	"net/url"
    21  	"strings"
    22  	"time"
    23  
    24  	"github.com/go-kit/log"
    25  	"github.com/go-kit/log/level"
    26  	commoncfg "github.com/prometheus/common/config"
    27  
    28  	"github.com/prometheus/alertmanager/config"
    29  	"github.com/prometheus/alertmanager/notify"
    30  	"github.com/prometheus/alertmanager/template"
    31  	"github.com/prometheus/alertmanager/types"
    32  )
    33  
    34  const (
    35  	// https://pushover.net/api#limits - 250 characters or runes.
    36  	maxTitleLenRunes = 250
    37  	// https://pushover.net/api#limits - 1024 characters or runes.
    38  	maxMessageLenRunes = 1024
    39  	// https://pushover.net/api#limits - 512 characters or runes.
    40  	maxURLLenRunes = 512
    41  )
    42  
    43  // Notifier implements a Notifier for Pushover notifications.
    44  type Notifier struct {
    45  	conf    *config.PushoverConfig
    46  	tmpl    *template.Template
    47  	logger  log.Logger
    48  	client  *http.Client
    49  	retrier *notify.Retrier
    50  	apiURL  string // for tests.
    51  }
    52  
    53  // New returns a new Pushover notifier.
    54  func New(c *config.PushoverConfig, t *template.Template, l log.Logger, httpOpts ...commoncfg.HTTPClientOption) (*Notifier, error) {
    55  	client, err := commoncfg.NewClientFromConfig(*c.HTTPConfig, "pushover", httpOpts...)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  	return &Notifier{
    60  		conf:    c,
    61  		tmpl:    t,
    62  		logger:  l,
    63  		client:  client,
    64  		retrier: &notify.Retrier{},
    65  		apiURL:  "https://api.pushover.net/1/messages.json",
    66  	}, nil
    67  }
    68  
    69  // Notify implements the Notifier interface.
    70  func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
    71  	key, ok := notify.GroupKey(ctx)
    72  	if !ok {
    73  		return false, fmt.Errorf("group key missing")
    74  	}
    75  	data := notify.GetTemplateData(ctx, n.tmpl, as, n.logger)
    76  
    77  	level.Debug(n.logger).Log("incident", key)
    78  
    79  	var (
    80  		err     error
    81  		message string
    82  	)
    83  	tmpl := notify.TmplText(n.tmpl, data, &err)
    84  	tmplHTML := notify.TmplHTML(n.tmpl, data, &err)
    85  
    86  	parameters := url.Values{}
    87  	parameters.Add("token", tmpl(string(n.conf.Token)))
    88  	parameters.Add("user", tmpl(string(n.conf.UserKey)))
    89  
    90  	title, truncated := notify.TruncateInRunes(tmpl(n.conf.Title), maxTitleLenRunes)
    91  	if truncated {
    92  		level.Warn(n.logger).Log("msg", "Truncated title", "incident", key, "max_runes", maxTitleLenRunes)
    93  	}
    94  	parameters.Add("title", title)
    95  
    96  	if n.conf.HTML {
    97  		parameters.Add("html", "1")
    98  		message = tmplHTML(n.conf.Message)
    99  	} else {
   100  		message = tmpl(n.conf.Message)
   101  	}
   102  
   103  	message, truncated = notify.TruncateInRunes(message, maxMessageLenRunes)
   104  	if truncated {
   105  		level.Warn(n.logger).Log("msg", "Truncated message", "incident", key, "max_runes", maxMessageLenRunes)
   106  	}
   107  	message = strings.TrimSpace(message)
   108  	if message == "" {
   109  		// Pushover rejects empty messages.
   110  		message = "(no details)"
   111  	}
   112  	parameters.Add("message", message)
   113  
   114  	supplementaryURL, truncated := notify.TruncateInRunes(tmpl(n.conf.URL), maxURLLenRunes)
   115  	if truncated {
   116  		level.Warn(n.logger).Log("msg", "Truncated URL", "incident", key, "max_runes", maxURLLenRunes)
   117  	}
   118  	parameters.Add("url", supplementaryURL)
   119  	parameters.Add("url_title", tmpl(n.conf.URLTitle))
   120  
   121  	parameters.Add("priority", tmpl(n.conf.Priority))
   122  	parameters.Add("retry", fmt.Sprintf("%d", int64(time.Duration(n.conf.Retry).Seconds())))
   123  	parameters.Add("expire", fmt.Sprintf("%d", int64(time.Duration(n.conf.Expire).Seconds())))
   124  	parameters.Add("sound", tmpl(n.conf.Sound))
   125  	if err != nil {
   126  		return false, err
   127  	}
   128  
   129  	u, err := url.Parse(n.apiURL)
   130  	if err != nil {
   131  		return false, err
   132  	}
   133  	u.RawQuery = parameters.Encode()
   134  	// Don't log the URL as it contains secret data (see #1825).
   135  	level.Debug(n.logger).Log("msg", "Sending message", "incident", key)
   136  	resp, err := notify.PostText(ctx, n.client, u.String(), nil)
   137  	if err != nil {
   138  		return true, notify.RedactURL(err)
   139  	}
   140  	defer notify.Drain(resp)
   141  
   142  	return n.retrier.Check(resp.StatusCode, resp.Body)
   143  }
   144  

View as plain text