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  }