forked from gofiber/contrib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fiber.go
127 lines (102 loc) · 3.08 KB
/
fiber.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
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
package fibernewrelic
import (
"fmt"
"net/url"
"strings"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/utils"
"github.com/newrelic/go-agent/v3/newrelic"
)
type Config struct {
// License parameter is required to initialize newrelic application
License string
// AppName parameter passed to set app name, default is fiber-api
AppName string
// Enabled parameter passed to enable/disable newrelic
Enabled bool
// TransportType can be HTTP or HTTPS, default is HTTP
// Deprecated: The Transport type now acquiring from request URL scheme internally
TransportType string
// Application field is required to use an existing newrelic application
Application *newrelic.Application
// ErrorStatusCodeHandler is executed when an error is returned from handler
// Optional. Default: DefaultErrorStatusCodeHandler
ErrorStatusCodeHandler func(c *fiber.Ctx, err error) int
}
var ConfigDefault = Config{
Application: nil,
License: "",
AppName: "fiber-api",
Enabled: false,
ErrorStatusCodeHandler: DefaultErrorStatusCodeHandler,
}
func New(cfg Config) fiber.Handler {
var app *newrelic.Application
var err error
if cfg.ErrorStatusCodeHandler == nil {
cfg.ErrorStatusCodeHandler = ConfigDefault.ErrorStatusCodeHandler
}
if cfg.Application != nil {
app = cfg.Application
} else {
if cfg.AppName == "" {
cfg.AppName = ConfigDefault.AppName
}
if cfg.License == "" {
panic(fmt.Errorf("unable to create New Relic Application -> License can not be empty"))
}
app, err = newrelic.NewApplication(
newrelic.ConfigAppName(cfg.AppName),
newrelic.ConfigLicense(cfg.License),
newrelic.ConfigEnabled(cfg.Enabled),
)
if err != nil {
panic(fmt.Errorf("unable to create New Relic Application -> %w", err))
}
}
return func(c *fiber.Ctx) error {
txn := app.StartTransaction("")
defer txn.End()
handlerErr := c.Next()
var (
method = utils.CopyString(c.Method())
routePath = utils.CopyString(c.Route().Path)
host = utils.CopyString(c.Hostname())
)
u := url.URL{
Host: host,
Scheme: string(c.Request().URI().Scheme()),
Path: string(c.Request().URI().Path()),
RawQuery: string(c.Request().URI().QueryString()),
}
txn.SetName(fmt.Sprintf("%s %s", method, routePath))
txn.SetWebRequest(newrelic.WebRequest{
URL: &u,
Method: method,
Transport: transport(u.Scheme),
Host: host,
})
statusCode := c.Context().Response.StatusCode()
if handlerErr != nil {
statusCode = cfg.ErrorStatusCodeHandler(c, handlerErr)
txn.NoticeError(handlerErr)
}
txn.SetWebResponse(nil).WriteHeader(statusCode)
return handlerErr
}
}
func transport(schema string) newrelic.TransportType {
if strings.HasPrefix(schema, "https") {
return newrelic.TransportHTTPS
}
if strings.HasPrefix(schema, "http") {
return newrelic.TransportHTTP
}
return newrelic.TransportUnknown
}
func DefaultErrorStatusCodeHandler(c *fiber.Ctx, err error) int {
if fiberErr, ok := err.(*fiber.Error); ok {
return fiberErr.Code
}
return c.Context().Response.StatusCode()
}