github.com/newrelic/newrelic-client-go@v1.1.0/pkg/events/events.go (about) 1 package events 2 3 import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "strings" 9 "time" 10 11 "github.com/newrelic/newrelic-client-go/internal/http" 12 "github.com/newrelic/newrelic-client-go/pkg/config" 13 "github.com/newrelic/newrelic-client-go/pkg/logging" 14 ) 15 16 const ( 17 DefaultBatchWorkers = 1 18 DefaultBatchSize = 900 19 DefaultBatchTimeout = 60 * time.Second 20 ) 21 22 // Events is used to send custom events to NRDB. 23 type Events struct { 24 client http.Client 25 config config.Config 26 logger logging.Logger 27 28 // For queue based event handling 29 accountID int 30 eventQueue chan []byte 31 eventTimer *time.Timer 32 flushQueue []chan bool 33 34 // These have defaults 35 batchWorkers int 36 batchSize int 37 batchTimeout time.Duration 38 } 39 40 // New is used to create a new Events client instance. 41 func New(cfg config.Config) Events { 42 cfg.Compression = config.Compression.Gzip 43 44 client := http.NewClient(cfg) 45 if cfg.InsightsInsertKey != "" { 46 client.SetAuthStrategy(&http.InsightsInsertKeyAuthorizer{}) 47 } else { 48 client.SetAuthStrategy(&http.LicenseKeyAuthorizer{}) 49 } 50 51 pkg := Events{ 52 client: client, 53 config: cfg, 54 logger: cfg.GetLogger(), 55 batchWorkers: DefaultBatchWorkers, 56 batchSize: DefaultBatchSize, 57 batchTimeout: DefaultBatchTimeout, 58 } 59 60 return pkg 61 } 62 63 // CreateEvent reports a custom event to New Relic. 64 func (e *Events) CreateEvent(accountID int, event interface{}) error { 65 return e.CreateEventWithContext(context.Background(), accountID, event) 66 } 67 68 // CreateEventWithContext reports a custom event to New Relic. 69 func (e *Events) CreateEventWithContext(ctx context.Context, accountID int, event interface{}) error { 70 jsonData, err := e.marshalEvent(event) 71 if err != nil { 72 return err 73 } 74 if jsonData == nil { 75 return errors.New("events: CreateEvent marhal returned nil data") 76 } 77 78 resp := &createEventResponse{} 79 80 _, err = e.client.PostWithContext(ctx, e.config.Region().InsightsURL(accountID), nil, *jsonData, resp) 81 if err != nil { 82 return err 83 } 84 85 if !resp.Success { 86 return errors.New("failed creating custom event") 87 } 88 89 return nil 90 } 91 92 // marshalEvent converts the event interface into a JSON []byte 93 func (e *Events) marshalEvent(event interface{}) (*[]byte, error) { 94 var jsonData []byte 95 96 switch event := event.(type) { 97 case []byte: 98 jsonData = event 99 case string: 100 jsonData = []byte(event) 101 default: 102 var err error 103 jsonData, err = json.Marshal(event) 104 if err != nil { 105 return nil, fmt.Errorf("error marshaling event data: %s", err.Error()) 106 } 107 } 108 109 if !strings.Contains(string(jsonData), "eventType") { 110 return nil, fmt.Errorf("event data must contain eventType field. %s", jsonData) 111 } 112 113 return &jsonData, nil 114 } 115 116 type createEventResponse struct { 117 Success bool `json:"success"` 118 UUID string `json:"uuid"` 119 }