Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Express 5 Instrumentation #4913

Merged
merged 32 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
60266a8
update express to not wrap router methods if version is v5
wconti27 Nov 12, 2024
0bbc7df
update express v5 plugin, change failing tests to only run for <v5
wconti27 Nov 13, 2024
21513a9
change tests around
wconti27 Nov 13, 2024
d488f59
dont wrap params for now
wconti27 Nov 13, 2024
782752d
fix express 5 intrumentation
IlyasShabi Nov 18, 2024
bd9dd64
instrument path and query params and response
IlyasShabi Nov 20, 2024
d217138
skip uri tests
IlyasShabi Nov 20, 2024
cebb049
fix http tests
IlyasShabi Nov 21, 2024
1d6707b
fix express plugin tests
IlyasShabi Nov 21, 2024
d292bc2
router param instrumentation
IlyasShabi Nov 22, 2024
864324c
fix express tests and add req.query middleware
IlyasShabi Nov 22, 2024
4d71ea8
add custom middleware
IlyasShabi Nov 22, 2024
603c76d
fix router tests
IlyasShabi Nov 22, 2024
efa3f19
abort if response ended
IlyasShabi Nov 23, 2024
6abe086
instrument node querystring
IlyasShabi Nov 25, 2024
d342150
lint code
IlyasShabi Nov 25, 2024
b062e54
fix mongodb core and mongoose express version
IlyasShabi Nov 25, 2024
501c306
fix mongoose and express tests
IlyasShabi Nov 25, 2024
83ff4c8
escape express5 in testing express-mongo-sanitize
IlyasShabi Nov 25, 2024
9427caf
fix mongodb core tests
IlyasShabi Nov 25, 2024
ec07386
remove querystring instrumentation
IlyasShabi Nov 27, 2024
ef6a822
remove qs instrumentation
IlyasShabi Nov 27, 2024
cee9157
clean router handle instrumentation
IlyasShabi Nov 27, 2024
14bc0fb
add prefix matching test
IlyasShabi Nov 27, 2024
e99c180
fix mongoose tests
IlyasShabi Nov 27, 2024
e12f447
fix express versions
IlyasShabi Dec 3, 2024
1fe57b5
use weekSet to not process same params twice
IlyasShabi Dec 4, 2024
e12eb42
use arguments instead of explicit params
IlyasShabi Dec 4, 2024
7f71fc7
fix wrapped fn scope
IlyasShabi Dec 4, 2024
eff2153
fix wrap param shimmer
IlyasShabi Dec 4, 2024
d764b89
use named function
IlyasShabi Dec 4, 2024
5ef7c24
Merge branch 'master' into express5
simon-id Dec 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions packages/datadog-instrumentations/src/express.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ function wrapResponseRender (render) {

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

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

addHook({ name: 'express', versions: ['4'] }, express => {
shimmer.wrap(express.Router, 'use', wrapRouterMethod)
shimmer.wrap(express.Router, 'route', wrapRouterMethod)

return express
})

addHook({ name: 'express', versions: ['>=5.0.0'] }, express => {
shimmer.wrap(express.Router.prototype, 'use', wrapRouterMethod)
shimmer.wrap(express.Router.prototype, 'route', wrapRouterMethod)

return express
})

const queryParserReadCh = channel('datadog:query:read:finish')

function publishQueryParsedAndNext (req, res, next) {
Expand All @@ -88,7 +100,7 @@ function publishQueryParsedAndNext (req, res, next) {

addHook({
name: 'express',
versions: ['>=4'],
versions: ['4'],
file: 'lib/middleware/query.js'
}, query => {
return shimmer.wrapFunction(query, query => function () {
Expand Down Expand Up @@ -129,7 +141,29 @@ addHook({ name: 'express', versions: ['>=4.0.0 <4.3.0'] }, express => {
return express
})

addHook({ name: 'express', versions: ['>=4.3.0'] }, express => {
addHook({ name: 'express', versions: ['>=4.3.0 <5.0.0'] }, express => {
shimmer.wrap(express.Router, 'process_params', wrapProcessParamsMethod(2))
return express
})

const queryReadCh = channel('datadog:express:query:finish')

addHook({ name: 'express', file: ['lib/request.js'], versions: ['>=5.0.0'] }, request => {
const requestDescriptor = Object.getOwnPropertyDescriptor(request, 'query')

shimmer.wrap(requestDescriptor, 'get', function (originalGet) {
return function wrappedGet () {
const query = originalGet.apply(this, arguments)

if (queryReadCh.hasSubscribers && query) {
queryReadCh.publish({ query })
}

return query
}
})

Object.defineProperty(request, 'query', requestDescriptor)

return request
})
1 change: 0 additions & 1 deletion packages/datadog-instrumentations/src/helpers/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ module.exports = {
protobufjs: () => require('../protobufjs'),
pug: () => require('../pug'),
q: () => require('../q'),
qs: () => require('../qs'),
redis: () => require('../redis'),
restify: () => require('../restify'),
rhea: () => require('../rhea'),
Expand Down
24 changes: 0 additions & 24 deletions packages/datadog-instrumentations/src/qs.js

This file was deleted.

98 changes: 97 additions & 1 deletion packages/datadog-instrumentations/src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,107 @@ function createWrapRouterMethod (name) {

const wrapRouterMethod = createWrapRouterMethod('router')

addHook({ name: 'router', versions: ['>=1'] }, Router => {
addHook({ name: 'router', versions: ['>=1 <2'] }, Router => {
simon-id marked this conversation as resolved.
Show resolved Hide resolved
shimmer.wrap(Router.prototype, 'use', wrapRouterMethod)
shimmer.wrap(Router.prototype, 'route', wrapRouterMethod)

return Router
})

const queryParserReadCh = channel('datadog:query:read:finish')

addHook({ name: 'router', versions: ['>=2'] }, Router => {
const WrappedRouter = shimmer.wrapFunction(Router, function (originalRouter) {
return function wrappedMethod () {
const router = originalRouter.apply(this, arguments)

shimmer.wrap(router, 'handle', function wrapHandle (originalHandle) {
return function wrappedHandle (req, res, next) {
const abortController = new AbortController()

if (queryParserReadCh.hasSubscribers && req) {
queryParserReadCh.publish({ req, res, query: req.query, abortController })

if (abortController.signal.aborted) return
}

return originalHandle.apply(this, arguments)
}
})

return router
}
})

shimmer.wrap(WrappedRouter.prototype, 'use', wrapRouterMethod)
shimmer.wrap(WrappedRouter.prototype, 'route', wrapRouterMethod)

return WrappedRouter
})

const routerParamStartCh = channel('datadog:router:param:start')
const visitedParams = new WeakSet()

function wrapHandleRequest (original) {
return function wrappedHandleRequest (req, res, next) {
if (routerParamStartCh.hasSubscribers && Object.keys(req.params).length && !visitedParams.has(req.params)) {
visitedParams.add(req.params)

const abortController = new AbortController()

routerParamStartCh.publish({
req,
res,
params: req?.params,
abortController
})

if (abortController.signal.aborted) return
}

return original.apply(this, arguments)
}
}

addHook({
name: 'router', file: 'lib/layer.js', versions: ['>=2']
}, Layer => {
shimmer.wrap(Layer.prototype, 'handleRequest', wrapHandleRequest)
return Layer
})

function wrapParam (original) {
simon-id marked this conversation as resolved.
Show resolved Hide resolved
return function wrappedProcessParams () {
arguments[1] = shimmer.wrapFunction(arguments[1], (originalFn) => {
return function wrappedFn (req, res) {
if (routerParamStartCh.hasSubscribers && Object.keys(req.params).length && !visitedParams.has(req.params)) {
visitedParams.add(req.params)

const abortController = new AbortController()

routerParamStartCh.publish({
req,
res,
params: req?.params,
abortController
})

if (abortController.signal.aborted) return
}

return originalFn.apply(this, arguments)
}
})

return original.apply(this, arguments)
}
}

addHook({
name: 'router', versions: ['>=2']
}, router => {
shimmer.wrap(router.prototype, 'param', wrapParam)
return router
})

module.exports = { createWrapRouterMethod }
2 changes: 1 addition & 1 deletion packages/datadog-instrumentations/test/express.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ withVersions('express', 'express', version => {
})

before((done) => {
const express = require('../../../versions/express').get()
const express = require(`../../../versions/express@${version}`).get()
const app = express()
app.get('/', (req, res) => {
requestBody()
Expand Down
Loading
Loading