webhook.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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. }
  19. var (
  20. webhookQueue chan *Webhook
  21. webhookLog log.Logger
  22. )
  23. func initWebhookQueue() {
  24. webhookLog = log.New("notifications.webhook")
  25. webhookQueue = make(chan *Webhook, 10)
  26. go processWebhookQueue()
  27. }
  28. func processWebhookQueue() {
  29. for {
  30. select {
  31. case webhook := <-webhookQueue:
  32. err := sendWebRequestSync(context.TODO(), webhook)
  33. if err != nil {
  34. webhookLog.Error("Failed to send webrequest ", "error", err)
  35. }
  36. }
  37. }
  38. }
  39. func sendWebRequestSync(ctx context.Context, webhook *Webhook) error {
  40. webhookLog.Debug("Sending webhook", "url", webhook.Url, "http method", webhook.HttpMethod)
  41. if webhook.HttpMethod == "" {
  42. webhook.HttpMethod = http.MethodPost
  43. }
  44. request, err := http.NewRequest(webhook.HttpMethod, webhook.Url, bytes.NewReader([]byte(webhook.Body)))
  45. if err != nil {
  46. return err
  47. }
  48. request.Header.Add("Content-Type", "application/json")
  49. request.Header.Add("User-Agent", "Grafana")
  50. if webhook.User != "" && webhook.Password != "" {
  51. request.Header.Add("Authorization", util.GetBasicAuthHeader(webhook.User, webhook.Password))
  52. }
  53. resp, err := ctxhttp.Do(ctx, http.DefaultClient, request)
  54. if err != nil {
  55. return err
  56. }
  57. if resp.StatusCode/100 == 2 {
  58. return nil
  59. }
  60. defer resp.Body.Close()
  61. body, err := ioutil.ReadAll(resp.Body)
  62. if err != nil {
  63. return err
  64. }
  65. webhookLog.Debug("Webhook failed", "statuscode", resp.Status, "body", string(body))
  66. return fmt.Errorf("Webhook response status %v", resp.Status)
  67. }
  68. var addToWebhookQueue = func(msg *Webhook) {
  69. webhookQueue <- msg
  70. }