dd-trace 5.0.0 → 5.2.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 +0 -3
- package/MIGRATING.md +15 -0
- package/README.md +11 -9
- package/package.json +4 -6
- package/packages/datadog-instrumentations/src/amqplib.js +1 -1
- package/packages/datadog-instrumentations/src/cucumber.js +3 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/jest.js +1 -0
- package/packages/datadog-instrumentations/src/mocha.js +9 -2
- package/packages/datadog-instrumentations/src/mquery.js +65 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +28 -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-cucumber/src/index.js +11 -7
- package/packages/datadog-plugin-cypress/src/plugin.js +60 -46
- package/packages/datadog-plugin-graphql/src/index.js +1 -6
- package/packages/datadog-plugin-grpc/src/util.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +7 -1
- package/packages/datadog-plugin-mocha/src/index.js +11 -2
- package/packages/datadog-plugin-playwright/src/index.js +2 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +3 -3
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +22 -17
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-randomness-analyzer.js +19 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +1 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +12 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
- package/packages/dd-trace/src/appsec/remote_config/manager.js +9 -8
- package/packages/dd-trace/src/appsec/reporter.js +2 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +4 -2
- package/packages/dd-trace/src/config.js +10 -6
- package/packages/dd-trace/src/datastreams/processor.js +30 -5
- package/packages/dd-trace/src/datastreams/writer.js +9 -0
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +25 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +1 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +9 -3
- package/packages/dd-trace/src/plugins/util/test.js +2 -0
- package/packages/dd-trace/src/plugins/util/web.js +1 -1
- package/packages/dd-trace/src/profiling/config.js +19 -5
- package/packages/dd-trace/src/telemetry/index.js +8 -3
- package/packages/dd-trace/src/telemetry/send-data.js +2 -2
- 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/scripts/st.js +105 -0
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
|
package/MIGRATING.md
CHANGED
|
@@ -4,6 +4,21 @@ This guide describes the steps to upgrade dd-trace from a major version to the
|
|
|
4
4
|
next. If you are having any issues related to migrating, please feel free to
|
|
5
5
|
open an issue or contact our [support](https://www.datadoghq.com/support/) team.
|
|
6
6
|
|
|
7
|
+
## 4.0 to 5.0
|
|
8
|
+
|
|
9
|
+
### Node 16 is no longer supported
|
|
10
|
+
|
|
11
|
+
Node.js 16 has reached EOL in September 2023 and is no longer supported. Generally
|
|
12
|
+
speaking, we highly recommend always keeping Node.js up to date regardless of
|
|
13
|
+
our support policy.
|
|
14
|
+
|
|
15
|
+
### Update `trace<T>` TypeScript declaration
|
|
16
|
+
|
|
17
|
+
The TypeScript declaration for `trace<T>` has been updated to enforce
|
|
18
|
+
that calls to `tracer.trace(name, fn)` must receive a function which takes at least
|
|
19
|
+
the span object. Previously the span was technically optional when it should not have
|
|
20
|
+
been as the span must be handled.
|
|
21
|
+
|
|
7
22
|
## 3.0 to 4.0
|
|
8
23
|
|
|
9
24
|
### Node 14 is no longer supported
|
package/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# `dd-trace`: Node.js APM Tracer Library
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/dd-trace)
|
|
4
|
+
[](https://www.npmjs.com/package/dd-trace/v/latest-node16)
|
|
5
|
+
[](https://www.npmjs.com/package/dd-trace/v/latest-node14)
|
|
5
6
|
[](https://codecov.io/gh/DataDog/dd-trace-js)
|
|
6
7
|
|
|
7
8
|
<img align="right" src="https://user-images.githubusercontent.com/551402/208212084-1d0c07e2-4135-4c61-b2da-8f2fddbc66ed.png" alt="Bits the dog JavaScript" width="200px"/>
|
|
@@ -28,24 +29,25 @@ Most of the documentation for `dd-trace` is available on these webpages:
|
|
|
28
29
|
| [`v1`](https://github.com/DataDog/dd-trace-js/tree/v1.x) |  | `>= v12` | **End of Life** | 2021-07-13 | 2022-02-25 |
|
|
29
30
|
| [`v2`](https://github.com/DataDog/dd-trace-js/tree/v2.x) |  | `>= v12` | **End of Life** | 2022-01-28 | 2023-08-15 |
|
|
30
31
|
| [`v3`](https://github.com/DataDog/dd-trace-js/tree/v3.x) |  | `>= v14` | **Maintenance** | 2022-08-15 | 2024-05-15 |
|
|
31
|
-
| [`v4`](https://github.com/DataDog/dd-trace-js/tree/v4.x) |  | `>= v16` | **
|
|
32
|
+
| [`v4`](https://github.com/DataDog/dd-trace-js/tree/v4.x) |  | `>= v16` | **Maintenance** | 2023-05-12 | 2025-01-11 |
|
|
33
|
+
| [`v5`](https://github.com/DataDog/dd-trace-js/tree/v5.x) |  | `>= v18` | **Current** | 2024-01-11 | Unknown |
|
|
32
34
|
|
|
33
|
-
We currently maintain
|
|
34
|
-
Features and bug fixes that are merged are released to the `
|
|
35
|
+
We currently maintain three release lines, namely `v5`, `v4` and `v3`.
|
|
36
|
+
Features and bug fixes that are merged are released to the `v5` line and, if appropriate, also the `v4` & `v3` line.
|
|
35
37
|
|
|
36
|
-
For any new projects it is recommended to use the `
|
|
38
|
+
For any new projects it is recommended to use the `v5` release line:
|
|
37
39
|
|
|
38
40
|
```sh
|
|
39
41
|
$ npm install dd-trace
|
|
40
42
|
$ yarn add dd-trace
|
|
41
43
|
```
|
|
42
44
|
|
|
43
|
-
However, existing projects that already use the `v3` release line, or projects that need to support EOL versions of Node.js, may continue to use these release lines.
|
|
45
|
+
However, existing projects that already use the `v4` & `v3` release line, or projects that need to support EOL versions of Node.js, may continue to use these release lines.
|
|
44
46
|
This is done by specifying the version when installing the package.
|
|
45
47
|
|
|
46
48
|
```sh
|
|
47
|
-
$ npm install dd-trace@
|
|
48
|
-
$ yarn add dd-trace@
|
|
49
|
+
$ npm install dd-trace@4
|
|
50
|
+
$ yarn add dd-trace@4
|
|
49
51
|
```
|
|
50
52
|
|
|
51
53
|
Any backwards-breaking functionality that is introduced into the library will result in an increase of the major version of the library and therefore a new release line.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.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:profiler": "mocha --colors --timeout 90000 \"integration-tests/profiler/*.spec.js\"",
|
|
39
40
|
"test:integration:serverless": "mocha --colors --timeout 30000 \"integration-tests/serverless/*.spec.js\"",
|
|
40
41
|
"test:integration:plugins": "mocha --colors --exit -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/datadog-plugin-@($(echo $PLUGINS))/test/integration-test/**/*.spec.js\"",
|
|
41
42
|
"test:unit:plugins": "mocha --colors --exit -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/datadog-instrumentations/test/@($(echo $PLUGINS)).spec.js\" \"packages/datadog-plugin-@($(echo $PLUGINS))/test/**/*.spec.js\" --exclude \"packages/datadog-plugin-@($(echo $PLUGINS))/test/integration-test/**/*.spec.js\"",
|
|
@@ -68,7 +69,7 @@
|
|
|
68
69
|
"node": ">=18"
|
|
69
70
|
},
|
|
70
71
|
"dependencies": {
|
|
71
|
-
"@datadog/native-appsec": "
|
|
72
|
+
"@datadog/native-appsec": "7.0.0",
|
|
72
73
|
"@datadog/native-iast-rewriter": "2.2.2",
|
|
73
74
|
"@datadog/native-iast-taint-tracking": "1.6.4",
|
|
74
75
|
"@datadog/native-metrics": "^2.0.0",
|
|
@@ -79,17 +80,14 @@
|
|
|
79
80
|
"crypto-randomuuid": "^1.0.0",
|
|
80
81
|
"dc-polyfill": "^0.1.2",
|
|
81
82
|
"ignore": "^5.2.4",
|
|
82
|
-
"import-in-the-middle": "^1.7.
|
|
83
|
+
"import-in-the-middle": "^1.7.3",
|
|
83
84
|
"int64-buffer": "^0.1.9",
|
|
84
85
|
"ipaddr.js": "^2.1.0",
|
|
85
86
|
"istanbul-lib-coverage": "3.2.0",
|
|
86
87
|
"jest-docblock": "^29.7.0",
|
|
87
88
|
"koalas": "^1.0.2",
|
|
88
89
|
"limiter": "1.1.5",
|
|
89
|
-
"lodash.kebabcase": "^4.1.1",
|
|
90
|
-
"lodash.pick": "^4.4.0",
|
|
91
90
|
"lodash.sortby": "^4.7.0",
|
|
92
|
-
"lodash.uniq": "^4.5.0",
|
|
93
91
|
"lru-cache": "^7.14.0",
|
|
94
92
|
"methods": "^1.1.2",
|
|
95
93
|
"module-details-from-path": "^1.0.3",
|
|
@@ -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')
|
|
@@ -44,6 +44,7 @@ const patched = new WeakSet()
|
|
|
44
44
|
let pickleByFile = {}
|
|
45
45
|
const pickleResultByFile = {}
|
|
46
46
|
let skippableSuites = []
|
|
47
|
+
let itrCorrelationId = ''
|
|
47
48
|
let isForcedToRun = false
|
|
48
49
|
let isUnskippable = false
|
|
49
50
|
|
|
@@ -102,7 +103,7 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
102
103
|
const testSuitePath = getTestSuitePath(testSuiteFullPath, process.cwd())
|
|
103
104
|
isForcedToRun = isUnskippable && skippableSuites.includes(testSuitePath)
|
|
104
105
|
|
|
105
|
-
testSuiteStartCh.publish({ testSuitePath, isUnskippable, isForcedToRun })
|
|
106
|
+
testSuiteStartCh.publish({ testSuitePath, isUnskippable, isForcedToRun, itrCorrelationId })
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
const testSourceLine = this.gherkinDocument &&
|
|
@@ -304,6 +305,7 @@ addHook({
|
|
|
304
305
|
this.pickleIds = picklesToRun
|
|
305
306
|
|
|
306
307
|
skippedSuites = Array.from(filteredPickles.skippedSuites)
|
|
308
|
+
itrCorrelationId = skippableResponse.itrCorrelationId
|
|
307
309
|
}
|
|
308
310
|
|
|
309
311
|
pickleByFile = getPickleByFile(this)
|
|
@@ -73,6 +73,7 @@ module.exports = {
|
|
|
73
73
|
'mongodb': () => require('../mongodb'),
|
|
74
74
|
'mongodb-core': () => require('../mongodb-core'),
|
|
75
75
|
'mongoose': () => require('../mongoose'),
|
|
76
|
+
'mquery': () => require('../mquery'),
|
|
76
77
|
'mysql': () => require('../mysql'),
|
|
77
78
|
'mysql2': () => require('../mysql2'),
|
|
78
79
|
'net': () => require('../net'),
|
|
@@ -53,6 +53,7 @@ let isSuitesSkipped = false
|
|
|
53
53
|
let skippedSuites = []
|
|
54
54
|
const unskippableSuites = []
|
|
55
55
|
let isForcedToRun = false
|
|
56
|
+
let itrCorrelationId = ''
|
|
56
57
|
|
|
57
58
|
function getSuitesByTestFile (root) {
|
|
58
59
|
const suitesByTestFile = {}
|
|
@@ -191,7 +192,12 @@ function mochaHook (Runner) {
|
|
|
191
192
|
const isUnskippable = unskippableSuites.includes(suite.file)
|
|
192
193
|
isForcedToRun = isUnskippable && suitesToSkip.includes(getTestSuitePath(suite.file, process.cwd()))
|
|
193
194
|
asyncResource.runInAsyncScope(() => {
|
|
194
|
-
testSuiteStartCh.publish({
|
|
195
|
+
testSuiteStartCh.publish({
|
|
196
|
+
testSuite: suite.file,
|
|
197
|
+
isUnskippable,
|
|
198
|
+
isForcedToRun,
|
|
199
|
+
itrCorrelationId
|
|
200
|
+
})
|
|
195
201
|
})
|
|
196
202
|
}
|
|
197
203
|
})
|
|
@@ -395,11 +401,12 @@ addHook({
|
|
|
395
401
|
}
|
|
396
402
|
})
|
|
397
403
|
|
|
398
|
-
const onReceivedSkippableSuites = ({ err, skippableSuites }) => {
|
|
404
|
+
const onReceivedSkippableSuites = ({ err, skippableSuites, itrCorrelationId: responseItrCorrelationId }) => {
|
|
399
405
|
if (err) {
|
|
400
406
|
suitesToSkip = []
|
|
401
407
|
} else {
|
|
402
408
|
suitesToSkip = skippableSuites
|
|
409
|
+
itrCorrelationId = responseItrCorrelationId
|
|
403
410
|
}
|
|
404
411
|
// We remove the suites that we skip through ITR
|
|
405
412
|
const filteredSuites = getFilteredSuites(runner.suite.suites)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const dc = require('dc-polyfill')
|
|
4
|
+
const {
|
|
5
|
+
channel,
|
|
6
|
+
addHook
|
|
7
|
+
} = require('./helpers/instrument')
|
|
8
|
+
const shimmer = require('../../datadog-shimmer')
|
|
9
|
+
|
|
10
|
+
const prepareCh = channel('datadog:mquery:filter:prepare')
|
|
11
|
+
const tracingCh = dc.tracingChannel('datadog:mquery:filter')
|
|
12
|
+
|
|
13
|
+
const methods = [
|
|
14
|
+
'find',
|
|
15
|
+
'findOne',
|
|
16
|
+
'findOneAndRemove',
|
|
17
|
+
'findOneAndDelete',
|
|
18
|
+
'count',
|
|
19
|
+
'distinct',
|
|
20
|
+
'where'
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
const methodsOptionalArgs = ['findOneAndUpdate']
|
|
24
|
+
|
|
25
|
+
function getFilters (args, methodName) {
|
|
26
|
+
const [arg0, arg1] = args
|
|
27
|
+
|
|
28
|
+
const filters = arg0 && typeof arg0 === 'object' ? [arg0] : []
|
|
29
|
+
|
|
30
|
+
if (arg1 && typeof arg1 === 'object' && methodsOptionalArgs.includes(methodName)) {
|
|
31
|
+
filters.push(arg1)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return filters
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
addHook({
|
|
38
|
+
name: 'mquery',
|
|
39
|
+
versions: ['>=5.0.0']
|
|
40
|
+
}, Query => {
|
|
41
|
+
[...methods, ...methodsOptionalArgs].forEach(methodName => {
|
|
42
|
+
if (!(methodName in Query.prototype)) return
|
|
43
|
+
|
|
44
|
+
shimmer.wrap(Query.prototype, methodName, method => {
|
|
45
|
+
return function () {
|
|
46
|
+
if (prepareCh.hasSubscribers) {
|
|
47
|
+
const filters = getFilters(arguments, methodName)
|
|
48
|
+
if (filters?.length) {
|
|
49
|
+
prepareCh.publish({ filters })
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return method.apply(this, arguments)
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
shimmer.wrap(Query.prototype, 'exec', originalExec => {
|
|
59
|
+
return function wrappedExec () {
|
|
60
|
+
return tracingCh.tracePromise(originalExec, {}, this, arguments)
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
return Query
|
|
65
|
+
})
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
+
const {
|
|
3
|
+
CONTEXT_PROPAGATION_KEY
|
|
4
|
+
} = require('../../../dd-trace/src/datastreams/processor')
|
|
5
|
+
const { encodePathwayContext } = require('../../../dd-trace/src/datastreams/pathway')
|
|
2
6
|
const log = require('../../../dd-trace/src/log')
|
|
3
7
|
const BaseAwsSdkPlugin = require('../base')
|
|
8
|
+
|
|
4
9
|
class Kinesis extends BaseAwsSdkPlugin {
|
|
5
10
|
static get id () { return 'kinesis' }
|
|
6
11
|
static get peerServicePrecursors () { return ['streamname'] }
|
|
@@ -37,8 +42,9 @@ class Kinesis extends BaseAwsSdkPlugin {
|
|
|
37
42
|
if (!request.params) {
|
|
38
43
|
return
|
|
39
44
|
}
|
|
40
|
-
|
|
41
45
|
const traceData = {}
|
|
46
|
+
|
|
47
|
+
// inject data with DD context
|
|
42
48
|
this.tracer.inject(span, 'text_map', traceData)
|
|
43
49
|
let injectPath
|
|
44
50
|
if (request.params.Records && request.params.Records.length > 0) {
|
|
@@ -49,9 +55,30 @@ class Kinesis extends BaseAwsSdkPlugin {
|
|
|
49
55
|
log.error('No valid payload passed, unable to pass trace context')
|
|
50
56
|
return
|
|
51
57
|
}
|
|
58
|
+
|
|
52
59
|
const parsedData = this._tryParse(injectPath.Data)
|
|
53
60
|
if (parsedData) {
|
|
54
61
|
parsedData._datadog = traceData
|
|
62
|
+
|
|
63
|
+
// set DSM hash if enabled
|
|
64
|
+
if (this.config.dsmEnabled) {
|
|
65
|
+
// get payload size of request data
|
|
66
|
+
const payloadSize = Buffer.from(JSON.stringify(parsedData)).byteLength
|
|
67
|
+
let stream
|
|
68
|
+
// users can optionally use either stream name or stream arn
|
|
69
|
+
if (request.params && request.params.StreamArn) {
|
|
70
|
+
stream = request.params.StreamArn
|
|
71
|
+
} else if (request.params && request.params.StreamName) {
|
|
72
|
+
stream = request.params.StreamName
|
|
73
|
+
}
|
|
74
|
+
const dataStreamsContext = this.tracer
|
|
75
|
+
.setCheckpoint(['direction:out', `topic:${stream}`, 'type:kinesis'], span, payloadSize)
|
|
76
|
+
if (dataStreamsContext) {
|
|
77
|
+
const pathwayCtx = encodePathwayContext(dataStreamsContext)
|
|
78
|
+
parsedData._datadog[CONTEXT_PROPAGATION_KEY] = pathwayCtx.toJSON()
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
55
82
|
const finalData = Buffer.from(JSON.stringify(parsedData))
|
|
56
83
|
const byteSize = finalData.length
|
|
57
84
|
// Kinesis max payload size is 1MB
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
+
const { CONTEXT_PROPAGATION_KEY, getHeadersSize } = require('../../../dd-trace/src/datastreams/processor')
|
|
3
|
+
const { encodePathwayContext } = require('../../../dd-trace/src/datastreams/pathway')
|
|
2
4
|
const log = require('../../../dd-trace/src/log')
|
|
3
5
|
const BaseAwsSdkPlugin = require('../base')
|
|
4
6
|
|
|
@@ -11,6 +13,7 @@ class Sns extends BaseAwsSdkPlugin {
|
|
|
11
13
|
|
|
12
14
|
if (!params.TopicArn && !(response.data && response.data.TopicArn)) return {}
|
|
13
15
|
const TopicArn = params.TopicArn || response.data.TopicArn
|
|
16
|
+
|
|
14
17
|
// Split the ARN into its parts
|
|
15
18
|
// ex.'arn:aws:sns:us-east-1:123456789012:my-topic'
|
|
16
19
|
const arnParts = TopicArn.split(':')
|
|
@@ -72,10 +75,25 @@ class Sns extends BaseAwsSdkPlugin {
|
|
|
72
75
|
}
|
|
73
76
|
const ddInfo = {}
|
|
74
77
|
this.tracer.inject(span, 'text_map', ddInfo)
|
|
78
|
+
// add ddInfo before checking DSM so we can include DD attributes in payload size
|
|
75
79
|
params.MessageAttributes._datadog = {
|
|
76
80
|
DataType: 'Binary',
|
|
77
|
-
BinaryValue:
|
|
81
|
+
BinaryValue: ddInfo
|
|
82
|
+
}
|
|
83
|
+
if (this.config.dsmEnabled) {
|
|
84
|
+
const payloadSize = getHeadersSize({
|
|
85
|
+
Message: params.Message,
|
|
86
|
+
MessageAttributes: params.MessageAttributes
|
|
87
|
+
})
|
|
88
|
+
const dataStreamsContext = this.tracer
|
|
89
|
+
.setCheckpoint(['direction:out', `topic:${params.TopicArn}`, 'type:sns'], span, payloadSize)
|
|
90
|
+
if (dataStreamsContext) {
|
|
91
|
+
const pathwayCtx = encodePathwayContext(dataStreamsContext)
|
|
92
|
+
ddInfo[CONTEXT_PROPAGATION_KEY] = pathwayCtx.toJSON()
|
|
93
|
+
}
|
|
78
94
|
}
|
|
95
|
+
// BINARY types are automatically base64 encoded
|
|
96
|
+
params.MessageAttributes._datadog.BinaryValue = Buffer.from(JSON.stringify(ddInfo))
|
|
79
97
|
}
|
|
80
98
|
}
|
|
81
99
|
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
const log = require('../../../dd-trace/src/log')
|
|
4
4
|
const BaseAwsSdkPlugin = require('../base')
|
|
5
5
|
const { storage } = require('../../../datadog-core')
|
|
6
|
+
const { CONTEXT_PROPAGATION_KEY, getHeadersSize } = require('../../../dd-trace/src/datastreams/processor')
|
|
7
|
+
const { encodePathwayContext } = require('../../../dd-trace/src/datastreams/pathway')
|
|
6
8
|
|
|
7
9
|
class Sqs extends BaseAwsSdkPlugin {
|
|
8
10
|
static get id () { return 'sqs' }
|
|
@@ -19,20 +21,27 @@ class Sqs extends BaseAwsSdkPlugin {
|
|
|
19
21
|
const { request, response } = obj
|
|
20
22
|
const store = storage.getStore()
|
|
21
23
|
const plugin = this
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
+
const contextExtraction = this.responseExtract(request.params, request.operation, response)
|
|
25
|
+
let span
|
|
26
|
+
let parsedMessageAttributes
|
|
27
|
+
if (contextExtraction && contextExtraction.datadogContext) {
|
|
24
28
|
obj.needsFinish = true
|
|
25
29
|
const options = {
|
|
26
|
-
childOf:
|
|
30
|
+
childOf: contextExtraction.datadogContext,
|
|
27
31
|
tags: Object.assign(
|
|
28
32
|
{},
|
|
29
33
|
this.requestTags.get(request) || {},
|
|
30
34
|
{ 'span.kind': 'server' }
|
|
31
35
|
)
|
|
32
36
|
}
|
|
33
|
-
|
|
37
|
+
parsedMessageAttributes = contextExtraction.parsedAttributes
|
|
38
|
+
span = plugin.tracer.startSpan('aws.response', options)
|
|
34
39
|
this.enter(span, store)
|
|
35
40
|
}
|
|
41
|
+
// extract DSM context after as we might not have a parent-child but may have a DSM context
|
|
42
|
+
this.responseExtractDSMContext(
|
|
43
|
+
request.operation, request.params, response, span ?? null, parsedMessageAttributes ?? null
|
|
44
|
+
)
|
|
36
45
|
})
|
|
37
46
|
|
|
38
47
|
this.addSub('apm:aws:response:finish:sqs', err => {
|
|
@@ -133,19 +142,69 @@ class Sqs extends BaseAwsSdkPlugin {
|
|
|
133
142
|
|
|
134
143
|
const datadogAttribute = message.MessageAttributes._datadog
|
|
135
144
|
|
|
145
|
+
const parsedAttributes = this.parseDatadogAttributes(datadogAttribute)
|
|
146
|
+
if (parsedAttributes) {
|
|
147
|
+
return {
|
|
148
|
+
datadogContext: this.tracer.extract('text_map', parsedAttributes),
|
|
149
|
+
parsedAttributes: parsedAttributes
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
parseDatadogAttributes (attributes) {
|
|
136
155
|
try {
|
|
137
|
-
if (
|
|
138
|
-
const textMap =
|
|
139
|
-
return
|
|
140
|
-
} else if (
|
|
141
|
-
const buffer = Buffer.from(
|
|
142
|
-
return
|
|
156
|
+
if (attributes.StringValue) {
|
|
157
|
+
const textMap = attributes.StringValue
|
|
158
|
+
return JSON.parse(textMap)
|
|
159
|
+
} else if (attributes.Type === 'Binary') {
|
|
160
|
+
const buffer = Buffer.from(attributes.Value, 'base64')
|
|
161
|
+
return JSON.parse(buffer)
|
|
143
162
|
}
|
|
144
163
|
} catch (e) {
|
|
145
164
|
log.error(e)
|
|
146
165
|
}
|
|
147
166
|
}
|
|
148
167
|
|
|
168
|
+
responseExtractDSMContext (operation, params, response, span, parsedAttributes) {
|
|
169
|
+
if (!this.config.dsmEnabled) return
|
|
170
|
+
if (operation !== 'receiveMessage') return
|
|
171
|
+
if (!response || !response.Messages || !response.Messages[0]) return
|
|
172
|
+
|
|
173
|
+
// we only want to set the payloadSize on the span if we have one message
|
|
174
|
+
span = response.Messages.length > 1 ? null : span
|
|
175
|
+
|
|
176
|
+
response.Messages.forEach(message => {
|
|
177
|
+
// we may have already parsed the message attributes when extracting trace context
|
|
178
|
+
if (!parsedAttributes) {
|
|
179
|
+
if (message.Body) {
|
|
180
|
+
try {
|
|
181
|
+
const body = JSON.parse(message.Body)
|
|
182
|
+
|
|
183
|
+
// SNS to SQS
|
|
184
|
+
if (body.Type === 'Notification') {
|
|
185
|
+
message = body
|
|
186
|
+
}
|
|
187
|
+
} catch (e) {
|
|
188
|
+
// SQS to SQS
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (message.MessageAttributes && message.MessageAttributes._datadog) {
|
|
192
|
+
parsedAttributes = this.parseDatadogAttributes(message.MessageAttributes._datadog)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (parsedAttributes && parsedAttributes[CONTEXT_PROPAGATION_KEY]) {
|
|
196
|
+
const payloadSize = getHeadersSize({
|
|
197
|
+
Body: message.Body,
|
|
198
|
+
MessageAttributes: message.MessageAttributes
|
|
199
|
+
})
|
|
200
|
+
const queue = params.QueueUrl.split('/').pop()
|
|
201
|
+
this.tracer.decodeDataStreamsContext(Buffer.from(parsedAttributes[CONTEXT_PROPAGATION_KEY]))
|
|
202
|
+
this.tracer
|
|
203
|
+
.setCheckpoint(['direction:in', `topic:${queue}`, 'type:sqs'], span, payloadSize)
|
|
204
|
+
}
|
|
205
|
+
})
|
|
206
|
+
}
|
|
207
|
+
|
|
149
208
|
requestInject (span, request) {
|
|
150
209
|
const operation = request.operation
|
|
151
210
|
if (operation === 'sendMessage') {
|
|
@@ -164,6 +223,20 @@ class Sqs extends BaseAwsSdkPlugin {
|
|
|
164
223
|
DataType: 'String',
|
|
165
224
|
StringValue: JSON.stringify(ddInfo)
|
|
166
225
|
}
|
|
226
|
+
if (this.config.dsmEnabled) {
|
|
227
|
+
const payloadSize = getHeadersSize({
|
|
228
|
+
Body: request.params.MessageBody,
|
|
229
|
+
MessageAttributes: request.params.MessageAttributes
|
|
230
|
+
})
|
|
231
|
+
const queue = request.params.QueueUrl.split('/').pop()
|
|
232
|
+
const dataStreamsContext = this.tracer
|
|
233
|
+
.setCheckpoint(['direction:out', `topic:${queue}`, 'type:sqs'], span, payloadSize)
|
|
234
|
+
if (dataStreamsContext) {
|
|
235
|
+
const pathwayCtx = encodePathwayContext(dataStreamsContext)
|
|
236
|
+
ddInfo[CONTEXT_PROPAGATION_KEY] = pathwayCtx.toJSON()
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
request.params.MessageAttributes._datadog.StringValue = JSON.stringify(ddInfo)
|
|
167
240
|
}
|
|
168
241
|
}
|
|
169
242
|
}
|
|
@@ -13,7 +13,8 @@ const {
|
|
|
13
13
|
addIntelligentTestRunnerSpanTags,
|
|
14
14
|
TEST_ITR_UNSKIPPABLE,
|
|
15
15
|
TEST_ITR_FORCED_RUN,
|
|
16
|
-
TEST_CODE_OWNERS
|
|
16
|
+
TEST_CODE_OWNERS,
|
|
17
|
+
ITR_CORRELATION_ID
|
|
17
18
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
18
19
|
const { RESOURCE_NAME } = require('../../../ext/tags')
|
|
19
20
|
const { COMPONENT, ERROR_MESSAGE } = require('../../dd-trace/src/constants')
|
|
@@ -74,7 +75,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
74
75
|
this.tracer._exporter.flush()
|
|
75
76
|
})
|
|
76
77
|
|
|
77
|
-
this.addSub('ci:cucumber:test-suite:start', ({ testSuitePath, isUnskippable, isForcedToRun }) => {
|
|
78
|
+
this.addSub('ci:cucumber:test-suite:start', ({ testSuitePath, isUnskippable, isForcedToRun, itrCorrelationId }) => {
|
|
78
79
|
const testSuiteMetadata = getTestSuiteCommonTags(
|
|
79
80
|
this.command,
|
|
80
81
|
this.frameworkVersion,
|
|
@@ -89,6 +90,9 @@ class CucumberPlugin extends CiPlugin {
|
|
|
89
90
|
this.telemetry.count(TELEMETRY_ITR_FORCED_TO_RUN, { testLevel: 'suite' })
|
|
90
91
|
testSuiteMetadata[TEST_ITR_FORCED_RUN] = 'true'
|
|
91
92
|
}
|
|
93
|
+
if (itrCorrelationId) {
|
|
94
|
+
testSuiteMetadata[ITR_CORRELATION_ID] = itrCorrelationId
|
|
95
|
+
}
|
|
92
96
|
this.testSuiteSpan = this.tracer.startSpan('cucumber.test_suite', {
|
|
93
97
|
childOf: this.testModuleSpan,
|
|
94
98
|
tags: {
|
|
@@ -169,12 +173,12 @@ class CucumberPlugin extends CiPlugin {
|
|
|
169
173
|
}
|
|
170
174
|
|
|
171
175
|
span.finish()
|
|
172
|
-
this.telemetry.ciVisEvent(
|
|
173
|
-
TELEMETRY_EVENT_FINISHED,
|
|
174
|
-
'test',
|
|
175
|
-
{ hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
|
|
176
|
-
)
|
|
177
176
|
if (!isStep) {
|
|
177
|
+
this.telemetry.ciVisEvent(
|
|
178
|
+
TELEMETRY_EVENT_FINISHED,
|
|
179
|
+
'test',
|
|
180
|
+
{ hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
|
|
181
|
+
)
|
|
178
182
|
finishAllTraceSpans(span)
|
|
179
183
|
}
|
|
180
184
|
})
|