Skip to content

Commit 0e8d112

Browse files
authored
feat(nrecho-v4/v3): add New Relic instrumentation for Echo v4/v3 (#134)
* feat(nrecho-v4/v3): add New Relic instrumentation for Echo v4/v3 * Update go.mod/go.sums * feat(nrecho): enhance middleware handling and add tests for echo integration * feat(nrecho): improve function instrumentation and add tests for middleware handling * update expect ref
1 parent d301fdb commit 0e8d112

30 files changed

Lines changed: 2843 additions & 86 deletions

File tree

cmd/instrument.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
"github.com/charmbracelet/lipgloss"
1313
"github.com/dave/dst/decorator"
1414
"github.com/newrelic/go-easy-instrumentation/integrations/nragent"
15+
nrecho_v3 "github.com/newrelic/go-easy-instrumentation/integrations/nrecho-v3"
16+
nrecho_v4 "github.com/newrelic/go-easy-instrumentation/integrations/nrecho-v4"
1517
"github.com/newrelic/go-easy-instrumentation/integrations/nrgin"
1618
"github.com/newrelic/go-easy-instrumentation/integrations/nrgochi"
1719
"github.com/newrelic/go-easy-instrumentation/integrations/nrgrpc"
@@ -41,6 +43,8 @@ func registerIntegrations(manager *parser.InstrumentationManager) {
4143
parser.DetectTransactions,
4244
parser.DetectErrors,
4345
parser.DetectGinInstrumentation,
46+
parser.DetectEchoInstrumentation,
47+
parser.DetectEchoV3Instrumentation,
4448
nrnethttp.DetectWrappedRoutes,
4549
)
4650

@@ -52,6 +56,8 @@ func registerIntegrations(manager *parser.InstrumentationManager) {
5256
nrnethttp.CannotInstrumentHttpMethod,
5357
nrgrpc.InstrumentGrpcDial,
5458
nrgin.InstrumentGinFunction,
59+
nrecho_v4.InstrumentEchoFunction,
60+
nrecho_v3.InstrumentEchoFunction,
5561
nrgrpc.InstrumentGrpcServerMethod,
5662
nrslog.InstrumentSlogHandler,
5763
)
@@ -62,6 +68,8 @@ func registerIntegrations(manager *parser.InstrumentationManager) {
6268
nrnethttp.WrapNestedHandleFunction,
6369
nrgrpc.InstrumentGrpcServer,
6470
nrgin.InstrumentGinMiddleware,
71+
nrecho_v4.InstrumentEchoMiddleware,
72+
nrecho_v3.InstrumentEchoMiddleware,
6573
nrgochi.InstrumentChiMiddleware,
6674
nrgochi.InstrumentChiRouterLiteral,
6775
)

go.mod

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ require (
77
github.com/charmbracelet/bubbletea v1.3.10
88
github.com/charmbracelet/lipgloss v1.1.0
99
github.com/dave/dst v0.27.3
10-
github.com/newrelic/go-agent/v3 v3.42.0
10+
github.com/newrelic/go-agent/v3 v3.43.3
1111
github.com/sourcegraph/go-diff-patch v0.0.0-20240223163233-798fd1e94a8e
1212
github.com/spf13/cobra v1.8.1
1313
github.com/stretchr/testify v1.10.0
14-
golang.org/x/term v0.30.0
15-
golang.org/x/tools v0.28.0
14+
golang.org/x/term v0.39.0
15+
golang.org/x/tools v0.40.0
1616
)
1717

18-
require golang.org/x/sync v0.12.0 // indirect
18+
require golang.org/x/sync v0.19.0 // indirect
1919

2020
require (
2121
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
@@ -39,13 +39,13 @@ require (
3939
github.com/rogpeppe/go-internal v1.13.1 // indirect
4040
github.com/spf13/pflag v1.0.5 // indirect
4141
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
42-
golang.org/x/mod v0.22.0 // indirect
43-
golang.org/x/net v0.38.0 // indirect
44-
golang.org/x/sys v0.36.0 // indirect
45-
golang.org/x/text v0.23.0 // indirect
46-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect
47-
google.golang.org/grpc v1.65.0 // indirect
48-
google.golang.org/protobuf v1.34.2 // indirect
42+
golang.org/x/mod v0.31.0 // indirect
43+
golang.org/x/net v0.49.0 // indirect
44+
golang.org/x/sys v0.40.0 // indirect
45+
golang.org/x/text v0.33.0 // indirect
46+
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 // indirect
47+
google.golang.org/grpc v1.80.0 // indirect
48+
google.golang.org/protobuf v1.36.11 // indirect
4949
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
5050
gopkg.in/yaml.v3 v3.0.1 // indirect
5151
)

go.sum

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
22
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
3+
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
4+
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
35
github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
46
github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
57
github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
@@ -24,8 +26,16 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
2426
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2527
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
2628
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
27-
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
28-
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
29+
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
30+
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
31+
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
32+
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
33+
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
34+
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
35+
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
36+
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
37+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
38+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
2939
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
3040
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
3141
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
@@ -49,8 +59,8 @@ github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELU
4959
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
5060
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
5161
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
52-
github.com/newrelic/go-agent/v3 v3.42.0 h1:aA2Ea1RT5eD59LtOS1KGFXSmaDs6kM3Jeqo7PpuQoFQ=
53-
github.com/newrelic/go-agent/v3 v3.42.0/go.mod h1:sCgxDCVydoKD/C4S8BFxDtmFHvdWHtaIz/a3kiyNB/k=
62+
github.com/newrelic/go-agent/v3 v3.43.3 h1:0A6DkUBYK2bidV6jJDJ1SD2XkRlg976nl+SiEqkGTUQ=
63+
github.com/newrelic/go-agent/v3 v3.43.3/go.mod h1:MFXnCId5xXMIJI6A/kbkg0DO48EVTsKcmNijMYphzTg=
5464
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
5565
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
5666
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -73,30 +83,44 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
7383
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
7484
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
7585
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
86+
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
87+
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
88+
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
89+
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
90+
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
91+
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
92+
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
93+
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
94+
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
95+
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
96+
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
97+
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
7698
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
7799
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
78-
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
79-
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
80-
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
81-
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
82-
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
83-
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
100+
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
101+
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
102+
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
103+
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
104+
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
105+
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
84106
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
85107
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
86-
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
87-
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
88-
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
89-
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
90-
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
91-
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
92-
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
93-
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
94-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8=
95-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
96-
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
97-
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
98-
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
99-
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
108+
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
109+
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
110+
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
111+
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
112+
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
113+
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
114+
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
115+
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
116+
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
117+
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
118+
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 h1:sNrWoksmOyF5bvJUcnmbeAmQi8baNhqg5IWaI3llQqU=
119+
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
120+
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=
121+
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
122+
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
123+
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
100124
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
101125
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
102126
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

integrations/nrecho-v3/codegen.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package nrecho
2+
3+
import (
4+
"go/token"
5+
6+
"github.com/dave/dst"
7+
)
8+
9+
const (
10+
NrechoImportPath = "github.com/newrelic/go-agent/v3/integrations/nrecho-v3"
11+
EchoImportPath = "github.com/labstack/echo"
12+
)
13+
14+
// NrEchoMiddleware returns an Echo middleware call that instruments the router
15+
// with New Relic. Returns the middleware statement and the import path.
16+
//
17+
// Example output:
18+
//
19+
// e.Use(nrecho.Middleware(app))
20+
func NrEchoMiddleware(routerName string, agentVariableName dst.Expr) (*dst.ExprStmt, string) {
21+
return &dst.ExprStmt{
22+
X: &dst.CallExpr{
23+
Fun: &dst.SelectorExpr{
24+
X: &dst.Ident{Name: routerName},
25+
Sel: &dst.Ident{Name: "Use"},
26+
},
27+
Args: []dst.Expr{
28+
&dst.CallExpr{
29+
Fun: &dst.Ident{
30+
Name: "Middleware",
31+
Path: NrechoImportPath,
32+
},
33+
Args: []dst.Expr{
34+
agentVariableName,
35+
},
36+
},
37+
},
38+
},
39+
}, NrechoImportPath
40+
}
41+
42+
// TxnFromEchoContext generates code to extract a New Relic transaction from
43+
// an Echo context.
44+
//
45+
// Example output:
46+
//
47+
// txn := nrecho.FromContext(c)
48+
func TxnFromEchoContext(txnVariable string, ctxName string) *dst.AssignStmt {
49+
return &dst.AssignStmt{
50+
Lhs: []dst.Expr{
51+
&dst.Ident{Name: txnVariable},
52+
},
53+
Tok: token.DEFINE,
54+
Rhs: []dst.Expr{
55+
&dst.CallExpr{
56+
Fun: &dst.Ident{
57+
Name: "FromContext",
58+
Path: NrechoImportPath,
59+
},
60+
Args: []dst.Expr{
61+
&dst.Ident{Name: ctxName},
62+
},
63+
},
64+
},
65+
Decs: dst.AssignStmtDecorations{
66+
NodeDecs: dst.NodeDecs{
67+
Before: dst.NewLine,
68+
},
69+
},
70+
}
71+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package nrecho_test
2+
3+
import (
4+
"go/token"
5+
"reflect"
6+
"testing"
7+
8+
"github.com/newrelic/go-easy-instrumentation/integrations/nrecho-v3"
9+
10+
"github.com/dave/dst"
11+
)
12+
13+
func TestNrEchoMiddleware(t *testing.T) {
14+
type args struct {
15+
call *dst.CallExpr
16+
routerName string
17+
agentVariableName dst.Expr
18+
}
19+
tests := []struct {
20+
name string
21+
args args
22+
want *dst.ExprStmt
23+
}{
24+
{
25+
name: "inject_nrecho_middleware",
26+
args: args{
27+
call: &dst.CallExpr{
28+
Fun: &dst.SelectorExpr{
29+
X: &dst.Ident{
30+
Name: "New",
31+
Path: nrecho.EchoImportPath,
32+
},
33+
},
34+
},
35+
routerName: "e",
36+
agentVariableName: &dst.Ident{Name: "NewRelicApplication"},
37+
},
38+
want: &dst.ExprStmt{
39+
X: &dst.CallExpr{
40+
Fun: &dst.SelectorExpr{
41+
X: &dst.Ident{
42+
Name: "e",
43+
},
44+
Sel: &dst.Ident{
45+
Name: "Use",
46+
},
47+
},
48+
Args: []dst.Expr{
49+
&dst.CallExpr{
50+
Fun: &dst.Ident{
51+
Name: "Middleware",
52+
Path: nrecho.NrechoImportPath,
53+
},
54+
Args: []dst.Expr{
55+
&dst.Ident{Name: "NewRelicApplication"},
56+
},
57+
},
58+
},
59+
},
60+
},
61+
},
62+
}
63+
for _, tt := range tests {
64+
t.Run(tt.name, func(t *testing.T) {
65+
got, imp := nrecho.NrEchoMiddleware(tt.args.routerName, tt.args.agentVariableName)
66+
if !reflect.DeepEqual(got, tt.want) {
67+
t.Errorf("nrecho.NrEchoMiddleware() = %v, want %v", got, tt.want)
68+
}
69+
if imp != nrecho.NrechoImportPath {
70+
t.Errorf("nrecho.NrEchoMiddleware() = %v, want %v", imp, nrecho.NrechoImportPath)
71+
}
72+
})
73+
}
74+
}
75+
76+
func TestTxnFromEchoContext(t *testing.T) {
77+
type args struct {
78+
txnVariable string
79+
ctxName string
80+
}
81+
tests := []struct {
82+
name string
83+
args args
84+
want *dst.AssignStmt
85+
}{
86+
{
87+
name: "assign txn from echo context",
88+
args: args{
89+
txnVariable: "nrTxn",
90+
ctxName: "c",
91+
},
92+
want: &dst.AssignStmt{
93+
Lhs: []dst.Expr{
94+
&dst.Ident{
95+
Name: "nrTxn",
96+
},
97+
},
98+
Tok: token.DEFINE,
99+
Rhs: []dst.Expr{
100+
&dst.CallExpr{
101+
Fun: &dst.Ident{
102+
Name: "FromContext",
103+
Path: nrecho.NrechoImportPath,
104+
},
105+
Args: []dst.Expr{
106+
&dst.Ident{
107+
Name: "c",
108+
},
109+
},
110+
},
111+
},
112+
Decs: dst.AssignStmtDecorations{
113+
NodeDecs: dst.NodeDecs{
114+
Before: dst.NewLine,
115+
},
116+
},
117+
},
118+
},
119+
}
120+
for _, tt := range tests {
121+
t.Run(tt.name, func(t *testing.T) {
122+
if got := nrecho.TxnFromEchoContext(tt.args.txnVariable, tt.args.ctxName); !reflect.DeepEqual(got, tt.want) {
123+
t.Errorf("nrecho.TxnFromEchoContext() = %v, want %v", got, tt.want)
124+
}
125+
})
126+
}
127+
}

0 commit comments

Comments
 (0)