alerter/alert/client.go (62 lines of code) (raw):

package alert import ( "bytes" "context" "encoding/json" "errors" "fmt" "io" "net/http" "time" ) var ( // ErrTooManyRequests is returned when a given alert is sent too many times. ErrTooManyRequests = errors.New("too many requests") ) // Client is a client for alert notification services. Notification services implement the JSON http API // to receive alerts from the alerter service. type Client struct { httpClient *http.Client } func NewClient(timeout time.Duration) (*Client, error) { t := http.DefaultTransport.(*http.Transport).Clone() t.MaxIdleConns = 100 t.MaxConnsPerHost = 100 t.MaxIdleConnsPerHost = 100 t.ResponseHeaderTimeout = timeout t.IdleConnTimeout = time.Minute httpClient := &http.Client{ Timeout: timeout, } return &Client{ httpClient: httpClient, }, nil } func (c *Client) Create(ctx context.Context, endpoint string, alert Alert) error { b, err := json.Marshal(alert) if err != nil { return fmt.Errorf("marshal alert: %w", err) } req, err := http.NewRequestWithContext(ctx, "POST", endpoint, bytes.NewReader(b)) if err != nil { return fmt.Errorf("new request: %w", err) } req.Header.Set("Content-Type", "application/json") req.Header.Set("User-Agent", "adx-mon-alerter") resp, err := c.httpClient.Do(req) if err != nil { return fmt.Errorf("http post: %w", err) } defer func() { io.Copy(io.Discard, resp.Body) resp.Body.Close() }() if resp.StatusCode != http.StatusCreated { if resp.StatusCode == http.StatusTooManyRequests { return ErrTooManyRequests } body, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("read resp: %w", err) } return fmt.Errorf("write failed: %s:%s", resp.Status, string(body)) } return nil }