/
newrelic.go
97 lines (76 loc) · 2.34 KB
/
newrelic.go
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
package newrelic
import (
"context"
"fmt"
c "github.com/go-chi/chi/v5"
"net/http"
"strings"
"github.com/americanas-go/ignite/go-chi/chi.v5"
newrelic "github.com/americanas-go/ignite/newrelic/go-agent.v3"
"github.com/americanas-go/log"
"github.com/go-chi/chi/v5/middleware"
nr "github.com/newrelic/go-agent/v3/newrelic"
)
// Register registers a default newrelic plugin as a middleware in a new chi config.
func Register(ctx context.Context, mux *c.Mux) (*chi.Config, error) {
o, err := NewOptions()
if err != nil {
return nil, err
}
n := NewNewrelicWithOptions(o)
return n.Register(ctx, mux)
}
// NewRelic struct which represents a new relic plugin for chi
type Newrelic struct {
options *Options
}
// NewNewrelicWithConfigPath returns a new relic plugin with options from config path.
func NewNewrelicWithConfigPath(path string) (*Newrelic, error) {
o, err := NewOptionsWithPath(path)
if err != nil {
return nil, err
}
return NewNewrelicWithOptions(o), nil
}
// NewNewrelicWithOptions returns a new relic plugin with options.
func NewNewrelicWithOptions(options *Options) *Newrelic {
return &Newrelic{options: options}
}
// Register registers the newrelic plugin as a middleware in a new chi config.
func (d *Newrelic) Register(ctx context.Context, mux *c.Mux) (*chi.Config, error) {
if !d.options.Enabled || !newrelic.IsEnabled() {
return nil, nil
}
logger := log.FromContext(ctx)
logger.Trace("enabling newrelic middleware in chi")
return &chi.Config{
Middlewares: []func(http.Handler) http.Handler{
d.nrMiddleware,
},
}, nil
}
func (d *Newrelic) nrMiddleware(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
url := r.URL.String()
path := r.URL.Path
txnName := strings.Join([]string{r.Method, path}, " ")
txn := newrelic.Application().StartTransaction(txnName)
defer txn.End()
txn.SetWebRequestHTTP(r)
if d.options.WebResponseEnabled {
w = txn.SetWebResponse(w)
}
txn.AddAttribute("request.url", fmt.Sprintf("http://%s%s", r.Host, url))
qs := r.URL.Query()
for key, value := range qs {
txn.AddAttribute(key, strings.Join(value, "|"))
}
if reqID := middleware.GetReqID(ctx); reqID != "" {
txn.AddAttribute("request.id", reqID)
}
r = nr.RequestWithTransactionContext(r, txn)
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}