Skip to content

Commit

Permalink
Merge pull request #768 from Abdulsametileri/main
Browse files Browse the repository at this point in the history
feat: propagate newrelic tx info by using fiber.Ctx and little refact…
  • Loading branch information
mstrYoda authored Sep 13, 2023
2 parents 502f4c5 + 2f55bd2 commit e6b6de0
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 21 deletions.
12 changes: 11 additions & 1 deletion fibernewrelic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,19 @@ func main() {
app.Get("/", func(ctx *fiber.Ctx) error {
return ctx.SendStatus(200)
})

app.Get("/foo", func(ctx *fiber.Ctx) error {
txn := newrelic.FromContext(ctx)
segment := txn.StartSegment("foo segment")
defer segment.End()

// do foo

return nil
})

cfg := fibernewrelic.Config{
Application: newrelicApp
Application: newrelicApp,
}

app.Use(fibernewrelic.New(cfg))
Expand Down
44 changes: 26 additions & 18 deletions fibernewrelic/fiber.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package fibernewrelic

import (
"fmt"
"github.com/gofiber/fiber/v2/utils"
"net/url"
"strings"

"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/utils"
"github.com/newrelic/go-agent/v3/newrelic"
)

Expand Down Expand Up @@ -66,33 +66,31 @@ func New(cfg Config) fiber.Handler {
}

return func(c *fiber.Ctx) error {
txn := app.StartTransaction("")
txn := app.StartTransaction(createTransactionName(c))
defer txn.End()

handlerErr := c.Next()

var (
method = utils.CopyString(c.Method())
routePath = utils.CopyString(c.Route().Path)
host = utils.CopyString(c.Hostname())
host = utils.CopyString(c.Hostname())
method = utils.CopyString(c.Method())
)

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))
scheme := c.Request().URI().Scheme()

txn.SetWebRequest(newrelic.WebRequest{
URL: &u,
Method: method,
Transport: transport(u.Scheme),
Host: host,
Method: method,
Transport: transport(string(scheme)),
URL: &url.URL{
Host: host,
Scheme: string(c.Request().URI().Scheme()),
Path: string(c.Request().URI().Path()),
RawQuery: string(c.Request().URI().QueryString()),
},
})

c.SetUserContext(newrelic.NewContext(c.UserContext(), txn))

handlerErr := c.Next()
statusCode := c.Context().Response.StatusCode()

if handlerErr != nil {
Expand All @@ -106,6 +104,16 @@ func New(cfg Config) fiber.Handler {
}
}

// FromContext returns the Transaction from the context if present, and nil
// otherwise.
func FromContext(c *fiber.Ctx) *newrelic.Transaction {
return newrelic.FromContext(c.UserContext())
}

func createTransactionName(c *fiber.Ctx) string {
return fmt.Sprintf("%s %s", c.Request().Header.Method(), c.Request().URI().Path())
}

func transport(schema string) newrelic.TransportType {
if strings.HasPrefix(schema, "https") {
return newrelic.TransportHTTPS
Expand Down
36 changes: 34 additions & 2 deletions fibernewrelic/fiber_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ func TestNewrelicAppConfig(t *testing.T) {
return ctx.SendStatus(200)
})

r := httptest.NewRequest("GET", "/", nil)
r := httptest.NewRequest(http.MethodGet, "/", nil)
resp, _ := app.Test(r, -1)
assert.Equal(t, 200, resp.StatusCode)
assert.Equal(t, http.StatusOK, resp.StatusCode)
})

t.Run("Run successfully as middleware",
Expand Down Expand Up @@ -310,3 +310,35 @@ func TestDefaultErrorStatusCodeHandler(t *testing.T) {
assert.Equal(t, http.StatusNotFound, resp.StatusCode)
})
}

func TestFromContext(t *testing.T) {
// given
cfg := Config{
License: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
AppName: "",
Enabled: true,
}
app := fiber.New()
app.Use(New(cfg))
app.Get("/foo", func(ctx *fiber.Ctx) error {
tx := FromContext(ctx)

if tx.Name() != "GET /foo" {
return ctx.SendStatus(http.StatusInternalServerError)
}

segment := tx.StartSegment("foo")
defer segment.End()

return ctx.SendStatus(http.StatusOK)
})

req := httptest.NewRequest(http.MethodGet, "/foo", http.NoBody)

// when
res, err := app.Test(req, -1)

// then
assert.Nil(t, err)
assert.Equal(t, http.StatusOK, res.StatusCode)
}

0 comments on commit e6b6de0

Please sign in to comment.