webhook.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package notifications
  2. import (
  3. "bytes"
  4. "context"
  5. "fmt"
  6. "io/ioutil"
  7. "net/http"
  8. "golang.org/x/net/context/ctxhttp"
  9. "github.com/grafana/grafana/pkg/log"
  10. "github.com/grafana/grafana/pkg/util"
  11. )
  12. type Webhook struct {
  13. Url string
  14. User string
  15. Password string
  16. Body string
  17. HttpMethod string
  18. HttpHeader map[string]string
  19. }
  20. var (
  21. webhookQueue chan *Webhook
  22. webhookLog log.Logger
  23. )
  24. func initWebhookQueue() {
  25. webhookLog = log.New("notifications.webhook")
  26. webhookQueue = make(chan *Webhook, 10)
  27. go processWebhookQueue()
  28. }
  29. func processWebhookQueue() {
  30. for {
  31. select {
  32. case webhook := <-webhookQueue:
  33. err := sendWebRequestSync(context.TODO(), webhook)
  34. if err != nil {
  35. webhookLog.Error("Failed to send webrequest ", "error", err)
  36. }
  37. }
  38. }
  39. }
  40. func sendWebRequestSync(ctx context.Context, webhook *Webhook) error {
  41. webhookLog.Debug("Sending webhook", "url", webhook.Url, "http method", webhook.HttpMethod)
  42. if webhook.HttpMethod == "" {
  43. webhook.HttpMethod = http.MethodPost
  44. }
  45. request, err := http.NewRequest(webhook.HttpMethod, webhook.Url, bytes.NewReader([]byte(webhook.Body)))
  46. if err != nil {
  47. return err
  48. }
  49. request.Header.Add("Content-Type", "application/json")
  50. request.Header.Add("User-Agent", "Grafana")
  51. if webhook.User != "" && webhook.Password != "" {
  52. request.Header.Add("Authorization", util.GetBasicAuthHeader(webhook.User, webhook.Password))
  53. }
  54. for k, v := range webhook.HttpHeader {
  55. request.Header.Set(k, v)
  56. }
  57. resp, err := ctxhttp.Do(ctx, http.DefaultClient, request)
  58. if err != nil {
  59. return err
  60. }
  61. if resp.StatusCode/100 == 2 {
  62. return nil
  63. }
  64. defer resp.Body.Close()
  65. body, err := ioutil.ReadAll(resp.Body)
  66. if err != nil {
  67. return err
  68. }
  69. webhookLog.Debug("Webhook failed", "statuscode", resp.Status, "body", string(body))
  70. return fmt.Errorf("Webhook response status %v", resp.Status)
  71. }
  72. var addToWebhookQueue = func(msg *Webhook) {
  73. webhookQueue <- msg
  74. }