dd-trace 5.0.0-pre-cd5fbdb → 5.0.0-pre-4c05491
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ext/tags.d.ts +1 -0
- package/ext/tags.js +1 -0
- package/index.d.ts +4 -4
- package/package.json +6 -5
- package/packages/datadog-instrumentations/src/body-parser.js +2 -2
- package/packages/datadog-instrumentations/src/cookie-parser.js +37 -0
- package/packages/datadog-instrumentations/src/express.js +1 -1
- package/packages/datadog-instrumentations/src/graphql.js +5 -4
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/http/server.js +1 -1
- package/packages/datadog-instrumentations/src/mysql.js +39 -1
- package/packages/datadog-instrumentations/src/next.js +22 -80
- package/packages/datadog-instrumentations/src/pg.js +14 -15
- package/packages/datadog-instrumentations/src/playwright.js +15 -3
- package/packages/datadog-plugin-graphql/src/resolve.js +27 -2
- package/packages/datadog-plugin-next/src/index.js +14 -5
- package/packages/dd-trace/src/appsec/addresses.js +1 -0
- package/packages/dd-trace/src/appsec/channels.js +2 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/ldap-injection-analyzer.js +7 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +28 -32
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +19 -1
- package/packages/dd-trace/src/appsec/iast/path-line.js +1 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +48 -5
- package/packages/dd-trace/src/appsec/index.js +42 -7
- package/packages/dd-trace/src/appsec/recommended.json +655 -31
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +2 -0
- package/packages/dd-trace/src/appsec/reporter.js +26 -0
- package/packages/dd-trace/src/appsec/telemetry.js +132 -0
- package/packages/dd-trace/src/appsec/waf/index.js +1 -1
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +13 -5
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +12 -14
- package/packages/dd-trace/src/datastreams/processor.js +6 -2
- package/packages/dd-trace/src/dogstatsd.js +45 -5
- package/packages/dd-trace/src/format.js +6 -1
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/tracing.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/wall.js +14 -6
- package/packages/dd-trace/src/proxy.js +1 -11
- package/packages/dd-trace/src/runtime_metrics.js +1 -32
- package/packages/dd-trace/src/telemetry/index.js +10 -1
- package/packages/dd-trace/src/telemetry/metrics.js +0 -5
- package/packages/dd-trace/src/util.js +1 -1
package/ext/tags.d.ts
CHANGED
package/ext/tags.js
CHANGED
package/index.d.ts
CHANGED
|
@@ -649,7 +649,7 @@ export declare interface DogStatsD {
|
|
|
649
649
|
* Increments a metric by the specified value, optionally specifying tags.
|
|
650
650
|
* @param {string} stat The dot-separated metric name.
|
|
651
651
|
* @param {number} value The amount to increment the stat by.
|
|
652
|
-
* @param {[tag:string]:string|number} tags Tags to pass along, such as `
|
|
652
|
+
* @param {[tag:string]:string|number} tags Tags to pass along, such as `{ foo: 'bar' }`. Values are combined with config.tags.
|
|
653
653
|
*/
|
|
654
654
|
increment(stat: string, value?: number, tags?: { [tag: string]: string|number }): void
|
|
655
655
|
|
|
@@ -657,7 +657,7 @@ export declare interface DogStatsD {
|
|
|
657
657
|
* Decrements a metric by the specified value, optionally specifying tags.
|
|
658
658
|
* @param {string} stat The dot-separated metric name.
|
|
659
659
|
* @param {number} value The amount to decrement the stat by.
|
|
660
|
-
* @param {[tag:string]:string|number} tags Tags to pass along, such as `
|
|
660
|
+
* @param {[tag:string]:string|number} tags Tags to pass along, such as `{ foo: 'bar' }`. Values are combined with config.tags.
|
|
661
661
|
*/
|
|
662
662
|
decrement(stat: string, value?: number, tags?: { [tag: string]: string|number }): void
|
|
663
663
|
|
|
@@ -665,7 +665,7 @@ export declare interface DogStatsD {
|
|
|
665
665
|
* Sets a distribution value, optionally specifying tags.
|
|
666
666
|
* @param {string} stat The dot-separated metric name.
|
|
667
667
|
* @param {number} value The amount to increment the stat by.
|
|
668
|
-
* @param {[tag:string]:string|number} tags Tags to pass along, such as `
|
|
668
|
+
* @param {[tag:string]:string|number} tags Tags to pass along, such as `{ foo: 'bar' }`. Values are combined with config.tags.
|
|
669
669
|
*/
|
|
670
670
|
distribution(stat: string, value?: number, tags?: { [tag: string]: string|number }): void
|
|
671
671
|
|
|
@@ -673,7 +673,7 @@ export declare interface DogStatsD {
|
|
|
673
673
|
* Sets a gauge value, optionally specifying tags.
|
|
674
674
|
* @param {string} stat The dot-separated metric name.
|
|
675
675
|
* @param {number} value The amount to increment the stat by.
|
|
676
|
-
* @param {[tag:string]:string|number} tags Tags to pass along, such as `
|
|
676
|
+
* @param {[tag:string]:string|number} tags Tags to pass along, such as `{ foo: 'bar' }`. Values are combined with config.tags.
|
|
677
677
|
*/
|
|
678
678
|
gauge(stat: string, value?: number, tags?: { [tag: string]: string|number }): void
|
|
679
679
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.0.0-pre-
|
|
3
|
+
"version": "5.0.0-pre-4c05491",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"test:appsec": "mocha --colors --exit -r \"packages/dd-trace/test/setup/mocha.js\" --exclude \"packages/dd-trace/test/appsec/**/*.plugin.spec.js\" \"packages/dd-trace/test/appsec/**/*.spec.js\"",
|
|
19
19
|
"test:appsec:ci": "nyc --no-clean --include \"packages/dd-trace/src/appsec/**/*.js\" --exclude \"packages/dd-trace/test/appsec/**/*.plugin.spec.js\" -- npm run test:appsec",
|
|
20
20
|
"test:appsec:plugins": "mocha --colors --exit -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/dd-trace/test/appsec/**/*.@($(echo $PLUGINS)).plugin.spec.js\"",
|
|
21
|
-
"test:appsec:plugins:ci": "yarn services && nyc --no-clean --include \"packages/dd-trace/
|
|
21
|
+
"test:appsec:plugins:ci": "yarn services && nyc --no-clean --include \"packages/dd-trace/src/appsec/**/*.js\" -- npm run test:appsec:plugins",
|
|
22
22
|
"test:trace:core": "tap packages/dd-trace/test/*.spec.js \"packages/dd-trace/test/{ci-visibility,encode,exporters,opentelemetry,opentracing,plugins,service-naming,telemetry}/**/*.spec.js\"",
|
|
23
23
|
"test:trace:core:ci": "npm run test:trace:core -- --coverage --nyc-arg=--include=\"packages/dd-trace/src/**/*.js\"",
|
|
24
24
|
"test:instrumentations": "mocha --colors -r 'packages/dd-trace/test/setup/mocha.js' 'packages/datadog-instrumentations/test/**/*.spec.js'",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"test:integration:playwright": "mocha --colors --timeout 30000 \"integration-tests/playwright/*.spec.js\"",
|
|
39
39
|
"test:integration:serverless": "mocha --colors --timeout 30000 \"integration-tests/serverless/*.spec.js\"",
|
|
40
40
|
"test:integration:plugins": "mocha --colors --timeout 30000 \"packages/datadog-plugin-*/test/integration-test/*.spec.js\"",
|
|
41
|
+
"test:unit:plugins": "mocha --colors --exit -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/datadog-instrumentations/test/@($(echo $PLUGINS)).spec.js\" \"packages/datadog-plugin-@($(echo $PLUGINS))/test/**/*.spec.js\" --exclude \"packages/datadog-plugin-@($(echo $PLUGINS))/test/integration-test/**/*.spec.js\"",
|
|
41
42
|
"test:shimmer": "mocha --colors 'packages/datadog-shimmer/test/**/*.spec.js'",
|
|
42
43
|
"test:shimmer:ci": "nyc --no-clean --include 'packages/datadog-shimmer/src/**/*.js' -- npm run test:shimmer",
|
|
43
44
|
"leak:core": "node ./scripts/install_plugin_modules && (cd packages/memwatch && yarn) && NODE_PATH=./packages/memwatch/node_modules node --no-warnings ./node_modules/.bin/tape 'packages/dd-trace/test/leak/**/*.js'",
|
|
@@ -58,7 +59,7 @@
|
|
|
58
59
|
"apm"
|
|
59
60
|
],
|
|
60
61
|
"author": "Datadog Inc. <info@datadoghq.com>",
|
|
61
|
-
"license": "BSD-3-Clause",
|
|
62
|
+
"license": "(Apache-2.0 OR BSD-3-Clause)",
|
|
62
63
|
"bugs": {
|
|
63
64
|
"url": "https://github.com/DataDog/dd-trace-js/issues"
|
|
64
65
|
},
|
|
@@ -67,8 +68,8 @@
|
|
|
67
68
|
"node": ">=16"
|
|
68
69
|
},
|
|
69
70
|
"dependencies": {
|
|
70
|
-
"@datadog/native-appsec": "^
|
|
71
|
-
"@datadog/native-iast-rewriter": "2.
|
|
71
|
+
"@datadog/native-appsec": "^4.0.0",
|
|
72
|
+
"@datadog/native-iast-rewriter": "2.1.3",
|
|
72
73
|
"@datadog/native-iast-taint-tracking": "1.5.0",
|
|
73
74
|
"@datadog/native-metrics": "^2.0.0",
|
|
74
75
|
"@datadog/pprof": "3.2.0",
|
|
@@ -16,7 +16,7 @@ function publishRequestBodyAndNext (req, res, next) {
|
|
|
16
16
|
if (abortController.signal.aborted) return
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
next.apply(this, arguments)
|
|
19
|
+
return next.apply(this, arguments)
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -27,6 +27,6 @@ addHook({
|
|
|
27
27
|
}, read => {
|
|
28
28
|
return shimmer.wrap(read, function (req, res, next) {
|
|
29
29
|
arguments[2] = publishRequestBodyAndNext(req, res, next)
|
|
30
|
-
read.apply(this, arguments)
|
|
30
|
+
return read.apply(this, arguments)
|
|
31
31
|
})
|
|
32
32
|
})
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { AbortController } = require('node-abort-controller') // AbortController is not available in node <15
|
|
4
|
+
const shimmer = require('../../datadog-shimmer')
|
|
5
|
+
const { channel, addHook } = require('./helpers/instrument')
|
|
6
|
+
|
|
7
|
+
const cookieParserReadCh = channel('datadog:cookie-parser:read:finish')
|
|
8
|
+
|
|
9
|
+
function publishRequestCookieAndNext (req, res, next) {
|
|
10
|
+
return function cookieParserWrapper () {
|
|
11
|
+
if (cookieParserReadCh.hasSubscribers && req) {
|
|
12
|
+
const abortController = new AbortController()
|
|
13
|
+
|
|
14
|
+
const mergedCookies = Object.assign({}, req.cookies, req.signedCookies)
|
|
15
|
+
|
|
16
|
+
cookieParserReadCh.publish({ req, res, abortController, cookies: mergedCookies })
|
|
17
|
+
|
|
18
|
+
if (abortController.signal.aborted) return
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return next.apply(this, arguments)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
addHook({
|
|
26
|
+
name: 'cookie-parser',
|
|
27
|
+
versions: ['>=1.0.0']
|
|
28
|
+
}, cookieParser => {
|
|
29
|
+
return shimmer.wrap(cookieParser, function () {
|
|
30
|
+
const cookieMiddleware = cookieParser.apply(this, arguments)
|
|
31
|
+
|
|
32
|
+
return shimmer.wrap(cookieMiddleware, function (req, res, next) {
|
|
33
|
+
arguments[2] = publishRequestCookieAndNext(req, res, next)
|
|
34
|
+
return cookieMiddleware.apply(this, arguments)
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
})
|
|
@@ -188,7 +188,7 @@ function wrapExecute (execute) {
|
|
|
188
188
|
executeErrorCh.publish(error)
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
-
finishExecuteCh.publish({ res, args })
|
|
191
|
+
finishExecuteCh.publish({ res, args, context })
|
|
192
192
|
})
|
|
193
193
|
})
|
|
194
194
|
}
|
|
@@ -205,7 +205,7 @@ function wrapResolve (resolve) {
|
|
|
205
205
|
|
|
206
206
|
if (!context) return resolve.apply(this, arguments)
|
|
207
207
|
|
|
208
|
-
const field = assertField(context, info)
|
|
208
|
+
const field = assertField(context, info, args)
|
|
209
209
|
|
|
210
210
|
return callInAsyncScope(resolve, field.asyncResource, this, arguments, (err) => {
|
|
211
211
|
updateFieldCh.publish({ field, info, err })
|
|
@@ -250,7 +250,7 @@ function pathToArray (path) {
|
|
|
250
250
|
return flattened.reverse()
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
-
function assertField (context, info) {
|
|
253
|
+
function assertField (context, info, args) {
|
|
254
254
|
const pathInfo = info && info.path
|
|
255
255
|
|
|
256
256
|
const path = pathToArray(pathInfo)
|
|
@@ -272,7 +272,8 @@ function assertField (context, info) {
|
|
|
272
272
|
childResource.runInAsyncScope(() => {
|
|
273
273
|
startResolveCh.publish({
|
|
274
274
|
info,
|
|
275
|
-
context
|
|
275
|
+
context,
|
|
276
|
+
args
|
|
276
277
|
})
|
|
277
278
|
})
|
|
278
279
|
|
|
@@ -30,6 +30,7 @@ module.exports = {
|
|
|
30
30
|
'node:child_process': () => require('../child-process'),
|
|
31
31
|
'connect': () => require('../connect'),
|
|
32
32
|
'cookie': () => require('../cookie'),
|
|
33
|
+
'cookie-parser': () => require('../cookie-parser'),
|
|
33
34
|
'couchbase': () => require('../couchbase'),
|
|
34
35
|
'crypto': () => require('../crypto'),
|
|
35
36
|
'cypress': () => require('../cypress'),
|
|
@@ -81,6 +82,7 @@ module.exports = {
|
|
|
81
82
|
'pg': () => require('../pg'),
|
|
82
83
|
'pino': () => require('../pino'),
|
|
83
84
|
'pino-pretty': () => require('../pino'),
|
|
85
|
+
'playwright': () => require('../playwright'),
|
|
84
86
|
'promise-js': () => require('../promise-js'),
|
|
85
87
|
'promise': () => require('../promise'),
|
|
86
88
|
'q': () => require('../q'),
|
|
@@ -17,7 +17,7 @@ addHook({ name: 'mysql', file: 'lib/Connection.js', versions: ['>=2'] }, Connect
|
|
|
17
17
|
return query.apply(this, arguments)
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
const sql = arguments[0].sql
|
|
20
|
+
const sql = arguments[0].sql || arguments[0]
|
|
21
21
|
const conf = this.config
|
|
22
22
|
const payload = { sql, conf }
|
|
23
23
|
|
|
@@ -66,9 +66,47 @@ addHook({ name: 'mysql', file: 'lib/Connection.js', versions: ['>=2'] }, Connect
|
|
|
66
66
|
})
|
|
67
67
|
|
|
68
68
|
addHook({ name: 'mysql', file: 'lib/Pool.js', versions: ['>=2'] }, Pool => {
|
|
69
|
+
const startPoolQueryCh = channel('datadog:mysql:pool:query:start')
|
|
70
|
+
const finishPoolQueryCh = channel('datadog:mysql:pool:query:finish')
|
|
71
|
+
|
|
69
72
|
shimmer.wrap(Pool.prototype, 'getConnection', getConnection => function (cb) {
|
|
70
73
|
arguments[0] = AsyncResource.bind(cb)
|
|
71
74
|
return getConnection.apply(this, arguments)
|
|
72
75
|
})
|
|
76
|
+
|
|
77
|
+
shimmer.wrap(Pool.prototype, 'query', query => function () {
|
|
78
|
+
if (!startPoolQueryCh.hasSubscribers) {
|
|
79
|
+
return query.apply(this, arguments)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
83
|
+
|
|
84
|
+
const sql = arguments[0].sql || arguments[0]
|
|
85
|
+
|
|
86
|
+
return asyncResource.runInAsyncScope(() => {
|
|
87
|
+
startPoolQueryCh.publish({ sql })
|
|
88
|
+
|
|
89
|
+
const finish = asyncResource.bind(function () {
|
|
90
|
+
finishPoolQueryCh.publish()
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
const cb = arguments[arguments.length - 1]
|
|
94
|
+
if (typeof cb === 'function') {
|
|
95
|
+
arguments[arguments.length - 1] = shimmer.wrap(cb, function () {
|
|
96
|
+
finish()
|
|
97
|
+
return cb.apply(this, arguments)
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const retval = query.apply(this, arguments)
|
|
102
|
+
|
|
103
|
+
if (retval && retval.then) {
|
|
104
|
+
retval.then(finish).catch(finish)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return retval
|
|
108
|
+
})
|
|
109
|
+
})
|
|
110
|
+
|
|
73
111
|
return Pool
|
|
74
112
|
})
|
|
@@ -12,7 +12,6 @@ const errorChannel = channel('apm:next:request:error')
|
|
|
12
12
|
const pageLoadChannel = channel('apm:next:page:load')
|
|
13
13
|
|
|
14
14
|
const requests = new WeakSet()
|
|
15
|
-
const requestToNextjsPagePath = new WeakMap()
|
|
16
15
|
|
|
17
16
|
function wrapHandleRequest (handleRequest) {
|
|
18
17
|
return function (req, res, pathname, query) {
|
|
@@ -29,9 +28,9 @@ function wrapHandleApiRequest (handleApiRequest) {
|
|
|
29
28
|
if (!handled) return handled
|
|
30
29
|
|
|
31
30
|
return this.hasPage(pathname).then(pageFound => {
|
|
32
|
-
const
|
|
31
|
+
const pageData = pageFound ? { page: pathname } : getPageFromPath(pathname, this.dynamicRoutes)
|
|
33
32
|
|
|
34
|
-
pageLoadChannel.publish(
|
|
33
|
+
pageLoadChannel.publish(pageData)
|
|
35
34
|
|
|
36
35
|
return handled
|
|
37
36
|
})
|
|
@@ -84,15 +83,19 @@ function wrapFindPageComponents (findPageComponents) {
|
|
|
84
83
|
const result = findPageComponents.apply(this, arguments)
|
|
85
84
|
|
|
86
85
|
if (result) {
|
|
87
|
-
pageLoadChannel.publish(
|
|
86
|
+
pageLoadChannel.publish(getPagePath(pathname))
|
|
88
87
|
}
|
|
89
88
|
|
|
90
89
|
return result
|
|
91
90
|
}
|
|
92
91
|
}
|
|
93
92
|
|
|
94
|
-
function getPagePath (
|
|
95
|
-
|
|
93
|
+
function getPagePath (maybePage) {
|
|
94
|
+
if (typeof maybePage !== 'object') return { page: maybePage }
|
|
95
|
+
|
|
96
|
+
const isAppPath = maybePage.isAppPath
|
|
97
|
+
const page = maybePage.pathname || maybePage.page
|
|
98
|
+
return { page, isAppPath }
|
|
96
99
|
}
|
|
97
100
|
|
|
98
101
|
function getPageFromPath (page, dynamicRoutes = []) {
|
|
@@ -133,57 +136,16 @@ function instrument (req, res, handler) {
|
|
|
133
136
|
})
|
|
134
137
|
}
|
|
135
138
|
|
|
136
|
-
function
|
|
137
|
-
return function (
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function wrapInitialize (initialize) {
|
|
144
|
-
return async function () {
|
|
145
|
-
const result = await initialize.apply(this, arguments)
|
|
146
|
-
if (Array.isArray(result)) {
|
|
147
|
-
const requestHandler = result[0]
|
|
148
|
-
result[0] = shimmer.wrap(requestHandler, wrapRequestHandler(requestHandler))
|
|
149
|
-
}
|
|
150
|
-
return result
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function wrapRequestHandler (requestHandler) {
|
|
155
|
-
return function (req, res) {
|
|
156
|
-
return instrument(req, res, async () => {
|
|
157
|
-
const result = await requestHandler.apply(this, arguments) // apply here first to get page path association
|
|
158
|
-
|
|
159
|
-
const page = requestToNextjsPagePath.get(req)
|
|
160
|
-
if (page && pageLoadChannel.hasSubscribers) pageLoadChannel.publish({ page })
|
|
139
|
+
function wrapServeStatic (serveStatic) {
|
|
140
|
+
return function (req, res, path) {
|
|
141
|
+
return instrument(req, res, () => {
|
|
142
|
+
if (pageLoadChannel.hasSubscribers && path) pageLoadChannel.publish({ page: path })
|
|
161
143
|
|
|
162
|
-
return
|
|
144
|
+
return serveStatic.apply(this, arguments)
|
|
163
145
|
})
|
|
164
146
|
}
|
|
165
147
|
}
|
|
166
148
|
|
|
167
|
-
// these two functions make sure we get path groups for routes in standalone,
|
|
168
|
-
// as it doesn't route through `next-server`/`base-server`
|
|
169
|
-
function wrapGetResolveRoutes (getResolveRoutes) {
|
|
170
|
-
return function () {
|
|
171
|
-
const result = getResolveRoutes.apply(this, arguments)
|
|
172
|
-
return shimmer.wrap(result, wrapResolveRoutes(result))
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
function wrapResolveRoutes (resolveRoutes) {
|
|
177
|
-
return async function (req) {
|
|
178
|
-
const result = await resolveRoutes.apply(this, arguments)
|
|
179
|
-
if (result && result.matchedOutput) {
|
|
180
|
-
const path = result.matchedOutput.itemPath
|
|
181
|
-
requestToNextjsPagePath.set(req, path)
|
|
182
|
-
}
|
|
183
|
-
return result
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
149
|
function finish (ctx, result, err) {
|
|
188
150
|
if (err) {
|
|
189
151
|
ctx.error = err
|
|
@@ -201,25 +163,21 @@ function finish (ctx, result, err) {
|
|
|
201
163
|
|
|
202
164
|
addHook({
|
|
203
165
|
name: 'next',
|
|
204
|
-
versions: ['>=
|
|
205
|
-
file: 'dist/server/
|
|
206
|
-
},
|
|
166
|
+
versions: ['>=11.1'],
|
|
167
|
+
file: 'dist/server/serve-static.js'
|
|
168
|
+
}, serveStatic => shimmer.wrap(serveStatic, 'serveStatic', wrapServeStatic))
|
|
207
169
|
|
|
208
170
|
addHook({
|
|
209
171
|
name: 'next',
|
|
210
|
-
versions: ['
|
|
211
|
-
file: 'dist/server/
|
|
212
|
-
},
|
|
213
|
-
|
|
214
|
-
addHook({
|
|
215
|
-
name: 'next',
|
|
216
|
-
versions: ['>=13.4.15'],
|
|
217
|
-
file: 'dist/server/lib/router-server.js'
|
|
218
|
-
}, routerServer => shimmer.wrap(routerServer, 'initialize', wrapInitialize))
|
|
172
|
+
versions: DD_MAJOR >= 4 ? ['>=10.2 <11.1'] : ['>=9.5 <11.1'],
|
|
173
|
+
file: 'dist/next-server/server/serve-static.js'
|
|
174
|
+
}, serveStatic => shimmer.wrap(serveStatic, 'serveStatic', wrapServeStatic))
|
|
219
175
|
|
|
220
176
|
addHook({ name: 'next', versions: ['>=13.2'], file: 'dist/server/next-server.js' }, nextServer => {
|
|
221
177
|
const Server = nextServer.default
|
|
222
178
|
|
|
179
|
+
shimmer.wrap(Server.prototype, 'handleRequest', wrapHandleRequest)
|
|
180
|
+
shimmer.wrap(Server.prototype, 'handleApiRequest', wrapHandleApiRequestWithMatch)
|
|
223
181
|
shimmer.wrap(Server.prototype, 'renderToResponse', wrapRenderToResponse)
|
|
224
182
|
shimmer.wrap(Server.prototype, 'renderErrorToResponse', wrapRenderErrorToResponse)
|
|
225
183
|
shimmer.wrap(Server.prototype, 'findPageComponents', wrapFindPageComponents)
|
|
@@ -227,22 +185,6 @@ addHook({ name: 'next', versions: ['>=13.2'], file: 'dist/server/next-server.js'
|
|
|
227
185
|
return nextServer
|
|
228
186
|
})
|
|
229
187
|
|
|
230
|
-
// these functions wrapped in all versions above 13.2 except:
|
|
231
|
-
// 13.4.13 due to tests failing when these functions are wrapped
|
|
232
|
-
// 13.4.14 due to it not being in the NPM registry/officially released
|
|
233
|
-
addHook({
|
|
234
|
-
name: 'next',
|
|
235
|
-
versions: ['>=13.2 <13.4.13', '>=13.4.15'],
|
|
236
|
-
file: 'dist/server/next-server.js'
|
|
237
|
-
}, nextServer => {
|
|
238
|
-
const Server = nextServer.default
|
|
239
|
-
|
|
240
|
-
shimmer.wrap(Server.prototype, 'handleRequest', wrapHandleRequest)
|
|
241
|
-
shimmer.wrap(Server.prototype, 'handleApiRequest', wrapHandleApiRequestWithMatch)
|
|
242
|
-
|
|
243
|
-
return nextServer
|
|
244
|
-
})
|
|
245
|
-
|
|
246
188
|
addHook({ name: 'next', versions: ['>=11.1 <13.2'], file: 'dist/server/next-server.js' }, nextServer => {
|
|
247
189
|
const Server = nextServer.default
|
|
248
190
|
|
|
@@ -39,28 +39,27 @@ function wrapQuery (query) {
|
|
|
39
39
|
? arguments[0]
|
|
40
40
|
: { text: arguments[0] }
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
42
|
+
const textProp = Object.getOwnPropertyDescriptor(pgQuery, 'text')
|
|
43
|
+
|
|
44
|
+
// Only alter `text` property if safe to do so.
|
|
45
|
+
if (!textProp || textProp.configurable) {
|
|
46
|
+
const originalText = pgQuery.text
|
|
47
|
+
|
|
48
|
+
Object.defineProperty(pgQuery, 'text', {
|
|
49
|
+
get () {
|
|
50
|
+
return this?.__ddInjectableQuery || originalText
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
53
|
}
|
|
54
|
-
Object.setPrototypeOf(newQuery, pgQuery)
|
|
55
54
|
|
|
56
55
|
return asyncResource.runInAsyncScope(() => {
|
|
57
56
|
startCh.publish({
|
|
58
57
|
params: this.connectionParameters,
|
|
59
|
-
query:
|
|
58
|
+
query: pgQuery,
|
|
60
59
|
processId
|
|
61
60
|
})
|
|
62
61
|
|
|
63
|
-
arguments[0] =
|
|
62
|
+
arguments[0] = pgQuery
|
|
64
63
|
|
|
65
64
|
const finish = asyncResource.bind(function (error) {
|
|
66
65
|
if (error) {
|
|
@@ -73,7 +72,7 @@ function wrapQuery (query) {
|
|
|
73
72
|
const queryQueue = this.queryQueue || this._queryQueue
|
|
74
73
|
const activeQuery = this.activeQuery || this._activeQuery
|
|
75
74
|
|
|
76
|
-
newQuery = queryQueue[queryQueue.length - 1] || activeQuery
|
|
75
|
+
const newQuery = queryQueue[queryQueue.length - 1] || activeQuery
|
|
77
76
|
|
|
78
77
|
if (!newQuery) {
|
|
79
78
|
return retval
|
|
@@ -254,7 +254,7 @@ addHook({
|
|
|
254
254
|
addHook({
|
|
255
255
|
name: '@playwright/test',
|
|
256
256
|
file: 'lib/dispatcher.js',
|
|
257
|
-
versions: ['>=1.18.0
|
|
257
|
+
versions: ['>=1.18.0 <1.30.0']
|
|
258
258
|
}, dispatcherHook)
|
|
259
259
|
|
|
260
260
|
addHook({
|
|
@@ -266,11 +266,23 @@ addHook({
|
|
|
266
266
|
addHook({
|
|
267
267
|
name: '@playwright/test',
|
|
268
268
|
file: 'lib/runner/dispatcher.js',
|
|
269
|
-
versions: ['>=1.31.0']
|
|
269
|
+
versions: ['>=1.31.0 <1.38.0']
|
|
270
270
|
}, (dispatcher) => dispatcherHookNew(dispatcher, dispatcherRunWrapperNew))
|
|
271
271
|
|
|
272
272
|
addHook({
|
|
273
273
|
name: '@playwright/test',
|
|
274
274
|
file: 'lib/runner/runner.js',
|
|
275
|
-
versions: ['>=1.31.0']
|
|
275
|
+
versions: ['>=1.31.0 <1.38.0']
|
|
276
276
|
}, runnerHook)
|
|
277
|
+
|
|
278
|
+
// From >=1.38.0
|
|
279
|
+
addHook({
|
|
280
|
+
name: 'playwright',
|
|
281
|
+
file: 'lib/runner/runner.js',
|
|
282
|
+
versions: ['>=1.38.0']
|
|
283
|
+
}, runnerHook)
|
|
284
|
+
addHook({
|
|
285
|
+
name: 'playwright',
|
|
286
|
+
file: 'lib/runner/dispatcher.js',
|
|
287
|
+
versions: ['>=1.38.0']
|
|
288
|
+
}, (dispatcher) => dispatcherHookNew(dispatcher, dispatcherRunWrapperNew))
|
|
@@ -8,13 +8,14 @@ class GraphQLResolvePlugin extends TracingPlugin {
|
|
|
8
8
|
static get id () { return 'graphql' }
|
|
9
9
|
static get operation () { return 'resolve' }
|
|
10
10
|
|
|
11
|
-
start ({ info, context }) {
|
|
11
|
+
start ({ info, context, args }) {
|
|
12
12
|
const path = getPath(info, this.config)
|
|
13
13
|
|
|
14
14
|
if (!shouldInstrument(this.config, path)) return
|
|
15
|
-
|
|
16
15
|
const computedPathString = path.join('.')
|
|
17
16
|
|
|
17
|
+
addResolver(context, info, args)
|
|
18
|
+
|
|
18
19
|
if (this.config.collapse) {
|
|
19
20
|
if (!context[collapsedPathSym]) {
|
|
20
21
|
context[collapsedPathSym] = {}
|
|
@@ -108,4 +109,28 @@ function withCollapse (responsePathAsArray) {
|
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
111
|
|
|
112
|
+
function addResolver (context, info, args) {
|
|
113
|
+
if (info.rootValue && !info.rootValue[info.fieldName]) {
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (!context.resolvers) {
|
|
118
|
+
context.resolvers = {}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const resolvers = context.resolvers
|
|
122
|
+
|
|
123
|
+
if (!resolvers[info.fieldName]) {
|
|
124
|
+
if (args && Object.keys(args).length) {
|
|
125
|
+
resolvers[info.fieldName] = [args]
|
|
126
|
+
} else {
|
|
127
|
+
resolvers[info.fieldName] = []
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
if (args && Object.keys(args).length) {
|
|
131
|
+
resolvers[info.fieldName].push(args)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
111
136
|
module.exports = GraphQLResolvePlugin
|
|
@@ -50,7 +50,6 @@ class NextPlugin extends ServerPlugin {
|
|
|
50
50
|
|
|
51
51
|
const span = store.span
|
|
52
52
|
const error = span.context()._tags['error']
|
|
53
|
-
const page = span.context()._tags['next.page']
|
|
54
53
|
|
|
55
54
|
if (!this.config.validateStatus(res.statusCode) && !error) {
|
|
56
55
|
span.setTag('error', true)
|
|
@@ -60,14 +59,12 @@ class NextPlugin extends ServerPlugin {
|
|
|
60
59
|
'http.status_code': res.statusCode
|
|
61
60
|
})
|
|
62
61
|
|
|
63
|
-
if (page) web.setRoute(req, page)
|
|
64
|
-
|
|
65
62
|
this.config.hooks.request(span, req, res)
|
|
66
63
|
|
|
67
64
|
span.finish()
|
|
68
65
|
}
|
|
69
66
|
|
|
70
|
-
pageLoad ({ page }) {
|
|
67
|
+
pageLoad ({ page, isAppPath }) {
|
|
71
68
|
const store = storage.getStore()
|
|
72
69
|
|
|
73
70
|
if (!store) return
|
|
@@ -77,15 +74,27 @@ class NextPlugin extends ServerPlugin {
|
|
|
77
74
|
|
|
78
75
|
// Only use error page names if there's not already a name
|
|
79
76
|
const current = span.context()._tags['next.page']
|
|
80
|
-
if (current &&
|
|
77
|
+
if (current && ['/404', '/500', '/_error', '/_not-found'].includes(page)) {
|
|
81
78
|
return
|
|
82
79
|
}
|
|
83
80
|
|
|
81
|
+
// remove ending /route or /page for appDir projects
|
|
82
|
+
if (isAppPath) page = page.substring(0, page.lastIndexOf('/'))
|
|
83
|
+
|
|
84
|
+
// This is for static files whose 'page' includes the whole file path
|
|
85
|
+
// For normal page matches, like /api/hello/[name] and a req.url like /api/hello/world,
|
|
86
|
+
// nothing should happen
|
|
87
|
+
// For page matches like /User/something/public/text.txt and req.url like /text.txt,
|
|
88
|
+
// it should disregard the extra absolute path Next.js sometimes sets
|
|
89
|
+
if (page.includes(req.url)) page = req.url
|
|
90
|
+
|
|
84
91
|
span.addTags({
|
|
85
92
|
[COMPONENT]: this.constructor.id,
|
|
86
93
|
'resource.name': `${req.method} ${page}`.trim(),
|
|
87
94
|
'next.page': page
|
|
88
95
|
})
|
|
96
|
+
|
|
97
|
+
web.setRoute(req, page)
|
|
89
98
|
}
|
|
90
99
|
|
|
91
100
|
configure (config) {
|
|
@@ -12,6 +12,7 @@ module.exports = {
|
|
|
12
12
|
HTTP_INCOMING_RESPONSE_CODE: 'server.response.status',
|
|
13
13
|
HTTP_INCOMING_RESPONSE_HEADERS: 'server.response.headers.no_cookies',
|
|
14
14
|
// TODO: 'server.response.trailers',
|
|
15
|
+
HTTP_INCOMING_GRAPHQL_RESOLVERS: 'graphql.server.all_resolvers',
|
|
15
16
|
|
|
16
17
|
HTTP_CLIENT_IP: 'http.client_ip',
|
|
17
18
|
|
|
@@ -5,6 +5,8 @@ const dc = require('../../../diagnostics_channel')
|
|
|
5
5
|
// TODO: use TBD naming convention
|
|
6
6
|
module.exports = {
|
|
7
7
|
bodyParser: dc.channel('datadog:body-parser:read:finish'),
|
|
8
|
+
cookieParser: dc.channel('datadog:cookie-parser:read:finish'),
|
|
9
|
+
graphqlFinishExecute: dc.channel('apm:graphql:execute:finish'),
|
|
8
10
|
incomingHttpRequestStart: dc.channel('dd-trace:incomingHttpRequestStart'),
|
|
9
11
|
incomingHttpRequestEnd: dc.channel('dd-trace:incomingHttpRequestEnd'),
|
|
10
12
|
passportVerify: dc.channel('datadog:passport:verify:finish'),
|