github.com/Tyktechnologies/tyk@v2.9.5+incompatible/gateway/newrelic.go (about) 1 package gateway 2 3 import ( 4 "fmt" 5 "strconv" 6 7 "github.com/gocraft/health" 8 "github.com/gorilla/mux" 9 newrelic "github.com/newrelic/go-agent" 10 "github.com/newrelic/go-agent/_integrations/nrgorilla/v1" 11 "github.com/sirupsen/logrus" 12 13 "github.com/TykTechnologies/tyk/config" 14 ) 15 16 // SetupNewRelic creates new newrelic.Application instance 17 func SetupNewRelic() (app newrelic.Application) { 18 var err error 19 logger := log.WithFields(logrus.Fields{"prefix": "newrelic"}) 20 21 logger.Info("Initializing NewRelic...") 22 23 cfg := newrelic.NewConfig(config.Global().NewRelic.AppName, config.Global().NewRelic.LicenseKey) 24 if config.Global().NewRelic.AppName != "" { 25 cfg.Enabled = true 26 } 27 cfg.Logger = &newRelicLogger{logger} 28 29 if app, err = newrelic.NewApplication(cfg); err != nil { 30 logger.Warn("Error initializing NewRelic, skipping... ", err) 31 return 32 } 33 34 instrument.AddSink(&newRelicSink{relic: app}) 35 logger.Info("NewRelic initialized") 36 37 return 38 } 39 40 // AddNewRelicInstrumentation adds NewRelic instrumentation to the router 41 func AddNewRelicInstrumentation(app newrelic.Application, r *mux.Router) { 42 if app != nil { 43 nrgorilla.InstrumentRoutes(r, app) 44 } 45 } 46 47 type newRelicLogger struct{ *logrus.Entry } 48 49 func (l *newRelicLogger) Error(msg string, c map[string]interface{}) { 50 l.WithFields(c).Error(msg) 51 } 52 func (l *newRelicLogger) Warn(msg string, c map[string]interface{}) { 53 l.WithFields(c).Warn(msg) 54 } 55 func (l *newRelicLogger) Info(msg string, c map[string]interface{}) { 56 l.WithFields(c).Info(msg) 57 } 58 func (l *newRelicLogger) Debug(msg string, c map[string]interface{}) { 59 l.WithFields(c).Debug(msg) 60 } 61 func (l *newRelicLogger) DebugEnabled() bool { 62 return l.Level >= logrus.DebugLevel 63 } 64 65 type newRelicSink struct { 66 relic newrelic.Application 67 health.Sink 68 } 69 70 func (s *newRelicSink) EmitEvent(job string, event string, kvs map[string]string) { 71 s.relic.RecordCustomEvent(job+":"+event, makeParams(kvs)) 72 } 73 74 func (s *newRelicSink) EmitEventErr(job string, event string, err error, kvs map[string]string) { 75 s.relic.RecordCustomEvent(job+":"+event+":msg:"+err.Error(), makeParams(kvs)) 76 } 77 78 func (s *newRelicSink) EmitTiming(job string, event string, nanoseconds int64, kvs map[string]string) { 79 s.relic.RecordCustomEvent(job+":"+event+":dur(ns):"+strconv.FormatInt(nanoseconds, 10), makeParams(kvs)) 80 } 81 82 func (s *newRelicSink) EmitComplete(job string, status health.CompletionStatus, nanoseconds int64, kvs map[string]string) { 83 s.relic.RecordCustomEvent(job+":health:"+status.String()+":dur(ns):"+strconv.FormatInt(nanoseconds, 10), makeParams(kvs)) 84 } 85 86 func (s *newRelicSink) EmitGauge(job string, event string, value float64, kvs map[string]string) { 87 s.relic.RecordCustomEvent(job+":"+event+":value:"+fmt.Sprintf("%.2f", value), makeParams(kvs)) 88 } 89 90 func makeParams(kvs map[string]string) (params map[string]interface{}) { 91 params = make(map[string]interface{}, len(kvs)) 92 for k, v := range kvs { 93 params[k] = v 94 } 95 return 96 }