github.com/lulzWill/go-agent@v2.1.2+incompatible/examples/server/main.go (about) 1 package main 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "math/rand" 8 "net/http" 9 "os" 10 "time" 11 12 newrelic "github.com/lulzWill/go-agent" 13 ) 14 15 var ( 16 app newrelic.Application 17 ) 18 19 func index(w http.ResponseWriter, r *http.Request) { 20 io.WriteString(w, "hello world") 21 } 22 23 func versionHandler(w http.ResponseWriter, r *http.Request) { 24 io.WriteString(w, "New Relic Go Agent Version: "+newrelic.Version) 25 } 26 27 func noticeError(w http.ResponseWriter, r *http.Request) { 28 io.WriteString(w, "noticing an error") 29 30 if txn, ok := w.(newrelic.Transaction); ok { 31 txn.NoticeError(errors.New("my error message")) 32 } 33 } 34 35 func noticeErrorWithAttributes(w http.ResponseWriter, r *http.Request) { 36 io.WriteString(w, "noticing an error") 37 38 if txn, ok := w.(newrelic.Transaction); ok { 39 txn.NoticeError(newrelic.Error{ 40 Message: "uh oh. something went very wrong", 41 Class: "errors are aggregated by class", 42 Attributes: map[string]interface{}{ 43 "important_number": 97232, 44 "relevant_string": "zap", 45 }, 46 }) 47 } 48 } 49 50 func customEvent(w http.ResponseWriter, r *http.Request) { 51 io.WriteString(w, "recording a custom event") 52 53 app.RecordCustomEvent("my_event_type", map[string]interface{}{ 54 "myString": "hello", 55 "myFloat": 0.603, 56 "myInt": 123, 57 "myBool": true, 58 }) 59 } 60 61 func setName(w http.ResponseWriter, r *http.Request) { 62 io.WriteString(w, "changing the transaction's name") 63 64 if txn, ok := w.(newrelic.Transaction); ok { 65 txn.SetName("other-name") 66 } 67 } 68 69 func addAttribute(w http.ResponseWriter, r *http.Request) { 70 io.WriteString(w, "adding attributes") 71 72 if txn, ok := w.(newrelic.Transaction); ok { 73 txn.AddAttribute("myString", "hello") 74 txn.AddAttribute("myInt", 123) 75 } 76 } 77 78 func background(w http.ResponseWriter, r *http.Request) { 79 // Transactions started without an http.Request are classified as 80 // background transactions. 81 txn := app.StartTransaction("background", nil, nil) 82 defer txn.End() 83 84 io.WriteString(w, "background transaction") 85 time.Sleep(150 * time.Millisecond) 86 } 87 88 func ignore(w http.ResponseWriter, r *http.Request) { 89 if coinFlip := (0 == rand.Intn(2)); coinFlip { 90 if txn, ok := w.(newrelic.Transaction); ok { 91 txn.Ignore() 92 } 93 io.WriteString(w, "ignoring the transaction") 94 } else { 95 io.WriteString(w, "not ignoring the transaction") 96 } 97 } 98 99 func segments(w http.ResponseWriter, r *http.Request) { 100 txn, _ := w.(newrelic.Transaction) 101 102 func() { 103 defer newrelic.StartSegment(txn, "f1").End() 104 105 func() { 106 defer newrelic.StartSegment(txn, "f2").End() 107 108 io.WriteString(w, "segments!") 109 time.Sleep(10 * time.Millisecond) 110 }() 111 time.Sleep(15 * time.Millisecond) 112 }() 113 time.Sleep(20 * time.Millisecond) 114 } 115 116 func mysql(w http.ResponseWriter, r *http.Request) { 117 txn, _ := w.(newrelic.Transaction) 118 s := newrelic.DatastoreSegment{ 119 StartTime: newrelic.StartSegmentNow(txn), 120 Product: newrelic.DatastoreMySQL, 121 Collection: "users", 122 Operation: "INSERT", 123 ParameterizedQuery: "INSERT INTO users (name, age) VALUES ($1, $2)", 124 QueryParameters: map[string]interface{}{ 125 "name": "Dracula", 126 "age": 439, 127 }, 128 Host: "mysql-server-1", 129 PortPathOrID: "3306", 130 DatabaseName: "my_database", 131 } 132 defer s.End() 133 134 time.Sleep(20 * time.Millisecond) 135 io.WriteString(w, `performing fake query "INSERT * from users"`) 136 } 137 138 func external(w http.ResponseWriter, r *http.Request) { 139 url := "http://example.com/" 140 txn, _ := w.(newrelic.Transaction) 141 // This demonstrates an external segment where only the URL is known. If 142 // an http.Request is accessible then `StartExternalSegment` is 143 // recommended. See the implementation of `NewRoundTripper` for an 144 // example. 145 es := newrelic.ExternalSegment{ 146 StartTime: newrelic.StartSegmentNow(txn), 147 URL: url, 148 } 149 defer es.End() 150 151 resp, err := http.Get(url) 152 if nil != err { 153 io.WriteString(w, err.Error()) 154 return 155 } 156 defer resp.Body.Close() 157 io.Copy(w, resp.Body) 158 } 159 160 func roundtripper(w http.ResponseWriter, r *http.Request) { 161 client := &http.Client{} 162 txn, _ := w.(newrelic.Transaction) 163 client.Transport = newrelic.NewRoundTripper(txn, nil) 164 resp, err := client.Get("http://example.com/") 165 if nil != err { 166 io.WriteString(w, err.Error()) 167 return 168 } 169 defer resp.Body.Close() 170 io.Copy(w, resp.Body) 171 } 172 173 func customMetric(w http.ResponseWriter, r *http.Request) { 174 for _, vals := range r.Header { 175 for _, v := range vals { 176 // This custom metric will have the name 177 // "Custom/HeaderLength" in the New Relic UI. 178 app.RecordCustomMetric("HeaderLength", float64(len(v))) 179 } 180 } 181 io.WriteString(w, "custom metric recorded") 182 } 183 184 func mustGetEnv(key string) string { 185 if val := os.Getenv(key); "" != val { 186 return val 187 } 188 panic(fmt.Sprintf("environment variable %s unset", key)) 189 } 190 191 func main() { 192 cfg := newrelic.NewConfig("Example App", mustGetEnv("NEW_RELIC_LICENSE_KEY")) 193 cfg.Logger = newrelic.NewDebugLogger(os.Stdout) 194 195 var err error 196 app, err = newrelic.NewApplication(cfg) 197 if nil != err { 198 fmt.Println(err) 199 os.Exit(1) 200 } 201 202 http.HandleFunc(newrelic.WrapHandleFunc(app, "/", index)) 203 http.HandleFunc(newrelic.WrapHandleFunc(app, "/version", versionHandler)) 204 http.HandleFunc(newrelic.WrapHandleFunc(app, "/notice_error", noticeError)) 205 http.HandleFunc(newrelic.WrapHandleFunc(app, "/notice_error_with_attributes", noticeErrorWithAttributes)) 206 http.HandleFunc(newrelic.WrapHandleFunc(app, "/custom_event", customEvent)) 207 http.HandleFunc(newrelic.WrapHandleFunc(app, "/set_name", setName)) 208 http.HandleFunc(newrelic.WrapHandleFunc(app, "/add_attribute", addAttribute)) 209 http.HandleFunc(newrelic.WrapHandleFunc(app, "/ignore", ignore)) 210 http.HandleFunc(newrelic.WrapHandleFunc(app, "/segments", segments)) 211 http.HandleFunc(newrelic.WrapHandleFunc(app, "/mysql", mysql)) 212 http.HandleFunc(newrelic.WrapHandleFunc(app, "/external", external)) 213 http.HandleFunc(newrelic.WrapHandleFunc(app, "/roundtripper", roundtripper)) 214 http.HandleFunc(newrelic.WrapHandleFunc(app, "/custommetric", customMetric)) 215 http.HandleFunc("/background", background) 216 217 http.ListenAndServe(":8000", nil) 218 }