dd-trace 5.1.0 → 5.3.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 -3
- package/README.md +1 -32
- package/ci/init.js +1 -4
- package/index.d.ts +21 -0
- package/package.json +6 -8
- package/packages/datadog-instrumentations/src/amqplib.js +2 -2
- package/packages/datadog-instrumentations/src/child_process.js +150 -0
- package/packages/datadog-instrumentations/src/cucumber.js +12 -12
- package/packages/datadog-instrumentations/src/express.js +20 -0
- package/packages/datadog-instrumentations/src/grpc/client.js +56 -36
- package/packages/datadog-instrumentations/src/helpers/hooks.js +3 -2
- package/packages/datadog-instrumentations/src/jest.js +147 -10
- package/packages/datadog-instrumentations/src/mocha.js +3 -3
- package/packages/datadog-instrumentations/src/mongoose.js +23 -10
- package/packages/datadog-instrumentations/src/mquery.js +65 -0
- package/packages/datadog-instrumentations/src/next.js +17 -3
- package/packages/datadog-instrumentations/src/playwright.js +41 -9
- package/packages/datadog-plugin-amqplib/src/consumer.js +10 -1
- package/packages/datadog-plugin-amqplib/src/producer.js +14 -1
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +134 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +19 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +83 -10
- package/packages/datadog-plugin-child_process/src/index.js +91 -0
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +125 -0
- package/packages/datadog-plugin-cucumber/src/index.js +16 -11
- package/packages/datadog-plugin-cypress/src/plugin.js +25 -12
- package/packages/datadog-plugin-graphql/src/index.js +1 -6
- package/packages/datadog-plugin-grpc/src/client.js +16 -2
- package/packages/datadog-plugin-grpc/src/util.js +1 -1
- package/packages/datadog-plugin-http/src/client.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +47 -6
- package/packages/datadog-plugin-mocha/src/index.js +14 -5
- package/packages/datadog-plugin-playwright/src/index.js +19 -5
- package/packages/datadog-plugin-rhea/src/consumer.js +11 -1
- package/packages/datadog-plugin-rhea/src/producer.js +11 -0
- package/packages/dd-trace/src/appsec/addresses.js +2 -0
- package/packages/dd-trace/src/appsec/api_security_sampler.js +16 -3
- package/packages/dd-trace/src/appsec/channels.js +2 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/command-injection-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +22 -17
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +7 -28
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +10 -6
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +4 -1
- package/packages/dd-trace/src/appsec/index.js +17 -2
- package/packages/dd-trace/src/appsec/rule_manager.js +2 -2
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +83 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +25 -6
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +2 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +83 -41
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +30 -8
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +7 -1
- package/packages/dd-trace/src/ci-visibility/{intelligent-test-runner/get-itr-configuration.js → requests/get-library-configuration.js} +18 -6
- package/packages/dd-trace/src/config.js +22 -9
- package/packages/dd-trace/src/datastreams/processor.js +36 -5
- package/packages/dd-trace/src/datastreams/writer.js +11 -5
- package/packages/dd-trace/src/dogstatsd.js +3 -5
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +5 -3
- package/packages/dd-trace/src/exporters/common/request.js +21 -3
- package/packages/dd-trace/src/format.js +25 -1
- package/packages/dd-trace/src/noop/span.js +1 -0
- package/packages/dd-trace/src/opentelemetry/span.js +9 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +1 -1
- package/packages/dd-trace/src/opentracing/span.js +38 -0
- package/packages/dd-trace/src/opentracing/span_context.js +12 -6
- package/packages/dd-trace/src/opentracing/tracer.js +2 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +24 -8
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/git.js +6 -0
- package/packages/dd-trace/src/plugins/util/test.js +36 -7
- package/packages/dd-trace/src/plugins/util/web.js +1 -1
- package/packages/dd-trace/src/profiling/config.js +22 -22
- package/packages/dd-trace/src/proxy.js +31 -23
- package/packages/dd-trace/src/span_processor.js +5 -1
- package/packages/dd-trace/src/telemetry/index.js +3 -0
- package/packages/dd-trace/src/tracer.js +1 -0
- package/packages/utils/src/kebabcase.js +16 -0
- package/packages/utils/src/pick.js +11 -0
- package/packages/utils/src/uniq.js +5 -0
- package/packages/datadog-instrumentations/src/child-process.js +0 -29
- package/packages/dd-trace/src/plugins/util/exec.js +0 -34
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -17,10 +17,7 @@ require,istanbul-lib-coverage,BSD-3-Clause,Copyright 2012-2015 Yahoo! Inc.
|
|
|
17
17
|
require,jest-docblock,MIT,Copyright Meta Platforms, Inc. and affiliates.
|
|
18
18
|
require,koalas,MIT,Copyright 2013-2017 Brian Woodward
|
|
19
19
|
require,limiter,MIT,Copyright 2011 John Hurliman
|
|
20
|
-
require,lodash.kebabcase,MIT,Copyright JS Foundation and other contributors
|
|
21
|
-
require,lodash.pick,MIT,Copyright JS Foundation and other contributors
|
|
22
20
|
require,lodash.sortby,MIT,Copyright JS Foundation and other contributors
|
|
23
|
-
require,lodash.uniq,MIT,Copyright JS Foundation and other contributors
|
|
24
21
|
require,lru-cache,ISC,Copyright (c) 2010-2022 Isaac Z. Schlueter and Contributors
|
|
25
22
|
require,methods,MIT,Copyright 2013-2014 TJ Holowaychuk
|
|
26
23
|
require,module-details-from-path,MIT,Copyright 2016 Thomas Watson Steen
|
|
@@ -33,6 +30,7 @@ require,protobufjs,BSD-3-Clause,Copyright 2016 Daniel Wirtz
|
|
|
33
30
|
require,tlhunter-sorted-set,MIT,Copyright (c) 2023 Datadog Inc.
|
|
34
31
|
require,retry,MIT,Copyright 2011 Tim Koschützki Felix Geisendörfer
|
|
35
32
|
require,semver,ISC,Copyright Isaac Z. Schlueter and Contributors
|
|
33
|
+
require,shell-quote,mit,Copyright (c) 2013 James Halliday
|
|
36
34
|
dev,@types/node,MIT,Copyright Authors
|
|
37
35
|
dev,autocannon,MIT,Copyright 2016 Matteo Collina
|
|
38
36
|
dev,aws-sdk,Apache 2.0,Copyright 2012-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
package/README.md
CHANGED
|
@@ -194,38 +194,7 @@ Regardless of where you open the issue, someone at Datadog will try to help.
|
|
|
194
194
|
|
|
195
195
|
## Bundling
|
|
196
196
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
Also generally, bundlers work by crawling all of the `require()` calls that an application makes to files on disk, replacing the `require()` calls with custom code, and then concatenating all of the resulting JavaScript into one "bundled" file. When a built-in module is loaded, like `require('fs')`, that call can then remain the same in the resulting bundle.
|
|
200
|
-
|
|
201
|
-
Fundamentally APM tools like `dd-trace` stop working at this point. Perhaps they continue to intercept the calls for built-in modules but don't intercept calls to third party libraries. This means that by default when you bundle a `dd-trace` app with a bundler it is likely to capture information about disk access (via `fs`) and outbound HTTP requests (via `http`), but will otherwise omit calls to third party libraries (like extracting incoming request route information for the `express` framework or showing which query is run for the `mysql` database client).
|
|
202
|
-
|
|
203
|
-
To get around this, one can treat all third party modules, or at least third party modules that the APM needs to instrument, as being "external" to the bundler. With this setting the instrumented modules remain on disk and continue to be loaded via `require()` while the non-instrumented modules are bundled. Sadly this results in a build with many extraneous files and starts to defeat the purpose of bundling.
|
|
204
|
-
|
|
205
|
-
For these reasons it's necessary to have custom-built bundler plugins. Such plugins are able to instruct the bundler on how to behave, injecting intermediary code and otherwise intercepting the "translated" `require()` calls. The result is that many more packages are then included in the bundled JavaScript file. Some applications can have 100% of modules bundled, however native modules still need to remain external to the bundle.
|
|
206
|
-
|
|
207
|
-
### ESBuild Support
|
|
208
|
-
|
|
209
|
-
This library provides experimental ESBuild support in the form of an ESBuild plugin. Require the `dd-trace/esbuild` module when building your bundle to enable the plugin.
|
|
210
|
-
|
|
211
|
-
Here's an example of how one might use `dd-trace` with ESBuild:
|
|
212
|
-
|
|
213
|
-
```javascript
|
|
214
|
-
const ddPlugin = require('dd-trace/esbuild')
|
|
215
|
-
const esbuild = require('esbuild')
|
|
216
|
-
|
|
217
|
-
esbuild.build({
|
|
218
|
-
entryPoints: ['app.js'],
|
|
219
|
-
bundle: true,
|
|
220
|
-
outfile: 'out.js',
|
|
221
|
-
plugins: [ddPlugin],
|
|
222
|
-
platform: 'node', // allows built-in modules to be required
|
|
223
|
-
target: ['node18']
|
|
224
|
-
}).catch((err) => {
|
|
225
|
-
console.error(err)
|
|
226
|
-
process.exit(1)
|
|
227
|
-
})
|
|
228
|
-
```
|
|
197
|
+
If you would like to trace your bundled application then please read this page on [bundling and dd-trace](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/nodejs/#bundling). It includes information on how to use our ESBuild plugin and includes caveats for other bundlers.
|
|
229
198
|
|
|
230
199
|
|
|
231
200
|
## Security Vulnerabilities
|
package/ci/init.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
const tracer = require('../packages/dd-trace')
|
|
3
|
-
const { ORIGIN_KEY } = require('../packages/dd-trace/src/constants')
|
|
4
3
|
const { isTrue } = require('../packages/dd-trace/src/util')
|
|
5
4
|
|
|
6
5
|
const isJestWorker = !!process.env.JEST_WORKER_ID
|
|
7
6
|
|
|
8
7
|
const options = {
|
|
9
8
|
startupLogs: false,
|
|
10
|
-
tags: {
|
|
11
|
-
[ORIGIN_KEY]: 'ciapp-test'
|
|
12
|
-
},
|
|
13
9
|
isCiVisibility: true,
|
|
14
10
|
flushInterval: isJestWorker ? 0 : 5000
|
|
15
11
|
}
|
|
@@ -44,6 +40,7 @@ if (isJestWorker) {
|
|
|
44
40
|
if (shouldInit) {
|
|
45
41
|
tracer.init(options)
|
|
46
42
|
tracer.use('fs', false)
|
|
43
|
+
tracer.use('child_process', false)
|
|
47
44
|
}
|
|
48
45
|
|
|
49
46
|
module.exports = tracer
|
package/index.d.ts
CHANGED
|
@@ -143,6 +143,11 @@ export declare interface TraceOptions extends Analyzable {
|
|
|
143
143
|
* The type of request.
|
|
144
144
|
*/
|
|
145
145
|
type?: string
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* An array of span links
|
|
149
|
+
*/
|
|
150
|
+
links?: Array<{ context: SpanContext, attributes?: Object }>
|
|
146
151
|
}
|
|
147
152
|
|
|
148
153
|
/**
|
|
@@ -154,6 +159,14 @@ export declare interface TraceOptions extends Analyzable {
|
|
|
154
159
|
*/
|
|
155
160
|
export declare interface Span extends opentracing.Span {
|
|
156
161
|
context (): SpanContext;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Causally links another span to the current span
|
|
165
|
+
* @param {SpanContext} context The context of the span to link to.
|
|
166
|
+
* @param {Object} attributes An optional key value pair of arbitrary values.
|
|
167
|
+
* @returns {void}
|
|
168
|
+
*/
|
|
169
|
+
addLink (context: SpanContext, attributes?: Object): void;
|
|
157
170
|
}
|
|
158
171
|
|
|
159
172
|
/**
|
|
@@ -1903,6 +1916,14 @@ export namespace opentelemetry {
|
|
|
1903
1916
|
* use the current time.
|
|
1904
1917
|
*/
|
|
1905
1918
|
recordException(exception: Exception, time?: TimeInput): void;
|
|
1919
|
+
|
|
1920
|
+
/**
|
|
1921
|
+
* Causally links another span to the current span
|
|
1922
|
+
* @param {otel.SpanContext} context The context of the span to link to.
|
|
1923
|
+
* @param {SpanAttributes} attributes An optional key value pair of arbitrary values.
|
|
1924
|
+
* @returns {void}
|
|
1925
|
+
*/
|
|
1926
|
+
addLink (context: otel.SpanContext, attributes?: SpanAttributes): void;
|
|
1906
1927
|
}
|
|
1907
1928
|
|
|
1908
1929
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
72
|
"@datadog/native-appsec": "7.0.0",
|
|
73
|
-
"@datadog/native-iast-rewriter": "2.2.
|
|
73
|
+
"@datadog/native-iast-rewriter": "2.2.3",
|
|
74
74
|
"@datadog/native-iast-taint-tracking": "1.6.4",
|
|
75
75
|
"@datadog/native-metrics": "^2.0.0",
|
|
76
76
|
"@datadog/pprof": "5.0.0",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"@opentelemetry/api": "^1.0.0",
|
|
79
79
|
"@opentelemetry/core": "^1.14.0",
|
|
80
80
|
"crypto-randomuuid": "^1.0.0",
|
|
81
|
-
"dc-polyfill": "^0.1.
|
|
81
|
+
"dc-polyfill": "^0.1.4",
|
|
82
82
|
"ignore": "^5.2.4",
|
|
83
83
|
"import-in-the-middle": "^1.7.3",
|
|
84
84
|
"int64-buffer": "^0.1.9",
|
|
@@ -87,10 +87,7 @@
|
|
|
87
87
|
"jest-docblock": "^29.7.0",
|
|
88
88
|
"koalas": "^1.0.2",
|
|
89
89
|
"limiter": "1.1.5",
|
|
90
|
-
"lodash.kebabcase": "^4.1.1",
|
|
91
|
-
"lodash.pick": "^4.4.0",
|
|
92
90
|
"lodash.sortby": "^4.7.0",
|
|
93
|
-
"lodash.uniq": "^4.5.0",
|
|
94
91
|
"lru-cache": "^7.14.0",
|
|
95
92
|
"methods": "^1.1.2",
|
|
96
93
|
"module-details-from-path": "^1.0.3",
|
|
@@ -102,13 +99,14 @@
|
|
|
102
99
|
"protobufjs": "^7.2.5",
|
|
103
100
|
"retry": "^0.13.1",
|
|
104
101
|
"semver": "^7.5.4",
|
|
102
|
+
"shell-quote": "^1.8.1",
|
|
105
103
|
"tlhunter-sorted-set": "^0.1.0"
|
|
106
104
|
},
|
|
107
105
|
"devDependencies": {
|
|
108
106
|
"@types/node": ">=18",
|
|
109
107
|
"autocannon": "^4.5.2",
|
|
110
108
|
"aws-sdk": "^2.1446.0",
|
|
111
|
-
"axios": "^
|
|
109
|
+
"axios": "^1.6.7",
|
|
112
110
|
"benchmark": "^2.1.4",
|
|
113
111
|
"body-parser": "^1.20.2",
|
|
114
112
|
"chai": "^4.3.7",
|
|
@@ -132,7 +130,7 @@
|
|
|
132
130
|
"jszip": "^3.5.0",
|
|
133
131
|
"knex": "^2.4.2",
|
|
134
132
|
"mkdirp": "^3.0.1",
|
|
135
|
-
"mocha": "
|
|
133
|
+
"mocha": "^9",
|
|
136
134
|
"multer": "^1.4.5-lts.1",
|
|
137
135
|
"nock": "^11.3.3",
|
|
138
136
|
"nyc": "^15.1.0",
|
|
@@ -5,7 +5,7 @@ const {
|
|
|
5
5
|
addHook,
|
|
6
6
|
AsyncResource
|
|
7
7
|
} = require('./helpers/instrument')
|
|
8
|
-
const kebabCase = require('
|
|
8
|
+
const kebabCase = require('../../utils/src/kebabcase')
|
|
9
9
|
const shimmer = require('../../datadog-shimmer')
|
|
10
10
|
|
|
11
11
|
const startCh = channel('apm:amqplib:command:start')
|
|
@@ -28,7 +28,7 @@ addHook({ name: 'amqplib', file: 'lib/channel.js', versions: ['>=0.5'] }, channe
|
|
|
28
28
|
})
|
|
29
29
|
|
|
30
30
|
shimmer.wrap(channel.Channel.prototype, 'sendMessage', sendMessage => function (fields) {
|
|
31
|
-
return instrument(sendMessage, this, arguments, 'basic.publish', fields)
|
|
31
|
+
return instrument(sendMessage, this, arguments, 'basic.publish', fields, arguments[2])
|
|
32
32
|
})
|
|
33
33
|
|
|
34
34
|
shimmer.wrap(channel.BaseChannel.prototype, 'dispatchMessage', dispatchMessage => function (fields, message) {
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const util = require('util')
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
addHook,
|
|
7
|
+
AsyncResource
|
|
8
|
+
} = require('./helpers/instrument')
|
|
9
|
+
const shimmer = require('../../datadog-shimmer')
|
|
10
|
+
const dc = require('dc-polyfill')
|
|
11
|
+
|
|
12
|
+
const childProcessChannel = dc.tracingChannel('datadog:child_process:execution')
|
|
13
|
+
|
|
14
|
+
// ignored exec method because it calls to execFile directly
|
|
15
|
+
const execAsyncMethods = ['execFile', 'spawn']
|
|
16
|
+
const execSyncMethods = ['execFileSync', 'spawnSync']
|
|
17
|
+
|
|
18
|
+
const names = ['child_process', 'node:child_process']
|
|
19
|
+
|
|
20
|
+
// child_process and node:child_process returns the same object instance, we only want to add hooks once
|
|
21
|
+
let patched = false
|
|
22
|
+
names.forEach(name => {
|
|
23
|
+
addHook({ name }, childProcess => {
|
|
24
|
+
if (!patched) {
|
|
25
|
+
patched = true
|
|
26
|
+
shimmer.massWrap(childProcess, execAsyncMethods, wrapChildProcessAsyncMethod())
|
|
27
|
+
shimmer.massWrap(childProcess, execSyncMethods, wrapChildProcessSyncMethod())
|
|
28
|
+
shimmer.wrap(childProcess, 'execSync', wrapChildProcessSyncMethod(true))
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return childProcess
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
function normalizeArgs (args, shell) {
|
|
36
|
+
const childProcessInfo = {
|
|
37
|
+
command: args[0]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (Array.isArray(args[1])) {
|
|
41
|
+
childProcessInfo.command = childProcessInfo.command + ' ' + args[1].join(' ')
|
|
42
|
+
if (args[2] != null && typeof args[2] === 'object') {
|
|
43
|
+
childProcessInfo.options = args[2]
|
|
44
|
+
}
|
|
45
|
+
} else if (args[1] != null && typeof args[1] === 'object') {
|
|
46
|
+
childProcessInfo.options = args[1]
|
|
47
|
+
}
|
|
48
|
+
childProcessInfo.shell = shell ||
|
|
49
|
+
childProcessInfo.options?.shell === true ||
|
|
50
|
+
typeof childProcessInfo.options?.shell === 'string'
|
|
51
|
+
|
|
52
|
+
return childProcessInfo
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function wrapChildProcessSyncMethod (shell = false) {
|
|
56
|
+
return function wrapMethod (childProcessMethod) {
|
|
57
|
+
return function () {
|
|
58
|
+
if (!childProcessChannel.start.hasSubscribers || arguments.length === 0) {
|
|
59
|
+
return childProcessMethod.apply(this, arguments)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const childProcessInfo = normalizeArgs(arguments, shell)
|
|
63
|
+
|
|
64
|
+
return childProcessChannel.traceSync(
|
|
65
|
+
childProcessMethod,
|
|
66
|
+
{
|
|
67
|
+
command: childProcessInfo.command,
|
|
68
|
+
shell: childProcessInfo.shell
|
|
69
|
+
},
|
|
70
|
+
this,
|
|
71
|
+
...arguments)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function wrapChildProcessCustomPromisifyMethod (customPromisifyMethod, shell) {
|
|
77
|
+
return function () {
|
|
78
|
+
if (!childProcessChannel.start.hasSubscribers || arguments.length === 0) {
|
|
79
|
+
return customPromisifyMethod.apply(this, arguments)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const childProcessInfo = normalizeArgs(arguments, shell)
|
|
83
|
+
|
|
84
|
+
return childProcessChannel.tracePromise(
|
|
85
|
+
customPromisifyMethod,
|
|
86
|
+
{
|
|
87
|
+
command: childProcessInfo.command,
|
|
88
|
+
shell: childProcessInfo.shell
|
|
89
|
+
},
|
|
90
|
+
this,
|
|
91
|
+
...arguments)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function wrapChildProcessAsyncMethod (shell = false) {
|
|
96
|
+
return function wrapMethod (childProcessMethod) {
|
|
97
|
+
function wrappedChildProcessMethod () {
|
|
98
|
+
if (!childProcessChannel.start.hasSubscribers || arguments.length === 0) {
|
|
99
|
+
return childProcessMethod.apply(this, arguments)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const childProcessInfo = normalizeArgs(arguments, shell)
|
|
103
|
+
|
|
104
|
+
const innerResource = new AsyncResource('bound-anonymous-fn')
|
|
105
|
+
return innerResource.runInAsyncScope(() => {
|
|
106
|
+
childProcessChannel.start.publish({ command: childProcessInfo.command, shell: childProcessInfo.shell })
|
|
107
|
+
|
|
108
|
+
const childProcess = childProcessMethod.apply(this, arguments)
|
|
109
|
+
if (childProcess) {
|
|
110
|
+
let errorExecuted = false
|
|
111
|
+
|
|
112
|
+
childProcess.on('error', (e) => {
|
|
113
|
+
errorExecuted = true
|
|
114
|
+
childProcessChannel.error.publish(e)
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
childProcess.on('close', (code) => {
|
|
118
|
+
code = code || 0
|
|
119
|
+
if (!errorExecuted && code !== 0) {
|
|
120
|
+
childProcessChannel.error.publish()
|
|
121
|
+
}
|
|
122
|
+
childProcessChannel.asyncEnd.publish({
|
|
123
|
+
command: childProcessInfo.command,
|
|
124
|
+
shell: childProcessInfo.shell,
|
|
125
|
+
result: code
|
|
126
|
+
})
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return childProcess
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (childProcessMethod[util.promisify.custom]) {
|
|
135
|
+
const wrapedChildProcessCustomPromisifyMethod =
|
|
136
|
+
shimmer.wrap(childProcessMethod[util.promisify.custom],
|
|
137
|
+
wrapChildProcessCustomPromisifyMethod(childProcessMethod[util.promisify.custom]), shell)
|
|
138
|
+
|
|
139
|
+
// should do it in this way because the original property is readonly
|
|
140
|
+
const descriptor = Object.getOwnPropertyDescriptor(childProcessMethod, util.promisify.custom)
|
|
141
|
+
Object.defineProperty(wrappedChildProcessMethod,
|
|
142
|
+
util.promisify.custom,
|
|
143
|
+
{
|
|
144
|
+
...descriptor,
|
|
145
|
+
value: wrapedChildProcessCustomPromisifyMethod
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
return wrappedChildProcessMethod
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -16,7 +16,7 @@ const testSuiteStartCh = channel('ci:cucumber:test-suite:start')
|
|
|
16
16
|
const testSuiteFinishCh = channel('ci:cucumber:test-suite:finish')
|
|
17
17
|
const testSuiteCodeCoverageCh = channel('ci:cucumber:test-suite:code-coverage')
|
|
18
18
|
|
|
19
|
-
const
|
|
19
|
+
const libraryConfigurationCh = channel('ci:cucumber:library-configuration')
|
|
20
20
|
const skippableSuitesCh = channel('ci:cucumber:test-suite:skippable')
|
|
21
21
|
const sessionStartCh = channel('ci:cucumber:session:start')
|
|
22
22
|
const sessionFinishCh = channel('ci:cucumber:session:finish')
|
|
@@ -96,11 +96,11 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
96
96
|
|
|
97
97
|
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
98
98
|
return asyncResource.runInAsyncScope(() => {
|
|
99
|
-
const
|
|
99
|
+
const testFileAbsolutePath = this.pickle.uri
|
|
100
100
|
|
|
101
|
-
if (!pickleResultByFile[
|
|
101
|
+
if (!pickleResultByFile[testFileAbsolutePath]) { // first test in suite
|
|
102
102
|
isUnskippable = isMarkedAsUnskippable(this.pickle)
|
|
103
|
-
const testSuitePath = getTestSuitePath(
|
|
103
|
+
const testSuitePath = getTestSuitePath(testFileAbsolutePath, process.cwd())
|
|
104
104
|
isForcedToRun = isUnskippable && skippableSuites.includes(testSuitePath)
|
|
105
105
|
|
|
106
106
|
testSuiteStartCh.publish({ testSuitePath, isUnskippable, isForcedToRun, itrCorrelationId })
|
|
@@ -113,7 +113,7 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
113
113
|
|
|
114
114
|
testStartCh.publish({
|
|
115
115
|
testName: this.pickle.name,
|
|
116
|
-
|
|
116
|
+
testFileAbsolutePath,
|
|
117
117
|
testSourceLine
|
|
118
118
|
})
|
|
119
119
|
try {
|
|
@@ -123,21 +123,21 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
123
123
|
const { status, skipReason, errorMessage } = isLatestVersion
|
|
124
124
|
? getStatusFromResultLatest(result) : getStatusFromResult(result)
|
|
125
125
|
|
|
126
|
-
if (!pickleResultByFile[
|
|
127
|
-
pickleResultByFile[
|
|
126
|
+
if (!pickleResultByFile[testFileAbsolutePath]) {
|
|
127
|
+
pickleResultByFile[testFileAbsolutePath] = [status]
|
|
128
128
|
} else {
|
|
129
|
-
pickleResultByFile[
|
|
129
|
+
pickleResultByFile[testFileAbsolutePath].push(status)
|
|
130
130
|
}
|
|
131
131
|
testFinishCh.publish({ status, skipReason, errorMessage })
|
|
132
132
|
// last test in suite
|
|
133
|
-
if (pickleResultByFile[
|
|
134
|
-
const testSuiteStatus = getSuiteStatusFromTestStatuses(pickleResultByFile[
|
|
133
|
+
if (pickleResultByFile[testFileAbsolutePath].length === pickleByFile[testFileAbsolutePath].length) {
|
|
134
|
+
const testSuiteStatus = getSuiteStatusFromTestStatuses(pickleResultByFile[testFileAbsolutePath])
|
|
135
135
|
if (global.__coverage__) {
|
|
136
136
|
const coverageFiles = getCoveredFilenamesFromCoverage(global.__coverage__)
|
|
137
137
|
|
|
138
138
|
testSuiteCodeCoverageCh.publish({
|
|
139
139
|
coverageFiles,
|
|
140
|
-
suiteFile:
|
|
140
|
+
suiteFile: testFileAbsolutePath
|
|
141
141
|
})
|
|
142
142
|
// We need to reset coverage to get a code coverage per suite
|
|
143
143
|
// Before that, we preserve the original coverage
|
|
@@ -272,7 +272,7 @@ addHook({
|
|
|
272
272
|
})
|
|
273
273
|
|
|
274
274
|
asyncResource.runInAsyncScope(() => {
|
|
275
|
-
|
|
275
|
+
libraryConfigurationCh.publish({ onDone })
|
|
276
276
|
})
|
|
277
277
|
|
|
278
278
|
await configPromise
|
|
@@ -19,11 +19,31 @@ function wrapHandle (handle) {
|
|
|
19
19
|
|
|
20
20
|
const wrapRouterMethod = createWrapRouterMethod('express')
|
|
21
21
|
|
|
22
|
+
const responseJsonChannel = channel('datadog:express:response:json:start')
|
|
23
|
+
|
|
24
|
+
function wrapResponseJson (json) {
|
|
25
|
+
return function wrappedJson (obj) {
|
|
26
|
+
if (responseJsonChannel.hasSubscribers) {
|
|
27
|
+
// backward compat as express 4.x supports deprecated 3.x signature
|
|
28
|
+
if (arguments.length === 2 && typeof arguments[1] !== 'number') {
|
|
29
|
+
obj = arguments[1]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
responseJsonChannel.publish({ req: this.req, body: obj })
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return json.apply(this, arguments)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
22
39
|
addHook({ name: 'express', versions: ['>=4'] }, express => {
|
|
23
40
|
shimmer.wrap(express.application, 'handle', wrapHandle)
|
|
24
41
|
shimmer.wrap(express.Router, 'use', wrapRouterMethod)
|
|
25
42
|
shimmer.wrap(express.Router, 'route', wrapRouterMethod)
|
|
26
43
|
|
|
44
|
+
shimmer.wrap(express.response, 'json', wrapResponseJson)
|
|
45
|
+
shimmer.wrap(express.response, 'jsonp', wrapResponseJson)
|
|
46
|
+
|
|
27
47
|
return express
|
|
28
48
|
})
|
|
29
49
|
|
|
@@ -15,54 +15,52 @@ const errorChannel = channel('apm:grpc:client:request:error')
|
|
|
15
15
|
const finishChannel = channel('apm:grpc:client:request:finish')
|
|
16
16
|
const emitChannel = channel('apm:grpc:client:request:emit')
|
|
17
17
|
|
|
18
|
-
function createWrapMakeRequest (type) {
|
|
18
|
+
function createWrapMakeRequest (type, hasPeer = false) {
|
|
19
19
|
return function wrapMakeRequest (makeRequest) {
|
|
20
20
|
return function (path) {
|
|
21
21
|
const args = ensureMetadata(this, arguments, 4)
|
|
22
22
|
|
|
23
|
-
return callMethod(this, makeRequest, args, path, args[4], type)
|
|
23
|
+
return callMethod(this, makeRequest, args, path, args[4], type, hasPeer)
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
function createWrapLoadPackageDefinition () {
|
|
28
|
+
function createWrapLoadPackageDefinition (hasPeer = false) {
|
|
29
29
|
return function wrapLoadPackageDefinition (loadPackageDefinition) {
|
|
30
30
|
return function (packageDef) {
|
|
31
31
|
const result = loadPackageDefinition.apply(this, arguments)
|
|
32
32
|
|
|
33
33
|
if (!result) return result
|
|
34
34
|
|
|
35
|
-
wrapPackageDefinition(result)
|
|
35
|
+
wrapPackageDefinition(result, hasPeer)
|
|
36
36
|
|
|
37
37
|
return result
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
function createWrapMakeClientConstructor () {
|
|
42
|
+
function createWrapMakeClientConstructor (hasPeer = false) {
|
|
43
43
|
return function wrapMakeClientConstructor (makeClientConstructor) {
|
|
44
44
|
return function (methods) {
|
|
45
45
|
const ServiceClient = makeClientConstructor.apply(this, arguments)
|
|
46
|
-
|
|
47
|
-
wrapClientConstructor(ServiceClient, methods)
|
|
48
|
-
|
|
46
|
+
wrapClientConstructor(ServiceClient, methods, hasPeer)
|
|
49
47
|
return ServiceClient
|
|
50
48
|
}
|
|
51
49
|
}
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
function wrapPackageDefinition (def) {
|
|
52
|
+
function wrapPackageDefinition (def, hasPeer = false) {
|
|
55
53
|
for (const name in def) {
|
|
56
54
|
if (def[name].format) continue
|
|
57
55
|
if (def[name].service && def[name].prototype) {
|
|
58
|
-
wrapClientConstructor(def[name], def[name].service)
|
|
56
|
+
wrapClientConstructor(def[name], def[name].service, hasPeer)
|
|
59
57
|
} else {
|
|
60
|
-
wrapPackageDefinition(def[name])
|
|
58
|
+
wrapPackageDefinition(def[name], hasPeer)
|
|
61
59
|
}
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
62
|
|
|
65
|
-
function wrapClientConstructor (ServiceClient, methods) {
|
|
63
|
+
function wrapClientConstructor (ServiceClient, methods, hasPeer = false) {
|
|
66
64
|
const proto = ServiceClient.prototype
|
|
67
65
|
|
|
68
66
|
if (typeof methods !== 'object' || 'format' in methods) return
|
|
@@ -76,24 +74,23 @@ function wrapClientConstructor (ServiceClient, methods) {
|
|
|
76
74
|
const type = getType(methods[name])
|
|
77
75
|
|
|
78
76
|
if (methods[name]) {
|
|
79
|
-
proto[name] = wrapMethod(proto[name], path, type)
|
|
77
|
+
proto[name] = wrapMethod(proto[name], path, type, hasPeer)
|
|
80
78
|
}
|
|
81
79
|
|
|
82
80
|
if (originalName) {
|
|
83
|
-
proto[originalName] = wrapMethod(proto[originalName], path, type)
|
|
81
|
+
proto[originalName] = wrapMethod(proto[originalName], path, type, hasPeer)
|
|
84
82
|
}
|
|
85
83
|
})
|
|
86
84
|
}
|
|
87
85
|
|
|
88
|
-
function wrapMethod (method, path, type) {
|
|
86
|
+
function wrapMethod (method, path, type, hasPeer) {
|
|
89
87
|
if (typeof method !== 'function' || patched.has(method)) {
|
|
90
88
|
return method
|
|
91
89
|
}
|
|
92
90
|
|
|
93
91
|
const wrapped = function () {
|
|
94
92
|
const args = ensureMetadata(this, arguments, 1)
|
|
95
|
-
|
|
96
|
-
return callMethod(this, method, args, path, args[1], type)
|
|
93
|
+
return callMethod(this, method, args, path, args[1], type, hasPeer)
|
|
97
94
|
}
|
|
98
95
|
|
|
99
96
|
Object.assign(wrapped, method)
|
|
@@ -117,7 +114,20 @@ function wrapCallback (ctx, callback = () => { }) {
|
|
|
117
114
|
}
|
|
118
115
|
}
|
|
119
116
|
|
|
120
|
-
function createWrapEmit (ctx) {
|
|
117
|
+
function createWrapEmit (ctx, hasPeer = false) {
|
|
118
|
+
const onStatusWithPeer = function (ctx, arg1, thisArg) {
|
|
119
|
+
ctx.result = arg1
|
|
120
|
+
ctx.peer = thisArg.getPeer()
|
|
121
|
+
finishChannel.publish(ctx)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const onStatusWithoutPeer = function (ctx, arg1, thisArg) {
|
|
125
|
+
ctx.result = arg1
|
|
126
|
+
finishChannel.publish(ctx)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const onStatus = hasPeer ? onStatusWithPeer : onStatusWithoutPeer
|
|
130
|
+
|
|
121
131
|
return function wrapEmit (emit) {
|
|
122
132
|
return function (event, arg1) {
|
|
123
133
|
switch (event) {
|
|
@@ -126,8 +136,7 @@ function createWrapEmit (ctx) {
|
|
|
126
136
|
errorChannel.publish(ctx)
|
|
127
137
|
break
|
|
128
138
|
case 'status':
|
|
129
|
-
ctx
|
|
130
|
-
finishChannel.publish(ctx)
|
|
139
|
+
onStatus(ctx, arg1, this)
|
|
131
140
|
break
|
|
132
141
|
}
|
|
133
142
|
|
|
@@ -138,7 +147,7 @@ function createWrapEmit (ctx) {
|
|
|
138
147
|
}
|
|
139
148
|
}
|
|
140
149
|
|
|
141
|
-
function callMethod (client, method, args, path, metadata, type) {
|
|
150
|
+
function callMethod (client, method, args, path, metadata, type, hasPeer = false) {
|
|
142
151
|
if (!startChannel.hasSubscribers) return method.apply(client, args)
|
|
143
152
|
|
|
144
153
|
const length = args.length
|
|
@@ -159,7 +168,7 @@ function callMethod (client, method, args, path, metadata, type) {
|
|
|
159
168
|
const call = method.apply(client, args)
|
|
160
169
|
|
|
161
170
|
if (call && typeof call.emit === 'function') {
|
|
162
|
-
shimmer.wrap(call, 'emit', createWrapEmit(ctx))
|
|
171
|
+
shimmer.wrap(call, 'emit', createWrapEmit(ctx, hasPeer))
|
|
163
172
|
}
|
|
164
173
|
|
|
165
174
|
return call
|
|
@@ -223,34 +232,45 @@ function getGrpc (client) {
|
|
|
223
232
|
} while ((proto = Object.getPrototypeOf(proto)))
|
|
224
233
|
}
|
|
225
234
|
|
|
226
|
-
function patch (
|
|
227
|
-
|
|
235
|
+
function patch (hasPeer = false) {
|
|
236
|
+
return function patch (grpc) {
|
|
237
|
+
const proto = grpc.Client.prototype
|
|
228
238
|
|
|
229
|
-
|
|
239
|
+
instances.set(proto, grpc)
|
|
230
240
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
241
|
+
shimmer.wrap(proto, 'makeBidiStreamRequest', createWrapMakeRequest(types.bidi, hasPeer))
|
|
242
|
+
shimmer.wrap(proto, 'makeClientStreamRequest', createWrapMakeRequest(types.clientStream, hasPeer))
|
|
243
|
+
shimmer.wrap(proto, 'makeServerStreamRequest', createWrapMakeRequest(types.serverStream, hasPeer))
|
|
244
|
+
shimmer.wrap(proto, 'makeUnaryRequest', createWrapMakeRequest(types.unary, hasPeer))
|
|
235
245
|
|
|
236
|
-
|
|
246
|
+
return grpc
|
|
247
|
+
}
|
|
237
248
|
}
|
|
238
249
|
|
|
239
250
|
if (nodeMajor <= 14) {
|
|
240
|
-
addHook({ name: 'grpc', versions: ['>=1.24.3'] }, patch)
|
|
251
|
+
addHook({ name: 'grpc', versions: ['>=1.24.3'] }, patch(true))
|
|
241
252
|
|
|
242
253
|
addHook({ name: 'grpc', versions: ['>=1.24.3'], file: 'src/client.js' }, client => {
|
|
243
|
-
shimmer.wrap(client, 'makeClientConstructor', createWrapMakeClientConstructor())
|
|
254
|
+
shimmer.wrap(client, 'makeClientConstructor', createWrapMakeClientConstructor(true))
|
|
244
255
|
|
|
245
256
|
return client
|
|
246
257
|
})
|
|
247
258
|
}
|
|
248
259
|
|
|
249
|
-
addHook({ name: '@grpc/grpc-js', versions: ['>=1.0.3'] }, patch)
|
|
260
|
+
addHook({ name: '@grpc/grpc-js', versions: ['>=1.0.3 <1.1.4'] }, patch(false))
|
|
261
|
+
|
|
262
|
+
addHook({ name: '@grpc/grpc-js', versions: ['>=1.0.3 <1.1.4'], file: 'build/src/make-client.js' }, client => {
|
|
263
|
+
shimmer.wrap(client, 'makeClientConstructor', createWrapMakeClientConstructor(false))
|
|
264
|
+
shimmer.wrap(client, 'loadPackageDefinition', createWrapLoadPackageDefinition(false))
|
|
265
|
+
|
|
266
|
+
return client
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
addHook({ name: '@grpc/grpc-js', versions: ['>=1.1.4'] }, patch(true))
|
|
250
270
|
|
|
251
|
-
addHook({ name: '@grpc/grpc-js', versions: ['>=1.
|
|
252
|
-
shimmer.wrap(client, 'makeClientConstructor', createWrapMakeClientConstructor())
|
|
253
|
-
shimmer.wrap(client, 'loadPackageDefinition', createWrapLoadPackageDefinition())
|
|
271
|
+
addHook({ name: '@grpc/grpc-js', versions: ['>=1.1.4'], file: 'build/src/make-client.js' }, client => {
|
|
272
|
+
shimmer.wrap(client, 'makeClientConstructor', createWrapMakeClientConstructor(true))
|
|
273
|
+
shimmer.wrap(client, 'loadPackageDefinition', createWrapLoadPackageDefinition(true))
|
|
254
274
|
|
|
255
275
|
return client
|
|
256
276
|
})
|