dd-trace 4.11.1 → 4.16.0
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/LICENSE-3rdparty.csv +1 -0
- package/README.md +4 -9
- package/ext/tags.d.ts +1 -0
- package/ext/tags.js +1 -0
- package/index.d.ts +44 -0
- package/package.json +9 -6
- package/packages/datadog-esbuild/index.js +57 -32
- 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/cucumber.js +30 -11
- package/packages/datadog-instrumentations/src/express.js +1 -1
- package/packages/datadog-instrumentations/src/graphql.js +10 -4
- package/packages/datadog-instrumentations/src/helpers/hooks.js +3 -0
- package/packages/datadog-instrumentations/src/http/server.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +22 -11
- package/packages/datadog-instrumentations/src/kafkajs.js +3 -4
- package/packages/datadog-instrumentations/src/mocha.js +33 -8
- package/packages/datadog-instrumentations/src/mysql.js +39 -1
- package/packages/datadog-instrumentations/src/next.js +47 -19
- package/packages/datadog-instrumentations/src/openai.js +1 -1
- package/packages/datadog-instrumentations/src/pg.js +60 -15
- package/packages/datadog-instrumentations/src/playwright.js +15 -3
- package/packages/datadog-plugin-cucumber/src/index.js +14 -2
- package/packages/datadog-plugin-cypress/src/plugin.js +49 -13
- package/packages/datadog-plugin-graphql/src/index.js +3 -3
- package/packages/datadog-plugin-graphql/src/resolve.js +27 -2
- package/packages/datadog-plugin-jest/src/index.js +10 -2
- package/packages/datadog-plugin-jest/src/util.js +10 -4
- package/packages/datadog-plugin-mocha/src/index.js +14 -2
- package/packages/datadog-plugin-mongodb-core/src/index.js +6 -2
- package/packages/datadog-plugin-mysql/src/index.js +2 -2
- package/packages/datadog-plugin-next/src/index.js +22 -5
- package/packages/datadog-plugin-pg/src/index.js +2 -2
- 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 +29 -18
- 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/operations.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +48 -5
- package/packages/dd-trace/src/appsec/iast/telemetry/index.js +14 -5
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +131 -10
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +0 -1
- 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/ci-visibility/intelligent-test-runner/get-itr-configuration.js +1 -14
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +1 -13
- package/packages/dd-trace/src/datastreams/processor.js +6 -2
- package/packages/dd-trace/src/dogstatsd.js +108 -8
- package/packages/dd-trace/src/exporters/agent/writer.js +9 -9
- package/packages/dd-trace/src/exporters/common/request.js +13 -4
- package/packages/dd-trace/src/format.js +6 -1
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +2 -2
- package/packages/dd-trace/src/opentracing/span.js +13 -13
- package/packages/dd-trace/src/opentracing/tracer.js +3 -5
- package/packages/dd-trace/src/plugin_manager.js +1 -2
- package/packages/dd-trace/src/plugins/ci_plugin.js +22 -1
- package/packages/dd-trace/src/plugins/database.js +14 -4
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/outbound.js +4 -3
- package/packages/dd-trace/src/plugins/tracing.js +1 -1
- package/packages/dd-trace/src/plugins/util/test.js +20 -3
- package/packages/dd-trace/src/profiling/config.js +3 -1
- package/packages/dd-trace/src/profiling/profilers/wall.js +31 -7
- package/packages/dd-trace/src/proxy.js +13 -2
- package/packages/dd-trace/src/ritm.js +10 -2
- package/packages/dd-trace/src/{metrics.js → runtime_metrics.js} +1 -32
- package/packages/dd-trace/src/telemetry/dependencies.js +15 -0
- package/packages/dd-trace/src/telemetry/index.js +21 -2
- package/packages/dd-trace/src/util.js +1 -1
|
@@ -39,10 +39,13 @@ const testErrCh = channel('ci:jest:test:err')
|
|
|
39
39
|
const skippableSuitesCh = channel('ci:jest:test-suite:skippable')
|
|
40
40
|
const jestItrConfigurationCh = channel('ci:jest:itr-configuration')
|
|
41
41
|
|
|
42
|
+
const itrSkippedSuitesCh = channel('ci:jest:itr:skipped-suites')
|
|
43
|
+
|
|
42
44
|
let skippableSuites = []
|
|
43
45
|
let isCodeCoverageEnabled = false
|
|
44
46
|
let isSuitesSkippingEnabled = false
|
|
45
47
|
let isSuitesSkipped = false
|
|
48
|
+
let numSkippedSuites = 0
|
|
46
49
|
|
|
47
50
|
const sessionAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
48
51
|
|
|
@@ -102,7 +105,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
102
105
|
await super.handleTestEvent(event, state)
|
|
103
106
|
}
|
|
104
107
|
|
|
105
|
-
const setNameToParams = (name, params) => { this.nameToParams[name] = params }
|
|
108
|
+
const setNameToParams = (name, params) => { this.nameToParams[name] = [...params] }
|
|
106
109
|
|
|
107
110
|
if (event.name === 'setup') {
|
|
108
111
|
if (this.global.test) {
|
|
@@ -191,7 +194,7 @@ addHook({
|
|
|
191
194
|
addHook({
|
|
192
195
|
name: '@jest/test-sequencer',
|
|
193
196
|
versions: ['>=24.8.0']
|
|
194
|
-
}, sequencerPackage => {
|
|
197
|
+
}, (sequencerPackage, frameworkVersion) => {
|
|
195
198
|
shimmer.wrap(sequencerPackage.default.prototype, 'shard', shard => function () {
|
|
196
199
|
const shardedTests = shard.apply(this, arguments)
|
|
197
200
|
|
|
@@ -202,13 +205,15 @@ addHook({
|
|
|
202
205
|
const [test] = shardedTests
|
|
203
206
|
const rootDir = test && test.context && test.context.config && test.context.config.rootDir
|
|
204
207
|
|
|
205
|
-
const
|
|
208
|
+
const { skippedSuites, suitesToRun } = getJestSuitesToRun(skippableSuites, shardedTests, rootDir || process.cwd())
|
|
206
209
|
|
|
207
|
-
isSuitesSkipped =
|
|
210
|
+
isSuitesSkipped = suitesToRun.length !== shardedTests.length
|
|
211
|
+
numSkippedSuites = skippedSuites.length
|
|
208
212
|
|
|
209
|
-
|
|
213
|
+
itrSkippedSuitesCh.publish({ skippedSuites, frameworkVersion })
|
|
210
214
|
|
|
211
|
-
|
|
215
|
+
skippableSuites = []
|
|
216
|
+
return suitesToRun
|
|
212
217
|
})
|
|
213
218
|
return sequencerPackage
|
|
214
219
|
})
|
|
@@ -279,10 +284,13 @@ function cliWrapper (cli, jestVersion) {
|
|
|
279
284
|
isSuitesSkipped,
|
|
280
285
|
isSuitesSkippingEnabled,
|
|
281
286
|
isCodeCoverageEnabled,
|
|
282
|
-
testCodeCoverageLinesTotal
|
|
287
|
+
testCodeCoverageLinesTotal,
|
|
288
|
+
numSkippedSuites
|
|
283
289
|
})
|
|
284
290
|
})
|
|
285
291
|
|
|
292
|
+
numSkippedSuites = 0
|
|
293
|
+
|
|
286
294
|
return result
|
|
287
295
|
})
|
|
288
296
|
|
|
@@ -468,7 +476,7 @@ addHook({
|
|
|
468
476
|
name: '@jest/core',
|
|
469
477
|
versions: ['>=24.8.0'],
|
|
470
478
|
file: 'build/SearchSource.js'
|
|
471
|
-
}, searchSourcePackage => {
|
|
479
|
+
}, (searchSourcePackage, frameworkVersion) => {
|
|
472
480
|
const SearchSource = searchSourcePackage.default ? searchSourcePackage.default : searchSourcePackage
|
|
473
481
|
|
|
474
482
|
shimmer.wrap(SearchSource.prototype, 'getTestPaths', getTestPaths => async function () {
|
|
@@ -492,13 +500,16 @@ addHook({
|
|
|
492
500
|
const testPaths = await getTestPaths.apply(this, arguments)
|
|
493
501
|
const { tests } = testPaths
|
|
494
502
|
|
|
495
|
-
const
|
|
503
|
+
const { skippedSuites, suitesToRun } = getJestSuitesToRun(skippableSuites, tests, rootDir)
|
|
504
|
+
|
|
505
|
+
isSuitesSkipped = suitesToRun.length !== tests.length
|
|
506
|
+
numSkippedSuites = skippedSuites.length
|
|
496
507
|
|
|
497
|
-
|
|
508
|
+
itrSkippedSuitesCh.publish({ skippedSuites, frameworkVersion })
|
|
498
509
|
|
|
499
510
|
skippableSuites = []
|
|
500
511
|
|
|
501
|
-
return { ...testPaths, tests:
|
|
512
|
+
return { ...testPaths, tests: suitesToRun }
|
|
502
513
|
})
|
|
503
514
|
|
|
504
515
|
return searchSourcePackage
|
|
@@ -15,15 +15,14 @@ const consumerStartCh = channel('apm:kafkajs:consume:start')
|
|
|
15
15
|
const consumerFinishCh = channel('apm:kafkajs:consume:finish')
|
|
16
16
|
const consumerErrorCh = channel('apm:kafkajs:consume:error')
|
|
17
17
|
|
|
18
|
-
addHook({ name: 'kafkajs', versions: ['>=1.4'] }, (
|
|
19
|
-
class Kafka extends
|
|
18
|
+
addHook({ name: 'kafkajs', file: 'src/index.js', versions: ['>=1.4'] }, (BaseKafka) => {
|
|
19
|
+
class Kafka extends BaseKafka {
|
|
20
20
|
constructor (options) {
|
|
21
21
|
super(options)
|
|
22
22
|
this._brokers = (options.brokers && typeof options.brokers !== 'function')
|
|
23
23
|
? options.brokers.join(',') : undefined
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
obj.Kafka = Kafka
|
|
27
26
|
|
|
28
27
|
shimmer.wrap(Kafka.prototype, 'producer', createProducer => function () {
|
|
29
28
|
const producer = createProducer.apply(this, arguments)
|
|
@@ -117,5 +116,5 @@ addHook({ name: 'kafkajs', versions: ['>=1.4'] }, (obj) => {
|
|
|
117
116
|
}
|
|
118
117
|
return consumer
|
|
119
118
|
})
|
|
120
|
-
return
|
|
119
|
+
return Kafka
|
|
121
120
|
})
|
|
@@ -30,6 +30,8 @@ const testSuiteFinishCh = channel('ci:mocha:test-suite:finish')
|
|
|
30
30
|
const testSuiteErrorCh = channel('ci:mocha:test-suite:error')
|
|
31
31
|
const testSuiteCodeCoverageCh = channel('ci:mocha:test-suite:code-coverage')
|
|
32
32
|
|
|
33
|
+
const itrSkippedSuitesCh = channel('ci:mocha:itr:skipped-suites')
|
|
34
|
+
|
|
33
35
|
// TODO: remove when root hooks and fixtures are implemented
|
|
34
36
|
const patched = new WeakSet()
|
|
35
37
|
|
|
@@ -47,6 +49,7 @@ const originalCoverageMap = createCoverageMap()
|
|
|
47
49
|
let suitesToSkip = []
|
|
48
50
|
let frameworkVersion
|
|
49
51
|
let isSuitesSkipped = false
|
|
52
|
+
let skippedSuites = []
|
|
50
53
|
|
|
51
54
|
function getSuitesByTestFile (root) {
|
|
52
55
|
const suitesByTestFile = {}
|
|
@@ -97,10 +100,17 @@ function getTestAsyncResource (test) {
|
|
|
97
100
|
return testToAr.get(originalFn)
|
|
98
101
|
}
|
|
99
102
|
|
|
100
|
-
function
|
|
101
|
-
return originalSuites.
|
|
102
|
-
|
|
103
|
-
|
|
103
|
+
function getFilteredSuites (originalSuites) {
|
|
104
|
+
return originalSuites.reduce((acc, suite) => {
|
|
105
|
+
const testPath = getTestSuitePath(suite.file, process.cwd())
|
|
106
|
+
const shouldSkip = suitesToSkip.includes(testPath)
|
|
107
|
+
if (shouldSkip) {
|
|
108
|
+
acc.skippedSuites.add(testPath)
|
|
109
|
+
} else {
|
|
110
|
+
acc.suitesToRun.push(suite)
|
|
111
|
+
}
|
|
112
|
+
return acc
|
|
113
|
+
}, { suitesToRun: [], skippedSuites: new Set() })
|
|
104
114
|
}
|
|
105
115
|
|
|
106
116
|
function mochaHook (Runner) {
|
|
@@ -137,13 +147,21 @@ function mochaHook (Runner) {
|
|
|
137
147
|
global.__coverage__ = fromCoverageMapToCoverage(originalCoverageMap)
|
|
138
148
|
}
|
|
139
149
|
|
|
140
|
-
testSessionFinishCh.publish({
|
|
150
|
+
testSessionFinishCh.publish({
|
|
151
|
+
status,
|
|
152
|
+
isSuitesSkipped,
|
|
153
|
+
testCodeCoverageLinesTotal,
|
|
154
|
+
numSkippedSuites: skippedSuites.length
|
|
155
|
+
})
|
|
141
156
|
}))
|
|
142
157
|
|
|
143
158
|
this.once('start', testRunAsyncResource.bind(function () {
|
|
144
159
|
const processArgv = process.argv.slice(2).join(' ')
|
|
145
160
|
const command = `mocha ${processArgv}`
|
|
146
161
|
testSessionStartCh.publish({ command, frameworkVersion })
|
|
162
|
+
if (skippedSuites.length) {
|
|
163
|
+
itrSkippedSuitesCh.publish({ skippedSuites, frameworkVersion })
|
|
164
|
+
}
|
|
147
165
|
}))
|
|
148
166
|
|
|
149
167
|
this.on('suite', function (suite) {
|
|
@@ -359,9 +377,13 @@ addHook({
|
|
|
359
377
|
suitesToSkip = skippableSuites
|
|
360
378
|
}
|
|
361
379
|
// We remove the suites that we skip through ITR
|
|
362
|
-
const
|
|
363
|
-
|
|
364
|
-
|
|
380
|
+
const filteredSuites = getFilteredSuites(runner.suite.suites)
|
|
381
|
+
const { suitesToRun } = filteredSuites
|
|
382
|
+
|
|
383
|
+
isSuitesSkipped = suitesToRun.length !== runner.suite.suites.length
|
|
384
|
+
runner.suite.suites = suitesToRun
|
|
385
|
+
|
|
386
|
+
skippedSuites = Array.from(filteredSuites.skippedSuites)
|
|
365
387
|
|
|
366
388
|
global.run()
|
|
367
389
|
}
|
|
@@ -419,6 +441,9 @@ addHook({
|
|
|
419
441
|
file: 'lib/cli/run-helpers.js'
|
|
420
442
|
}, (run) => {
|
|
421
443
|
shimmer.wrap(run, 'runMocha', runMocha => async function () {
|
|
444
|
+
if (!testStartCh.hasSubscribers) {
|
|
445
|
+
return runMocha.apply(this, arguments)
|
|
446
|
+
}
|
|
422
447
|
const mocha = arguments[0]
|
|
423
448
|
/**
|
|
424
449
|
* This attaches `run` to the global context, which we'll call after
|
|
@@ -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
|
})
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// TODO: either instrument all or none of the render functions
|
|
4
4
|
|
|
5
|
-
const { channel, addHook
|
|
5
|
+
const { channel, addHook } = require('./helpers/instrument')
|
|
6
6
|
const shimmer = require('../../datadog-shimmer')
|
|
7
7
|
const { DD_MAJOR } = require('../../../version')
|
|
8
8
|
|
|
@@ -11,7 +11,7 @@ const finishChannel = channel('apm:next:request:finish')
|
|
|
11
11
|
const errorChannel = channel('apm:next:request:error')
|
|
12
12
|
const pageLoadChannel = channel('apm:next:page:load')
|
|
13
13
|
|
|
14
|
-
const
|
|
14
|
+
const requests = new WeakSet()
|
|
15
15
|
|
|
16
16
|
function wrapHandleRequest (handleRequest) {
|
|
17
17
|
return function (req, res, pathname, query) {
|
|
@@ -28,9 +28,9 @@ function wrapHandleApiRequest (handleApiRequest) {
|
|
|
28
28
|
if (!handled) return handled
|
|
29
29
|
|
|
30
30
|
return this.hasPage(pathname).then(pageFound => {
|
|
31
|
-
const
|
|
31
|
+
const pageData = pageFound ? { page: pathname } : getPageFromPath(pathname, this.dynamicRoutes)
|
|
32
32
|
|
|
33
|
-
pageLoadChannel.publish(
|
|
33
|
+
pageLoadChannel.publish(pageData)
|
|
34
34
|
|
|
35
35
|
return handled
|
|
36
36
|
})
|
|
@@ -83,15 +83,19 @@ function wrapFindPageComponents (findPageComponents) {
|
|
|
83
83
|
const result = findPageComponents.apply(this, arguments)
|
|
84
84
|
|
|
85
85
|
if (result) {
|
|
86
|
-
pageLoadChannel.publish(
|
|
86
|
+
pageLoadChannel.publish(getPagePath(pathname))
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
return result
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
function getPagePath (
|
|
94
|
-
|
|
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 }
|
|
95
99
|
}
|
|
96
100
|
|
|
97
101
|
function getPageFromPath (page, dynamicRoutes = []) {
|
|
@@ -105,38 +109,50 @@ function getPageFromPath (page, dynamicRoutes = []) {
|
|
|
105
109
|
}
|
|
106
110
|
|
|
107
111
|
function instrument (req, res, handler) {
|
|
108
|
-
|
|
112
|
+
req = req.originalRequest || req
|
|
113
|
+
res = res.originalResponse || res
|
|
109
114
|
|
|
110
|
-
|
|
115
|
+
if (requests.has(req)) return handler()
|
|
111
116
|
|
|
112
|
-
|
|
117
|
+
requests.add(req)
|
|
113
118
|
|
|
114
|
-
|
|
115
|
-
startChannel.publish({ req, res })
|
|
119
|
+
const ctx = { req, res }
|
|
116
120
|
|
|
121
|
+
return startChannel.runStores(ctx, () => {
|
|
117
122
|
try {
|
|
118
|
-
const promise = handler()
|
|
123
|
+
const promise = handler(ctx)
|
|
119
124
|
|
|
120
125
|
// promise should only reject when propagateError is true:
|
|
121
126
|
// https://github.com/vercel/next.js/blob/cee656238a/packages/next/server/api-utils/node.ts#L547
|
|
122
127
|
return promise.then(
|
|
123
|
-
result => finish(
|
|
124
|
-
err => finish(
|
|
128
|
+
result => finish(ctx, result),
|
|
129
|
+
err => finish(ctx, null, err)
|
|
125
130
|
)
|
|
126
131
|
} catch (e) {
|
|
127
132
|
// this will probably never happen as the handler caller is an async function:
|
|
128
133
|
// https://github.com/vercel/next.js/blob/cee656238a/packages/next/server/api-utils/node.ts#L420
|
|
129
|
-
return finish(
|
|
134
|
+
return finish(ctx, null, e)
|
|
130
135
|
}
|
|
131
136
|
})
|
|
132
137
|
}
|
|
133
138
|
|
|
134
|
-
function
|
|
139
|
+
function wrapServeStatic (serveStatic) {
|
|
140
|
+
return function (req, res, path) {
|
|
141
|
+
return instrument(req, res, () => {
|
|
142
|
+
if (pageLoadChannel.hasSubscribers && path) pageLoadChannel.publish({ page: path })
|
|
143
|
+
|
|
144
|
+
return serveStatic.apply(this, arguments)
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function finish (ctx, result, err) {
|
|
135
150
|
if (err) {
|
|
136
|
-
|
|
151
|
+
ctx.error = err
|
|
152
|
+
errorChannel.publish(ctx)
|
|
137
153
|
}
|
|
138
154
|
|
|
139
|
-
finishChannel.publish(
|
|
155
|
+
finishChannel.publish(ctx)
|
|
140
156
|
|
|
141
157
|
if (err) {
|
|
142
158
|
throw err
|
|
@@ -145,6 +161,18 @@ function finish (req, res, result, err) {
|
|
|
145
161
|
return result
|
|
146
162
|
}
|
|
147
163
|
|
|
164
|
+
addHook({
|
|
165
|
+
name: 'next',
|
|
166
|
+
versions: ['>=11.1'],
|
|
167
|
+
file: 'dist/server/serve-static.js'
|
|
168
|
+
}, serveStatic => shimmer.wrap(serveStatic, 'serveStatic', wrapServeStatic))
|
|
169
|
+
|
|
170
|
+
addHook({
|
|
171
|
+
name: 'next',
|
|
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))
|
|
175
|
+
|
|
148
176
|
addHook({ name: 'next', versions: ['>=13.2'], file: 'dist/server/next-server.js' }, nextServer => {
|
|
149
177
|
const Server = nextServer.default
|
|
150
178
|
|
|
@@ -10,7 +10,7 @@ const startCh = channel('apm:openai:request:start')
|
|
|
10
10
|
const finishCh = channel('apm:openai:request:finish')
|
|
11
11
|
const errorCh = channel('apm:openai:request:error')
|
|
12
12
|
|
|
13
|
-
addHook({ name: 'openai', file: 'dist/api.js', versions: ['>=3.0.0'] }, exports => {
|
|
13
|
+
addHook({ name: 'openai', file: 'dist/api.js', versions: ['>=3.0.0 <4'] }, exports => {
|
|
14
14
|
const methodNames = Object.getOwnPropertyNames(exports.OpenAIApi.prototype)
|
|
15
15
|
methodNames.shift() // remove leading 'constructor' method
|
|
16
16
|
|
|
@@ -11,8 +11,12 @@ const startCh = channel('apm:pg:query:start')
|
|
|
11
11
|
const finishCh = channel('apm:pg:query:finish')
|
|
12
12
|
const errorCh = channel('apm:pg:query:error')
|
|
13
13
|
|
|
14
|
+
const startPoolQueryCh = channel('datadog:pg:pool:query:start')
|
|
15
|
+
const finishPoolQueryCh = channel('datadog:pg:pool:query:finish')
|
|
16
|
+
|
|
14
17
|
addHook({ name: 'pg', versions: ['>=8.0.3'] }, pg => {
|
|
15
18
|
shimmer.wrap(pg.Client.prototype, 'query', query => wrapQuery(query))
|
|
19
|
+
shimmer.wrap(pg.Pool.prototype, 'query', query => wrapPoolQuery(query))
|
|
16
20
|
return pg
|
|
17
21
|
})
|
|
18
22
|
|
|
@@ -35,28 +39,27 @@ function wrapQuery (query) {
|
|
|
35
39
|
? arguments[0]
|
|
36
40
|
: { text: arguments[0] }
|
|
37
41
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
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
|
+
})
|
|
49
53
|
}
|
|
50
|
-
Object.setPrototypeOf(newQuery, pgQuery)
|
|
51
54
|
|
|
52
55
|
return asyncResource.runInAsyncScope(() => {
|
|
53
56
|
startCh.publish({
|
|
54
57
|
params: this.connectionParameters,
|
|
55
|
-
query:
|
|
58
|
+
query: pgQuery,
|
|
56
59
|
processId
|
|
57
60
|
})
|
|
58
61
|
|
|
59
|
-
arguments[0] =
|
|
62
|
+
arguments[0] = pgQuery
|
|
60
63
|
|
|
61
64
|
const finish = asyncResource.bind(function (error) {
|
|
62
65
|
if (error) {
|
|
@@ -69,7 +72,7 @@ function wrapQuery (query) {
|
|
|
69
72
|
const queryQueue = this.queryQueue || this._queryQueue
|
|
70
73
|
const activeQuery = this.activeQuery || this._activeQuery
|
|
71
74
|
|
|
72
|
-
newQuery = queryQueue[queryQueue.length - 1] || activeQuery
|
|
75
|
+
const newQuery = queryQueue[queryQueue.length - 1] || activeQuery
|
|
73
76
|
|
|
74
77
|
if (!newQuery) {
|
|
75
78
|
return retval
|
|
@@ -97,3 +100,45 @@ function wrapQuery (query) {
|
|
|
97
100
|
})
|
|
98
101
|
}
|
|
99
102
|
}
|
|
103
|
+
|
|
104
|
+
function wrapPoolQuery (query) {
|
|
105
|
+
return function () {
|
|
106
|
+
if (!startPoolQueryCh.hasSubscribers) {
|
|
107
|
+
return query.apply(this, arguments)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
111
|
+
|
|
112
|
+
const pgQuery = arguments[0] && typeof arguments[0] === 'object' ? arguments[0] : { text: arguments[0] }
|
|
113
|
+
|
|
114
|
+
return asyncResource.runInAsyncScope(() => {
|
|
115
|
+
startPoolQueryCh.publish({
|
|
116
|
+
query: pgQuery
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
const finish = asyncResource.bind(function () {
|
|
120
|
+
finishPoolQueryCh.publish()
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
const cb = arguments[arguments.length - 1]
|
|
124
|
+
if (typeof cb === 'function') {
|
|
125
|
+
arguments[arguments.length - 1] = shimmer.wrap(cb, function () {
|
|
126
|
+
finish()
|
|
127
|
+
return cb.apply(this, arguments)
|
|
128
|
+
})
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const retval = query.apply(this, arguments)
|
|
132
|
+
|
|
133
|
+
if (retval && retval.then) {
|
|
134
|
+
retval.then(() => {
|
|
135
|
+
finish()
|
|
136
|
+
}).catch(() => {
|
|
137
|
+
finish()
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return retval
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -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))
|
|
@@ -25,12 +25,24 @@ class CucumberPlugin extends CiPlugin {
|
|
|
25
25
|
|
|
26
26
|
this.sourceRoot = process.cwd()
|
|
27
27
|
|
|
28
|
-
this.addSub('ci:cucumber:session:finish', ({
|
|
28
|
+
this.addSub('ci:cucumber:session:finish', ({
|
|
29
|
+
status,
|
|
30
|
+
isSuitesSkipped,
|
|
31
|
+
numSkippedSuites,
|
|
32
|
+
testCodeCoverageLinesTotal
|
|
33
|
+
}) => {
|
|
29
34
|
const { isSuitesSkippingEnabled, isCodeCoverageEnabled } = this.itrConfig || {}
|
|
30
35
|
addIntelligentTestRunnerSpanTags(
|
|
31
36
|
this.testSessionSpan,
|
|
32
37
|
this.testModuleSpan,
|
|
33
|
-
{
|
|
38
|
+
{
|
|
39
|
+
isSuitesSkipped,
|
|
40
|
+
isSuitesSkippingEnabled,
|
|
41
|
+
isCodeCoverageEnabled,
|
|
42
|
+
testCodeCoverageLinesTotal,
|
|
43
|
+
skippingCount: numSkippedSuites,
|
|
44
|
+
skippingType: 'suite'
|
|
45
|
+
}
|
|
34
46
|
)
|
|
35
47
|
|
|
36
48
|
this.testSessionSpan.setTag(TEST_STATUS, status)
|