github.com/newrelic/go-agent@v3.26.0+incompatible/examples_test.go (about) 1 // Copyright 2020 New Relic Corporation. All rights reserved. 2 // SPDX-License-Identifier: Apache-2.0 3 4 // +build go1.7 5 6 package newrelic 7 8 import ( 9 "fmt" 10 "io" 11 "log" 12 "net/http" 13 "net/url" 14 "os" 15 "time" 16 ) 17 18 func Example() { 19 // First create a Config. 20 cfg := NewConfig("Example Application", "__YOUR_NEW_RELIC_LICENSE_KEY__") 21 22 // Modify Config fields to control agent behavior. 23 cfg.Logger = NewDebugLogger(os.Stdout) 24 25 // Now use the Config the create an Application. 26 app, err := NewApplication(cfg) 27 if nil != err { 28 fmt.Println(err) 29 os.Exit(1) 30 } 31 32 // Now you can use the Application to collect data! Create transactions 33 // to time inbound requests or background tasks. You can start and stop 34 // transactions directly using Application.StartTransaction and 35 // Transaction.End. 36 func() { 37 txn := app.StartTransaction("myTask", nil, nil) 38 defer txn.End() 39 40 time.Sleep(time.Second) 41 }() 42 43 // WrapHandler and WrapHandleFunc make it easy to instrument inbound web 44 // requests handled by the http standard library without calling 45 // StartTransaction. Popular framework instrumentation packages exist 46 // in the _integrations directory. 47 http.HandleFunc(WrapHandleFunc(app, "", func(w http.ResponseWriter, req *http.Request) { 48 io.WriteString(w, "this is the index page") 49 })) 50 helloHandler := func(w http.ResponseWriter, req *http.Request) { 51 // WrapHandler and WrapHandleFunc add the transaction to the 52 // inbound request's context. Access the transaction using 53 // FromContext to add attributes, create segments, and notice. 54 // errors. 55 txn := FromContext(req.Context()) 56 57 func() { 58 // Segments help you understand where the time in your 59 // transaction is being spent. You can use them to time 60 // functions or arbitrary blocks of code. 61 defer StartSegment(txn, "helperFunction").End() 62 }() 63 64 io.WriteString(w, "hello world") 65 } 66 http.HandleFunc(WrapHandleFunc(app, "/hello", helloHandler)) 67 http.ListenAndServe(":8000", nil) 68 } 69 70 func currentTransaction() Transaction { 71 return nil 72 } 73 74 func ExampleNewRoundTripper() { 75 client := &http.Client{} 76 // The RoundTripper returned by NewRoundTripper instruments all requests 77 // done by this client with external segments. 78 client.Transport = NewRoundTripper(nil, client.Transport) 79 80 request, _ := http.NewRequest("GET", "http://example.com", nil) 81 82 // Be sure to add the current Transaction to each request's context so 83 // the Transport has access to it. 84 txn := currentTransaction() 85 request = RequestWithTransactionContext(request, txn) 86 87 client.Do(request) 88 } 89 90 func getApp() Application { 91 return nil 92 } 93 94 func ExampleBrowserTimingHeader() { 95 handler := func(w http.ResponseWriter, req *http.Request) { 96 io.WriteString(w, "<html><head>") 97 // The New Relic browser javascript should be placed as high in the 98 // HTML as possible. We suggest including it immediately after the 99 // opening <head> tag and any <meta charset> tags. 100 if txn := FromContext(req.Context()); nil != txn { 101 hdr, err := txn.BrowserTimingHeader() 102 if nil != err { 103 log.Printf("unable to create browser timing header: %v", err) 104 } 105 // BrowserTimingHeader() will always return a header whose methods can 106 // be safely called. 107 if js := hdr.WithTags(); js != nil { 108 w.Write(js) 109 } 110 } 111 io.WriteString(w, "</head><body>browser header page</body></html>") 112 } 113 http.HandleFunc(WrapHandleFunc(getApp(), "/browser", handler)) 114 http.ListenAndServe(":8000", nil) 115 } 116 117 func ExampleDatastoreSegment() { 118 txn := currentTransaction() 119 ds := &DatastoreSegment{ 120 StartTime: StartSegmentNow(txn), 121 // Product, Collection, and Operation are the primary metric 122 // aggregation fields which we encourage you to populate. 123 Product: DatastoreMySQL, 124 Collection: "users_table", 125 Operation: "SELECT", 126 } 127 // your database call here 128 ds.End() 129 } 130 131 func ExampleMessageProducerSegment() { 132 txn := currentTransaction() 133 seg := &MessageProducerSegment{ 134 StartTime: StartSegmentNow(txn), 135 Library: "RabbitMQ", 136 DestinationType: MessageExchange, 137 DestinationName: "myExchange", 138 } 139 // add message to queue here 140 seg.End() 141 } 142 143 func ExampleError() { 144 txn := currentTransaction() 145 username := "gopher" 146 e := fmt.Errorf("error unable to login user %s", username) 147 // txn.NoticeError(newrelic.Error{...}) instead of txn.NoticeError(e) 148 // allows more control over error fields. Class is how errors are 149 // aggregated and Attributes are added to the error event and error 150 // trace. 151 txn.NoticeError(Error{ 152 Message: e.Error(), 153 Class: "LoginError", 154 Attributes: map[string]interface{}{ 155 "username": username, 156 }, 157 }) 158 } 159 160 func ExampleExternalSegment() { 161 txn := currentTransaction() 162 client := &http.Client{} 163 request, _ := http.NewRequest("GET", "http://www.example.com", nil) 164 segment := StartExternalSegment(txn, request) 165 response, _ := client.Do(request) 166 segment.Response = response 167 segment.End() 168 } 169 170 // StartExternalSegment is the recommend way of creating ExternalSegments. If 171 // you don't have access to an http.Request, however, you may create an 172 // ExternalSegment and control the URL manually. 173 func ExampleExternalSegment_url() { 174 txn := currentTransaction() 175 segment := ExternalSegment{ 176 StartTime: StartSegmentNow(txn), 177 // URL is parsed using url.Parse so it must include the protocol 178 // scheme (eg. "http://"). The host of the URL is used to 179 // create metrics. Change the host to alter aggregation. 180 URL: "http://www.example.com", 181 } 182 http.Get("http://www.example.com") 183 segment.End() 184 } 185 186 func ExampleStartExternalSegment() { 187 txn := currentTransaction() 188 client := &http.Client{} 189 request, _ := http.NewRequest("GET", "http://www.example.com", nil) 190 segment := StartExternalSegment(txn, request) 191 response, _ := client.Do(request) 192 segment.Response = response 193 segment.End() 194 } 195 196 func ExampleStartExternalSegment_context() { 197 txn := currentTransaction() 198 request, _ := http.NewRequest("GET", "http://www.example.com", nil) 199 200 // If the transaction is added to the request's context then it does not 201 // need to be provided as a parameter to StartExternalSegment. 202 request = RequestWithTransactionContext(request, txn) 203 segment := StartExternalSegment(nil, request) 204 205 client := &http.Client{} 206 response, _ := client.Do(request) 207 segment.Response = response 208 segment.End() 209 } 210 211 func ExampleNewStaticWebRequest() { 212 app := getApp() 213 webReq := NewStaticWebRequest(http.Header{}, &url.URL{Path: "path"}, "GET", TransportHTTP) 214 txn := app.StartTransaction("My-Transaction", nil, nil) 215 txn.SetWebRequest(webReq) 216 }