Skip to content

Commit b04ced4

Browse files
IlyasShabiwconti27simon-id
authored
Express 5 Instrumentation (#4913)
Co-authored-by: William Conti <[email protected]> Co-authored-by: simon-id <[email protected]>
1 parent 4e9b1ff commit b04ced4

21 files changed

+397
-171
lines changed

Diff for: packages/datadog-instrumentations/src/express.js

+38-4
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ function wrapResponseRender (render) {
5959

6060
addHook({ name: 'express', versions: ['>=4'] }, express => {
6161
shimmer.wrap(express.application, 'handle', wrapHandle)
62-
shimmer.wrap(express.Router, 'use', wrapRouterMethod)
63-
shimmer.wrap(express.Router, 'route', wrapRouterMethod)
6462

6563
shimmer.wrap(express.response, 'json', wrapResponseJson)
6664
shimmer.wrap(express.response, 'jsonp', wrapResponseJson)
@@ -69,6 +67,20 @@ addHook({ name: 'express', versions: ['>=4'] }, express => {
6967
return express
7068
})
7169

70+
addHook({ name: 'express', versions: ['4'] }, express => {
71+
shimmer.wrap(express.Router, 'use', wrapRouterMethod)
72+
shimmer.wrap(express.Router, 'route', wrapRouterMethod)
73+
74+
return express
75+
})
76+
77+
addHook({ name: 'express', versions: ['>=5.0.0'] }, express => {
78+
shimmer.wrap(express.Router.prototype, 'use', wrapRouterMethod)
79+
shimmer.wrap(express.Router.prototype, 'route', wrapRouterMethod)
80+
81+
return express
82+
})
83+
7284
const queryParserReadCh = channel('datadog:query:read:finish')
7385

7486
function publishQueryParsedAndNext (req, res, next) {
@@ -88,7 +100,7 @@ function publishQueryParsedAndNext (req, res, next) {
88100

89101
addHook({
90102
name: 'express',
91-
versions: ['>=4'],
103+
versions: ['4'],
92104
file: 'lib/middleware/query.js'
93105
}, query => {
94106
return shimmer.wrapFunction(query, query => function () {
@@ -129,7 +141,29 @@ addHook({ name: 'express', versions: ['>=4.0.0 <4.3.0'] }, express => {
129141
return express
130142
})
131143

132-
addHook({ name: 'express', versions: ['>=4.3.0'] }, express => {
144+
addHook({ name: 'express', versions: ['>=4.3.0 <5.0.0'] }, express => {
133145
shimmer.wrap(express.Router, 'process_params', wrapProcessParamsMethod(2))
134146
return express
135147
})
148+
149+
const queryReadCh = channel('datadog:express:query:finish')
150+
151+
addHook({ name: 'express', file: ['lib/request.js'], versions: ['>=5.0.0'] }, request => {
152+
const requestDescriptor = Object.getOwnPropertyDescriptor(request, 'query')
153+
154+
shimmer.wrap(requestDescriptor, 'get', function (originalGet) {
155+
return function wrappedGet () {
156+
const query = originalGet.apply(this, arguments)
157+
158+
if (queryReadCh.hasSubscribers && query) {
159+
queryReadCh.publish({ query })
160+
}
161+
162+
return query
163+
}
164+
})
165+
166+
Object.defineProperty(request, 'query', requestDescriptor)
167+
168+
return request
169+
})

Diff for: packages/datadog-instrumentations/src/helpers/hooks.js

-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ module.exports = {
111111
protobufjs: () => require('../protobufjs'),
112112
pug: () => require('../pug'),
113113
q: () => require('../q'),
114-
qs: () => require('../qs'),
115114
redis: () => require('../redis'),
116115
restify: () => require('../restify'),
117116
rhea: () => require('../rhea'),

Diff for: packages/datadog-instrumentations/src/qs.js

-24
This file was deleted.

Diff for: packages/datadog-instrumentations/src/router.js

+97-1
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,107 @@ function createWrapRouterMethod (name) {
169169

170170
const wrapRouterMethod = createWrapRouterMethod('router')
171171

172-
addHook({ name: 'router', versions: ['>=1'] }, Router => {
172+
addHook({ name: 'router', versions: ['>=1 <2'] }, Router => {
173173
shimmer.wrap(Router.prototype, 'use', wrapRouterMethod)
174174
shimmer.wrap(Router.prototype, 'route', wrapRouterMethod)
175175

176176
return Router
177177
})
178178

179+
const queryParserReadCh = channel('datadog:query:read:finish')
180+
181+
addHook({ name: 'router', versions: ['>=2'] }, Router => {
182+
const WrappedRouter = shimmer.wrapFunction(Router, function (originalRouter) {
183+
return function wrappedMethod () {
184+
const router = originalRouter.apply(this, arguments)
185+
186+
shimmer.wrap(router, 'handle', function wrapHandle (originalHandle) {
187+
return function wrappedHandle (req, res, next) {
188+
const abortController = new AbortController()
189+
190+
if (queryParserReadCh.hasSubscribers && req) {
191+
queryParserReadCh.publish({ req, res, query: req.query, abortController })
192+
193+
if (abortController.signal.aborted) return
194+
}
195+
196+
return originalHandle.apply(this, arguments)
197+
}
198+
})
199+
200+
return router
201+
}
202+
})
203+
204+
shimmer.wrap(WrappedRouter.prototype, 'use', wrapRouterMethod)
205+
shimmer.wrap(WrappedRouter.prototype, 'route', wrapRouterMethod)
206+
207+
return WrappedRouter
208+
})
209+
210+
const routerParamStartCh = channel('datadog:router:param:start')
211+
const visitedParams = new WeakSet()
212+
213+
function wrapHandleRequest (original) {
214+
return function wrappedHandleRequest (req, res, next) {
215+
if (routerParamStartCh.hasSubscribers && Object.keys(req.params).length && !visitedParams.has(req.params)) {
216+
visitedParams.add(req.params)
217+
218+
const abortController = new AbortController()
219+
220+
routerParamStartCh.publish({
221+
req,
222+
res,
223+
params: req?.params,
224+
abortController
225+
})
226+
227+
if (abortController.signal.aborted) return
228+
}
229+
230+
return original.apply(this, arguments)
231+
}
232+
}
233+
234+
addHook({
235+
name: 'router', file: 'lib/layer.js', versions: ['>=2']
236+
}, Layer => {
237+
shimmer.wrap(Layer.prototype, 'handleRequest', wrapHandleRequest)
238+
return Layer
239+
})
240+
241+
function wrapParam (original) {
242+
return function wrappedProcessParams () {
243+
arguments[1] = shimmer.wrapFunction(arguments[1], (originalFn) => {
244+
return function wrappedFn (req, res) {
245+
if (routerParamStartCh.hasSubscribers && Object.keys(req.params).length && !visitedParams.has(req.params)) {
246+
visitedParams.add(req.params)
247+
248+
const abortController = new AbortController()
249+
250+
routerParamStartCh.publish({
251+
req,
252+
res,
253+
params: req?.params,
254+
abortController
255+
})
256+
257+
if (abortController.signal.aborted) return
258+
}
259+
260+
return originalFn.apply(this, arguments)
261+
}
262+
})
263+
264+
return original.apply(this, arguments)
265+
}
266+
}
267+
268+
addHook({
269+
name: 'router', versions: ['>=2']
270+
}, router => {
271+
shimmer.wrap(router.prototype, 'param', wrapParam)
272+
return router
273+
})
274+
179275
module.exports = { createWrapRouterMethod }

Diff for: packages/datadog-instrumentations/test/express.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ withVersions('express', 'express', version => {
1414
})
1515

1616
before((done) => {
17-
const express = require('../../../versions/express').get()
17+
const express = require(`../../../versions/express@${version}`).get()
1818
const app = express()
1919
app.get('/', (req, res) => {
2020
requestBody()

0 commit comments

Comments
 (0)