dd-trace 3.20.0 → 3.22.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/index.d.ts +8 -1
- package/package.json +6 -5
- package/packages/datadog-instrumentations/src/cucumber.js +13 -0
- package/packages/datadog-instrumentations/src/grpc/client.js +9 -5
- package/packages/datadog-instrumentations/src/grpc/server.js +8 -4
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +4 -0
- package/packages/datadog-instrumentations/src/http/client.js +2 -1
- package/packages/datadog-instrumentations/src/http/server.js +14 -0
- package/packages/datadog-instrumentations/src/http2/client.js +4 -0
- package/packages/datadog-instrumentations/src/jest.js +20 -17
- package/packages/datadog-instrumentations/src/next.js +6 -1
- package/packages/datadog-instrumentations/src/playwright.js +1 -1
- package/packages/datadog-instrumentations/src/sequelize.js +51 -0
- package/packages/datadog-plugin-amqp10/src/consumer.js +1 -3
- package/packages/datadog-plugin-amqp10/src/producer.js +1 -3
- package/packages/datadog-plugin-amqplib/src/client.js +4 -3
- package/packages/datadog-plugin-amqplib/src/consumer.js +1 -3
- package/packages/datadog-plugin-amqplib/src/producer.js +1 -3
- package/packages/datadog-plugin-aws-sdk/src/base.js +3 -0
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +2 -1
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +4 -2
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +4 -3
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -1
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +2 -1
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +2 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +8 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +7 -1
- package/packages/datadog-plugin-cucumber/src/index.js +2 -2
- package/packages/datadog-plugin-cypress/src/plugin.js +150 -30
- package/packages/datadog-plugin-cypress/src/support.js +6 -3
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +4 -3
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -3
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +1 -3
- package/packages/datadog-plugin-http/src/client.js +70 -67
- package/packages/datadog-plugin-http2/src/client.js +50 -46
- package/packages/datadog-plugin-jest/src/index.js +5 -4
- package/packages/datadog-plugin-jest/src/util.js +10 -1
- package/packages/datadog-plugin-kafkajs/src/consumer.js +1 -4
- package/packages/datadog-plugin-kafkajs/src/producer.js +1 -3
- package/packages/datadog-plugin-memcached/src/index.js +2 -3
- package/packages/datadog-plugin-mocha/src/index.js +4 -2
- package/packages/datadog-plugin-pg/src/index.js +1 -1
- package/packages/datadog-plugin-redis/src/index.js +2 -13
- package/packages/datadog-plugin-rhea/src/consumer.js +1 -3
- package/packages/datadog-plugin-rhea/src/producer.js +1 -5
- package/packages/dd-trace/src/appsec/blocked_templates.js +2 -101
- package/packages/dd-trace/src/appsec/blocking.js +60 -11
- package/packages/dd-trace/src/appsec/channels.js +3 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +7 -5
- package/packages/dd-trace/src/appsec/iast/analyzers/command-injection-analyzer.js +2 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/index.js +3 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/insecure-cookie-analyzer.js +31 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/ldap-injection-analyzer.js +2 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +26 -5
- package/packages/dd-trace/src/appsec/iast/analyzers/set-cookies-header-interceptor.js +47 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +65 -4
- package/packages/dd-trace/src/appsec/iast/analyzers/ssrf-analyzer.js +26 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +35 -3
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-cipher-analyzer.js +2 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +2 -1
- package/packages/dd-trace/src/appsec/iast/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/path-line.js +16 -8
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +19 -4
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/range-utils.js +37 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +29 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +35 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +118 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +49 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +146 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +113 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +10 -0
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +4 -109
- package/packages/dd-trace/src/appsec/recommended.json +45 -46
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +3 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +4 -0
- package/packages/dd-trace/src/appsec/rule_manager.js +49 -6
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -7
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +1 -6
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +10 -4
- package/packages/dd-trace/src/config.js +86 -9
- package/packages/dd-trace/src/constants.js +3 -1
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +11 -3
- package/packages/dd-trace/src/exporters/common/util.js +9 -0
- package/packages/dd-trace/src/exporters/common/writer.js +3 -2
- package/packages/dd-trace/src/git_metadata_tagger.js +17 -0
- package/packages/dd-trace/src/git_properties.js +32 -0
- package/packages/dd-trace/src/plugin_manager.js +2 -0
- package/packages/dd-trace/src/plugins/cache.js +7 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +2 -0
- package/packages/dd-trace/src/plugins/client.js +3 -2
- package/packages/dd-trace/src/plugins/consumer.js +14 -2
- package/packages/dd-trace/src/plugins/database.js +2 -2
- package/packages/dd-trace/src/plugins/inbound.js +7 -0
- package/packages/dd-trace/src/plugins/{outgoing.js → outbound.js} +2 -2
- package/packages/dd-trace/src/plugins/producer.js +19 -2
- package/packages/dd-trace/src/plugins/server.js +2 -2
- package/packages/dd-trace/src/plugins/storage.js +2 -0
- package/packages/dd-trace/src/plugins/tracing.js +11 -0
- package/packages/dd-trace/src/plugins/util/ci.js +63 -8
- package/packages/dd-trace/src/plugins/util/tags.js +5 -1
- package/packages/dd-trace/src/profiling/config.js +4 -2
- package/packages/dd-trace/src/profiling/constants.js +0 -1
- package/packages/dd-trace/src/profiling/profilers/space.js +1 -3
- package/packages/dd-trace/src/proxy.js +4 -0
- package/packages/dd-trace/src/serverless.js +25 -0
- package/packages/dd-trace/src/service-naming/index.js +30 -0
- package/packages/dd-trace/src/service-naming/schemas/definition.js +24 -0
- package/packages/dd-trace/src/service-naming/schemas/index.js +6 -0
- package/packages/dd-trace/src/service-naming/schemas/util.js +5 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/index.js +5 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +64 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +33 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/index.js +5 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +52 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +21 -0
- package/packages/dd-trace/src/span_processor.js +3 -0
- package/packages/dd-trace/src/tracer.js +3 -2
- package/version.js +9 -0
- package/packages/dd-trace/src/plugins/incoming.js +0 -7
package/index.d.ts
CHANGED
|
@@ -79,7 +79,8 @@ export declare interface Tracer extends opentracing.Tracer {
|
|
|
79
79
|
* which case the span will finish at the end of the function execution.
|
|
80
80
|
*
|
|
81
81
|
* If the `orphanable` option is set to false, the function will not be traced
|
|
82
|
-
* unless there is already an active span or `childOf` option.
|
|
82
|
+
* unless there is already an active span or `childOf` option. Note that this
|
|
83
|
+
* option is deprecated and has been removed in version 4.0.
|
|
83
84
|
*/
|
|
84
85
|
trace<T> (name: string, fn: (span?: Span, fn?: (error?: Error) => any) => T): T;
|
|
85
86
|
trace<T> (name: string, options: TraceOptions & SpanOptions, fn: (span?: Span, done?: (error?: Error) => string) => T): T;
|
|
@@ -443,6 +444,11 @@ export declare interface TracerOptions {
|
|
|
443
444
|
* Whether to enable vulnerability deduplication
|
|
444
445
|
*/
|
|
445
446
|
deduplicationEnabled?: boolean
|
|
447
|
+
/**
|
|
448
|
+
* Whether to enable vulnerability redaction
|
|
449
|
+
* @default true
|
|
450
|
+
*/
|
|
451
|
+
redactionEnabled?: boolean
|
|
446
452
|
}
|
|
447
453
|
};
|
|
448
454
|
|
|
@@ -491,6 +497,7 @@ export declare interface TracerOptions {
|
|
|
491
497
|
/**
|
|
492
498
|
* If false, require a parent in order to trace.
|
|
493
499
|
* @default true
|
|
500
|
+
* @deprecated since version 4.0
|
|
494
501
|
*/
|
|
495
502
|
orphanable?: boolean
|
|
496
503
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.22.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"test:integration:cucumber": "mocha --colors --timeout 30000 \"integration-tests/cucumber/*.spec.js\"",
|
|
37
37
|
"test:integration:cypress": "mocha --colors --timeout 30000 \"integration-tests/cypress/*.spec.js\"",
|
|
38
38
|
"test:integration:playwright": "mocha --colors --timeout 30000 \"integration-tests/playwright/*.spec.js\"",
|
|
39
|
+
"test:integration:serverless": "mocha --colors --timeout 30000 \"integration-tests/serverless/*.spec.js\"",
|
|
39
40
|
"test:shimmer": "mocha --colors 'packages/datadog-shimmer/test/**/*.spec.js'",
|
|
40
41
|
"test:shimmer:ci": "nyc --no-clean --include 'packages/datadog-shimmer/src/**/*.js' -- npm run test:shimmer",
|
|
41
42
|
"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'",
|
|
@@ -65,11 +66,11 @@
|
|
|
65
66
|
"node": ">=14"
|
|
66
67
|
},
|
|
67
68
|
"dependencies": {
|
|
68
|
-
"@datadog/native-appsec": "^3.
|
|
69
|
+
"@datadog/native-appsec": "^3.2.0",
|
|
69
70
|
"@datadog/native-iast-rewriter": "2.0.1",
|
|
70
|
-
"@datadog/native-iast-taint-tracking": "^1.4.
|
|
71
|
-
"@datadog/native-metrics": "^
|
|
72
|
-
"@datadog/pprof": "^2.2.
|
|
71
|
+
"@datadog/native-iast-taint-tracking": "^1.4.1",
|
|
72
|
+
"@datadog/native-metrics": "^2.0.0",
|
|
73
|
+
"@datadog/pprof": "^2.2.1",
|
|
73
74
|
"@datadog/sketches-js": "^2.1.0",
|
|
74
75
|
"crypto-randomuuid": "^1.0.0",
|
|
75
76
|
"diagnostics_channel": "^1.1.0",
|
|
@@ -3,6 +3,7 @@ const { createCoverageMap } = require('istanbul-lib-coverage')
|
|
|
3
3
|
|
|
4
4
|
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
5
5
|
const shimmer = require('../../datadog-shimmer')
|
|
6
|
+
const log = require('../../dd-trace/src/log')
|
|
6
7
|
|
|
7
8
|
const testStartCh = channel('ci:cucumber:test:start')
|
|
8
9
|
const testFinishCh = channel('ci:cucumber:test:finish') // used for test steps too
|
|
@@ -175,6 +176,12 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
175
176
|
}
|
|
176
177
|
|
|
177
178
|
function pickleHook (PickleRunner) {
|
|
179
|
+
if (process.env.CUCUMBER_WORKER_ID) {
|
|
180
|
+
// Parallel mode is not supported
|
|
181
|
+
log.warn('Unable to initialize CI Visibility because Cucumber is running in parallel mode.')
|
|
182
|
+
return PickleRunner
|
|
183
|
+
}
|
|
184
|
+
|
|
178
185
|
const pl = PickleRunner.default
|
|
179
186
|
|
|
180
187
|
wrapRun(pl, false)
|
|
@@ -183,6 +190,12 @@ function pickleHook (PickleRunner) {
|
|
|
183
190
|
}
|
|
184
191
|
|
|
185
192
|
function testCaseHook (TestCaseRunner) {
|
|
193
|
+
if (process.env.CUCUMBER_WORKER_ID) {
|
|
194
|
+
// Parallel mode is not supported
|
|
195
|
+
log.warn('Unable to initialize CI Visibility because Cucumber is running in parallel mode.')
|
|
196
|
+
return TestCaseRunner
|
|
197
|
+
}
|
|
198
|
+
|
|
186
199
|
const pl = TestCaseRunner.default
|
|
187
200
|
|
|
188
201
|
wrapRun(pl, true)
|
|
@@ -4,6 +4,8 @@ const types = require('./types')
|
|
|
4
4
|
const { addHook, channel, AsyncResource } = require('../helpers/instrument')
|
|
5
5
|
const shimmer = require('../../../datadog-shimmer')
|
|
6
6
|
|
|
7
|
+
const nodeMajor = parseInt(process.versions.node.split('.')[0])
|
|
8
|
+
|
|
7
9
|
const patched = new WeakSet()
|
|
8
10
|
const instances = new WeakMap()
|
|
9
11
|
|
|
@@ -232,13 +234,15 @@ function patch (grpc) {
|
|
|
232
234
|
return grpc
|
|
233
235
|
}
|
|
234
236
|
|
|
235
|
-
|
|
237
|
+
if (nodeMajor <= 14) {
|
|
238
|
+
addHook({ name: 'grpc', versions: ['>=1.24.3'] }, patch)
|
|
236
239
|
|
|
237
|
-
addHook({ name: 'grpc', versions: ['>=1.24.3'], file: 'src/client.js' }, client => {
|
|
238
|
-
|
|
240
|
+
addHook({ name: 'grpc', versions: ['>=1.24.3'], file: 'src/client.js' }, client => {
|
|
241
|
+
shimmer.wrap(client, 'makeClientConstructor', createWrapMakeClientConstructor())
|
|
239
242
|
|
|
240
|
-
|
|
241
|
-
})
|
|
243
|
+
return client
|
|
244
|
+
})
|
|
245
|
+
}
|
|
242
246
|
|
|
243
247
|
addHook({ name: '@grpc/grpc-js', versions: ['>=1.0.3'] }, patch)
|
|
244
248
|
|
|
@@ -4,6 +4,8 @@ const types = require('./types')
|
|
|
4
4
|
const { channel, addHook, AsyncResource } = require('../helpers/instrument')
|
|
5
5
|
const shimmer = require('../../../datadog-shimmer')
|
|
6
6
|
|
|
7
|
+
const nodeMajor = parseInt(process.versions.node.split('.')[0])
|
|
8
|
+
|
|
7
9
|
const startChannel = channel('apm:grpc:server:request:start')
|
|
8
10
|
const errorChannel = channel('apm:grpc:server:request:error')
|
|
9
11
|
const updateChannel = channel('apm:grpc:server:request:update')
|
|
@@ -139,11 +141,13 @@ function isEmitter (obj) {
|
|
|
139
141
|
return typeof obj.emit === 'function' && typeof obj.once === 'function'
|
|
140
142
|
}
|
|
141
143
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
+
if (nodeMajor <= 14) {
|
|
145
|
+
addHook({ name: 'grpc', versions: ['>=1.24.3'], file: 'src/server.js' }, server => {
|
|
146
|
+
shimmer.wrap(server.Server.prototype, 'register', wrapRegister)
|
|
144
147
|
|
|
145
|
-
|
|
146
|
-
})
|
|
148
|
+
return server
|
|
149
|
+
})
|
|
150
|
+
}
|
|
147
151
|
|
|
148
152
|
addHook({ name: '@grpc/grpc-js', versions: ['>=1.0.3'], file: 'build/src/server.js' }, server => {
|
|
149
153
|
shimmer.wrap(server.Server.prototype, 'register', wrapRegister)
|
|
@@ -80,6 +80,7 @@ module.exports = {
|
|
|
80
80
|
'rhea': () => require('../rhea'),
|
|
81
81
|
'router': () => require('../router'),
|
|
82
82
|
'sharedb': () => require('../sharedb'),
|
|
83
|
+
'sequelize': () => require('../sequelize'),
|
|
83
84
|
'tedious': () => require('../tedious'),
|
|
84
85
|
'when': () => require('../when'),
|
|
85
86
|
'winston': () => require('../winston')
|
|
@@ -22,6 +22,10 @@ for (const packageName of names) {
|
|
|
22
22
|
|
|
23
23
|
hooks[packageName]()
|
|
24
24
|
|
|
25
|
+
if (!instrumentations[packageName]) {
|
|
26
|
+
return moduleExports
|
|
27
|
+
}
|
|
28
|
+
|
|
25
29
|
for (const { name, file, versions, hook } of instrumentations[packageName]) {
|
|
26
30
|
const fullFilename = filename(name, file)
|
|
27
31
|
|
|
@@ -101,6 +101,7 @@ function patch (http, methodName) {
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
function normalizeArgs (inputURL, inputOptions, cb) {
|
|
104
|
+
const originalUrl = inputURL
|
|
104
105
|
inputURL = normalizeOptions(inputURL)
|
|
105
106
|
|
|
106
107
|
const [callback, inputOptionsNormalized] = normalizeCallback(inputOptions, cb, inputURL)
|
|
@@ -108,7 +109,7 @@ function patch (http, methodName) {
|
|
|
108
109
|
normalizeHeaders(options)
|
|
109
110
|
const uri = url.format(options)
|
|
110
111
|
|
|
111
|
-
return { uri, options, callback }
|
|
112
|
+
return { uri, options, callback, originalUrl }
|
|
112
113
|
}
|
|
113
114
|
|
|
114
115
|
function combineOptions (inputURL, inputOptions) {
|
|
@@ -11,6 +11,7 @@ const startServerCh = channel('apm:http:server:request:start')
|
|
|
11
11
|
const exitServerCh = channel('apm:http:server:request:exit')
|
|
12
12
|
const errorServerCh = channel('apm:http:server:request:error')
|
|
13
13
|
const finishServerCh = channel('apm:http:server:request:finish')
|
|
14
|
+
const finishSetHeaderCh = channel('datadog:http:server:response:set-header:finish')
|
|
14
15
|
|
|
15
16
|
const requestFinishedSet = new WeakSet()
|
|
16
17
|
|
|
@@ -58,6 +59,9 @@ function wrapEmit (emit) {
|
|
|
58
59
|
// TODO: should this always return true ?
|
|
59
60
|
return this.listenerCount(eventName) > 0
|
|
60
61
|
}
|
|
62
|
+
if (finishSetHeaderCh.hasSubscribers) {
|
|
63
|
+
wrapSetHeader(res)
|
|
64
|
+
}
|
|
61
65
|
return emit.apply(this, arguments)
|
|
62
66
|
} catch (err) {
|
|
63
67
|
errorServerCh.publish(err)
|
|
@@ -70,3 +74,13 @@ function wrapEmit (emit) {
|
|
|
70
74
|
return emit.apply(this, arguments)
|
|
71
75
|
}
|
|
72
76
|
}
|
|
77
|
+
|
|
78
|
+
function wrapSetHeader (res) {
|
|
79
|
+
shimmer.wrap(res, 'setHeader', setHeader => {
|
|
80
|
+
return function (name, value) {
|
|
81
|
+
const setHeaderResult = setHeader.apply(this, arguments)
|
|
82
|
+
finishSetHeaderCh.publish({ name, value, res })
|
|
83
|
+
return setHeaderResult
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const shimmer = require('../../../datadog-shimmer')
|
|
4
4
|
const { addHook, channel, AsyncResource } = require('../helpers/instrument')
|
|
5
5
|
|
|
6
|
+
const connectChannel = channel('apm:http2:client:connect:start')
|
|
6
7
|
const startChannel = channel('apm:http2:client:request:start')
|
|
7
8
|
const finishChannel = channel('apm:http2:client:request:finish')
|
|
8
9
|
const errorChannel = channel('apm:http2:client:request:error')
|
|
@@ -52,6 +53,9 @@ function createWrapRequest (authority, options) {
|
|
|
52
53
|
|
|
53
54
|
function wrapConnect (connect) {
|
|
54
55
|
return function (authority, options) {
|
|
56
|
+
if (connectChannel.hasSubscribers) {
|
|
57
|
+
connectChannel.publish({ authority })
|
|
58
|
+
}
|
|
55
59
|
const session = connect.apply(this, arguments)
|
|
56
60
|
|
|
57
61
|
shimmer.wrap(session, 'request', createWrapRequest(authority, options))
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
+
const semver = require('semver')
|
|
3
|
+
|
|
2
4
|
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
3
5
|
const shimmer = require('../../datadog-shimmer')
|
|
4
6
|
const log = require('../../dd-trace/src/log')
|
|
7
|
+
const { version: ddTraceVersion } = require('../../../package.json')
|
|
5
8
|
const {
|
|
6
9
|
getCoveredFilenamesFromCoverage,
|
|
7
10
|
JEST_WORKER_TRACE_PAYLOAD_CODE,
|
|
8
11
|
JEST_WORKER_COVERAGE_PAYLOAD_CODE,
|
|
9
|
-
getTestLineStart
|
|
12
|
+
getTestLineStart,
|
|
13
|
+
getTestSuitePath,
|
|
14
|
+
getTestParametersString
|
|
10
15
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
16
|
+
const {
|
|
17
|
+
getFormattedJestTestParameters,
|
|
18
|
+
getJestTestName,
|
|
19
|
+
getJestSuitesToRun
|
|
20
|
+
} = require('../../datadog-plugin-jest/src/util')
|
|
11
21
|
|
|
12
22
|
const testSessionStartCh = channel('ci:jest:session:start')
|
|
13
23
|
const testSessionFinishCh = channel('ci:jest:session:finish')
|
|
@@ -34,13 +44,6 @@ let skippableSuites = []
|
|
|
34
44
|
let isCodeCoverageEnabled = false
|
|
35
45
|
let isSuitesSkippingEnabled = false
|
|
36
46
|
|
|
37
|
-
const {
|
|
38
|
-
getTestSuitePath,
|
|
39
|
-
getTestParametersString
|
|
40
|
-
} = require('../../dd-trace/src/plugins/util/test')
|
|
41
|
-
|
|
42
|
-
const { getFormattedJestTestParameters, getJestTestName } = require('../../datadog-plugin-jest/src/util')
|
|
43
|
-
|
|
44
47
|
const sessionAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
45
48
|
|
|
46
49
|
const specStatusToTestStatus = {
|
|
@@ -426,10 +429,7 @@ addHook({
|
|
|
426
429
|
const testPaths = await getTestPaths.apply(this, arguments)
|
|
427
430
|
const { tests } = testPaths
|
|
428
431
|
|
|
429
|
-
const filteredTests =
|
|
430
|
-
const relativePath = testPath.replace(`${rootDir}/`, '')
|
|
431
|
-
return !skippableSuites.includes(relativePath)
|
|
432
|
-
})
|
|
432
|
+
const filteredTests = getJestSuitesToRun(skippableSuites, tests, rootDir)
|
|
433
433
|
|
|
434
434
|
skippableSuites = []
|
|
435
435
|
|
|
@@ -451,6 +451,7 @@ addHook({
|
|
|
451
451
|
}, jestConfigSyncWrapper)
|
|
452
452
|
|
|
453
453
|
function jasmineAsyncInstallWraper (jasmineAsyncInstallExport, jestVersion) {
|
|
454
|
+
log.warn('jest-jasmine2 support is removed from dd-trace@v4. Consider changing to jest-circus as `testRunner`.')
|
|
454
455
|
return function (globalConfig, globalInput) {
|
|
455
456
|
globalInput._ddtrace = global._ddtrace
|
|
456
457
|
shimmer.wrap(globalInput.jasmine.Spec.prototype, 'execute', execute => function (onComplete) {
|
|
@@ -480,11 +481,13 @@ function jasmineAsyncInstallWraper (jasmineAsyncInstallExport, jestVersion) {
|
|
|
480
481
|
}
|
|
481
482
|
}
|
|
482
483
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
484
|
+
if (semver.lt(ddTraceVersion, '4.0.0')) {
|
|
485
|
+
addHook({
|
|
486
|
+
name: 'jest-jasmine2',
|
|
487
|
+
versions: ['>=24.8.0'],
|
|
488
|
+
file: 'build/jasmineAsyncInstall.js'
|
|
489
|
+
}, jasmineAsyncInstallWraper)
|
|
490
|
+
}
|
|
488
491
|
|
|
489
492
|
addHook({
|
|
490
493
|
name: 'jest-worker',
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
const { channel, addHook, AsyncResource } = require('./helpers/instrument')
|
|
6
6
|
const shimmer = require('../../datadog-shimmer')
|
|
7
|
+
const { MAJOR } = require('../../../version')
|
|
7
8
|
|
|
8
9
|
const startChannel = channel('apm:next:request:start')
|
|
9
10
|
const finishChannel = channel('apm:next:request:finish')
|
|
@@ -168,7 +169,11 @@ addHook({ name: 'next', versions: ['>=11.1 <13.2'], file: 'dist/server/next-serv
|
|
|
168
169
|
return nextServer
|
|
169
170
|
})
|
|
170
171
|
|
|
171
|
-
addHook({
|
|
172
|
+
addHook({
|
|
173
|
+
name: 'next',
|
|
174
|
+
versions: MAJOR >= 4 ? ['>=10.2 <11.1'] : ['>=9.5 <11.1'],
|
|
175
|
+
file: 'dist/next-server/server/next-server.js'
|
|
176
|
+
}, nextServer => {
|
|
172
177
|
const Server = nextServer.default
|
|
173
178
|
|
|
174
179
|
shimmer.wrap(Server.prototype, 'handleRequest', wrapHandleRequest)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
channel,
|
|
5
|
+
addHook,
|
|
6
|
+
AsyncResource
|
|
7
|
+
} = require('./helpers/instrument')
|
|
8
|
+
|
|
9
|
+
const shimmer = require('../../datadog-shimmer')
|
|
10
|
+
|
|
11
|
+
addHook({ name: 'sequelize', versions: ['>=4'] }, Sequelize => {
|
|
12
|
+
const startCh = channel('datadog:sequelize:query:start')
|
|
13
|
+
const finishCh = channel('datadog:sequelize:query:finish')
|
|
14
|
+
|
|
15
|
+
shimmer.wrap(Sequelize.prototype, 'query', query => {
|
|
16
|
+
return function (sql) {
|
|
17
|
+
if (!startCh.hasSubscribers) {
|
|
18
|
+
return query.apply(this, arguments)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
22
|
+
|
|
23
|
+
let dialect
|
|
24
|
+
if (this.options && this.options.dialect) {
|
|
25
|
+
dialect = this.options.dialect
|
|
26
|
+
} else if (this.dialect && this.dialect.name) {
|
|
27
|
+
dialect = this.dialect.name
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function onFinish () {
|
|
31
|
+
asyncResource.bind(function () {
|
|
32
|
+
finishCh.publish()
|
|
33
|
+
}, this).apply(this)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return asyncResource.bind(function () {
|
|
37
|
+
startCh.publish({
|
|
38
|
+
sql,
|
|
39
|
+
dialect
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
const promise = query.apply(this, arguments)
|
|
43
|
+
promise.then(onFinish, onFinish)
|
|
44
|
+
|
|
45
|
+
return promise
|
|
46
|
+
}, this).apply(this, arguments)
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
return Sequelize
|
|
51
|
+
})
|
|
@@ -11,11 +11,9 @@ class Amqp10ConsumerPlugin extends ConsumerPlugin {
|
|
|
11
11
|
const source = getShortName(link)
|
|
12
12
|
const address = getAddress(link)
|
|
13
13
|
|
|
14
|
-
this.startSpan(
|
|
15
|
-
service: this.config.service || `${this.tracer._service}-amqp`,
|
|
14
|
+
this.startSpan({
|
|
16
15
|
resource: ['receive', source].filter(v => v).join(' '),
|
|
17
16
|
type: 'worker',
|
|
18
|
-
kind: 'consumer',
|
|
19
17
|
meta: {
|
|
20
18
|
'amqp.link.source.address': source,
|
|
21
19
|
'amqp.link.role': 'receiver',
|
|
@@ -13,10 +13,8 @@ class Amqp10ProducerPlugin extends ProducerPlugin {
|
|
|
13
13
|
const address = getAddress(link)
|
|
14
14
|
const target = getShortName(link)
|
|
15
15
|
|
|
16
|
-
this.startSpan(
|
|
17
|
-
service: this.config.service || `${this.tracer._service}-amqp`,
|
|
16
|
+
this.startSpan({
|
|
18
17
|
resource: ['send', target].filter(v => v).join(' '),
|
|
19
|
-
kind: 'producer',
|
|
20
18
|
meta: {
|
|
21
19
|
'amqp.link.target.address': target,
|
|
22
20
|
'amqp.link.role': 'sender',
|
|
@@ -7,6 +7,7 @@ const { getResourceName } = require('./util')
|
|
|
7
7
|
|
|
8
8
|
class AmqplibClientPlugin extends ClientPlugin {
|
|
9
9
|
static get id () { return 'amqplib' }
|
|
10
|
+
static get type () { return 'messaging' }
|
|
10
11
|
static get operation () { return 'command' }
|
|
11
12
|
|
|
12
13
|
start ({ channel = {}, method, fields }) {
|
|
@@ -14,10 +15,10 @@ class AmqplibClientPlugin extends ClientPlugin {
|
|
|
14
15
|
if (method === 'basic.publish') return
|
|
15
16
|
|
|
16
17
|
const stream = (channel.connection && channel.connection.stream) || {}
|
|
17
|
-
const span = this.startSpan(
|
|
18
|
-
service: this.config.service ||
|
|
18
|
+
const span = this.startSpan(this.operationName(), {
|
|
19
|
+
service: this.config.service || this.serviceName(),
|
|
19
20
|
resource: getResourceName(method, fields),
|
|
20
|
-
kind:
|
|
21
|
+
kind: this.constructor.kind,
|
|
21
22
|
meta: {
|
|
22
23
|
'out.host': stream._host,
|
|
23
24
|
[CLIENT_PORT_KEY]: stream.remotePort,
|
|
@@ -13,11 +13,9 @@ class AmqplibConsumerPlugin extends ConsumerPlugin {
|
|
|
13
13
|
|
|
14
14
|
const childOf = extract(this.tracer, message)
|
|
15
15
|
|
|
16
|
-
this.startSpan(
|
|
16
|
+
this.startSpan({
|
|
17
17
|
childOf,
|
|
18
|
-
service: this.config.service || `${this.tracer._service}-amqp`,
|
|
19
18
|
resource: getResourceName(method, fields),
|
|
20
|
-
kind: 'consumer',
|
|
21
19
|
type: 'worker',
|
|
22
20
|
meta: {
|
|
23
21
|
'amqp.queue': fields.queue,
|
|
@@ -13,10 +13,8 @@ class AmqplibProducerPlugin extends ProducerPlugin {
|
|
|
13
13
|
if (method !== 'basic.publish') return
|
|
14
14
|
|
|
15
15
|
const stream = (channel.connection && channel.connection.stream) || {}
|
|
16
|
-
const span = this.startSpan(
|
|
17
|
-
service: this.config.service || `${this.tracer._service}-amqp`,
|
|
16
|
+
const span = this.startSpan({
|
|
18
17
|
resource: getResourceName(method, fields),
|
|
19
|
-
kind: 'producer',
|
|
20
18
|
meta: {
|
|
21
19
|
'out.host': stream._host,
|
|
22
20
|
[CLIENT_PORT_KEY]: stream.remotePort,
|
|
@@ -38,6 +38,8 @@ class BaseAwsSdkPlugin extends Plugin {
|
|
|
38
38
|
'service.name': serviceName,
|
|
39
39
|
'aws.operation': operation,
|
|
40
40
|
'aws.region': awsRegion,
|
|
41
|
+
'region': awsRegion,
|
|
42
|
+
'aws_service': awsService,
|
|
41
43
|
'aws.service': awsService,
|
|
42
44
|
'component': 'aws-sdk'
|
|
43
45
|
}
|
|
@@ -60,6 +62,7 @@ class BaseAwsSdkPlugin extends Plugin {
|
|
|
60
62
|
const { span } = store
|
|
61
63
|
if (!span) return
|
|
62
64
|
span.setTag('aws.region', region)
|
|
65
|
+
span.setTag('region', region)
|
|
63
66
|
})
|
|
64
67
|
|
|
65
68
|
this.addSub(`apm:aws:request:complete:${this.serviceIdentifier}`, ({ response }) => {
|
|
@@ -12,7 +12,8 @@ class CloudwatchLogs extends BaseAwsSdkPlugin {
|
|
|
12
12
|
|
|
13
13
|
return Object.assign(tags, {
|
|
14
14
|
'resource.name': `${operation} ${params.logGroupName}`,
|
|
15
|
-
'aws.cloudwatch.logs.log_group_name': params.logGroupName
|
|
15
|
+
'aws.cloudwatch.logs.log_group_name': params.logGroupName,
|
|
16
|
+
'loggroupname': params.logGroupName
|
|
16
17
|
})
|
|
17
18
|
}
|
|
18
19
|
}
|
|
@@ -12,7 +12,8 @@ class DynamoDb extends BaseAwsSdkPlugin {
|
|
|
12
12
|
if (params.TableName) {
|
|
13
13
|
Object.assign(tags, {
|
|
14
14
|
'resource.name': `${operation} ${params.TableName}`,
|
|
15
|
-
'aws.dynamodb.table_name': params.TableName
|
|
15
|
+
'aws.dynamodb.table_name': params.TableName,
|
|
16
|
+
'tablename': params.TableName
|
|
16
17
|
})
|
|
17
18
|
}
|
|
18
19
|
|
|
@@ -27,7 +28,8 @@ class DynamoDb extends BaseAwsSdkPlugin {
|
|
|
27
28
|
// also add span type to match serverless convention
|
|
28
29
|
Object.assign(tags, {
|
|
29
30
|
'resource.name': `${operation} ${tableName}`,
|
|
30
|
-
'aws.dynamodb.table_name': tableName
|
|
31
|
+
'aws.dynamodb.table_name': tableName,
|
|
32
|
+
'tablename': tableName
|
|
31
33
|
})
|
|
32
34
|
}
|
|
33
35
|
}
|
|
@@ -7,10 +7,11 @@ class EventBridge extends BaseAwsSdkPlugin {
|
|
|
7
7
|
|
|
8
8
|
generateTags (params, operation, response) {
|
|
9
9
|
if (!params || !params.source) return {}
|
|
10
|
-
|
|
10
|
+
const rulename = params.Name ? params.Name : ''
|
|
11
11
|
return {
|
|
12
|
-
'resource.name': `${operation} ${params.source}
|
|
13
|
-
'aws.eventbridge.source': params.source
|
|
12
|
+
'resource.name': operation ? `${operation} ${params.source}` : params.source,
|
|
13
|
+
'aws.eventbridge.source': `${params.source}`,
|
|
14
|
+
'rulename': `${rulename}`
|
|
14
15
|
}
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -12,7 +12,8 @@ class Redshift extends BaseAwsSdkPlugin {
|
|
|
12
12
|
|
|
13
13
|
return Object.assign(tags, {
|
|
14
14
|
'resource.name': `${operation} ${params.ClusterIdentifier}`,
|
|
15
|
-
'aws.redshift.cluster_identifier': params.ClusterIdentifier
|
|
15
|
+
'aws.redshift.cluster_identifier': params.ClusterIdentifier,
|
|
16
|
+
'clusteridentifier': params.ClusterIdentifier
|
|
16
17
|
})
|
|
17
18
|
}
|
|
18
19
|
}
|
|
@@ -9,10 +9,17 @@ class Sns extends BaseAwsSdkPlugin {
|
|
|
9
9
|
if (!params) return {}
|
|
10
10
|
|
|
11
11
|
if (!params.TopicArn && !(response.data && response.data.TopicArn)) return {}
|
|
12
|
+
const TopicArn = params.TopicArn || response.data.TopicArn
|
|
13
|
+
// Split the ARN into its parts
|
|
14
|
+
// ex.'arn:aws:sns:us-east-1:123456789012:my-topic'
|
|
15
|
+
const arnParts = TopicArn.split(':')
|
|
12
16
|
|
|
17
|
+
// Get the topic name from the last part of the ARN
|
|
18
|
+
const topicName = arnParts[arnParts.length - 1]
|
|
13
19
|
return {
|
|
14
20
|
'resource.name': `${operation} ${params.TopicArn || response.data.TopicArn}`,
|
|
15
|
-
'aws.sns.topic_arn':
|
|
21
|
+
'aws.sns.topic_arn': TopicArn,
|
|
22
|
+
'topicname': topicName
|
|
16
23
|
}
|
|
17
24
|
|
|
18
25
|
// TODO: should arn be sanitized or quantized in some way here,
|
|
@@ -59,10 +59,16 @@ class Sqs extends BaseAwsSdkPlugin {
|
|
|
59
59
|
const tags = {}
|
|
60
60
|
|
|
61
61
|
if (!params || (!params.QueueName && !params.QueueUrl)) return tags
|
|
62
|
+
// 'https://sqs.us-east-1.amazonaws.com/123456789012/my-queue';
|
|
63
|
+
let queueName = params.QueueName
|
|
64
|
+
if (params.QueueUrl) {
|
|
65
|
+
queueName = params.QueueUrl.split('/')[params.QueueUrl.split('/').length - 1]
|
|
66
|
+
}
|
|
62
67
|
|
|
63
68
|
Object.assign(tags, {
|
|
64
69
|
'resource.name': `${operation} ${params.QueueName || params.QueueUrl}`,
|
|
65
|
-
'aws.sqs.queue_name': params.QueueName || params.QueueUrl
|
|
70
|
+
'aws.sqs.queue_name': params.QueueName || params.QueueUrl,
|
|
71
|
+
'queuename': queueName
|
|
66
72
|
})
|
|
67
73
|
|
|
68
74
|
switch (operation) {
|
|
@@ -73,8 +73,8 @@ class CucumberPlugin extends CiPlugin {
|
|
|
73
73
|
.map(filename => getTestSuitePath(filename, this.sourceRoot))
|
|
74
74
|
|
|
75
75
|
const formattedCoverage = {
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
sessionId: this.testSuiteSpan.context()._traceId,
|
|
77
|
+
suiteId: this.testSuiteSpan.context()._spanId,
|
|
78
78
|
files: relativeCoverageFiles
|
|
79
79
|
}
|
|
80
80
|
|