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