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  }