github.com/newrelic/go-agent@v3.26.0+incompatible/_integrations/nrgorilla/v1/nrgorilla.go (about)

     1  // Copyright 2020 New Relic Corporation. All rights reserved.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  // Package nrgorilla instruments https://github.com/gorilla/mux applications.
     5  //
     6  // Use this package to instrument inbound requests handled by a gorilla
     7  // mux.Router.  Call nrgorilla.InstrumentRoutes on your gorilla mux.Router
     8  // after your routes have been added to it.
     9  //
    10  // Example: https://github.com/newrelic/go-agent/tree/master/_integrations/nrgorilla/v1/example/main.go
    11  package nrgorilla
    12  
    13  import (
    14  	"net/http"
    15  
    16  	"github.com/gorilla/mux"
    17  	newrelic "github.com/newrelic/go-agent"
    18  	"github.com/newrelic/go-agent/internal"
    19  )
    20  
    21  func init() { internal.TrackUsage("integration", "framework", "gorilla", "v1") }
    22  
    23  type instrumentedHandler struct {
    24  	name string
    25  	app  newrelic.Application
    26  	orig http.Handler
    27  }
    28  
    29  func (h instrumentedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    30  	txn := h.app.StartTransaction(h.name, w, r)
    31  	defer txn.End()
    32  
    33  	r = newrelic.RequestWithTransactionContext(r, txn)
    34  
    35  	h.orig.ServeHTTP(txn, r)
    36  }
    37  
    38  func instrumentRoute(h http.Handler, app newrelic.Application, name string) http.Handler {
    39  	if _, ok := h.(instrumentedHandler); ok {
    40  		return h
    41  	}
    42  	return instrumentedHandler{
    43  		name: name,
    44  		orig: h,
    45  		app:  app,
    46  	}
    47  }
    48  
    49  func routeName(route *mux.Route) string {
    50  	if nil == route {
    51  		return ""
    52  	}
    53  	if n := route.GetName(); n != "" {
    54  		return n
    55  	}
    56  	if n, _ := route.GetPathTemplate(); n != "" {
    57  		return n
    58  	}
    59  	n, _ := route.GetHostTemplate()
    60  	return n
    61  }
    62  
    63  // InstrumentRoutes instruments requests through the provided mux.Router.  Use
    64  // this after the routes have been added to the router.
    65  func InstrumentRoutes(r *mux.Router, app newrelic.Application) *mux.Router {
    66  	if app != nil {
    67  		r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
    68  			h := instrumentRoute(route.GetHandler(), app, routeName(route))
    69  			route.Handler(h)
    70  			return nil
    71  		})
    72  		if nil != r.NotFoundHandler {
    73  			r.NotFoundHandler = instrumentRoute(r.NotFoundHandler, app, "NotFoundHandler")
    74  		}
    75  	}
    76  	return r
    77  }