dd-trace 5.86.0 → 5.88.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 +60 -32
- package/ext/exporters.d.ts +1 -0
- package/ext/exporters.js +1 -0
- package/index.d.ts +243 -7
- package/package.json +9 -6
- package/packages/datadog-instrumentations/src/ai.js +54 -90
- package/packages/datadog-instrumentations/src/cucumber.js +14 -0
- package/packages/datadog-instrumentations/src/helpers/hook.js +17 -11
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +55 -14
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +15 -13
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/ai.js +103 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/bullmq.js +108 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/transformer.js +21 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +138 -12
- package/packages/datadog-instrumentations/src/http/client.js +119 -1
- package/packages/datadog-instrumentations/src/jest.js +179 -15
- package/packages/datadog-instrumentations/src/kafkajs.js +20 -17
- package/packages/datadog-instrumentations/src/mocha/utils.js +6 -0
- package/packages/datadog-instrumentations/src/mysql2.js +131 -64
- package/packages/datadog-instrumentations/src/playwright.js +9 -1
- package/packages/datadog-instrumentations/src/stripe.js +92 -0
- package/packages/datadog-instrumentations/src/vitest.js +11 -0
- package/packages/datadog-plugin-amqplib/src/consumer.js +14 -10
- package/packages/datadog-plugin-amqplib/src/producer.js +23 -19
- package/packages/datadog-plugin-azure-functions/src/index.js +53 -37
- package/packages/datadog-plugin-bullmq/src/consumer.js +33 -11
- package/packages/datadog-plugin-bullmq/src/producer.js +60 -31
- package/packages/datadog-plugin-cucumber/src/index.js +9 -6
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +33 -0
- package/packages/datadog-plugin-cypress/src/support.js +48 -8
- package/packages/datadog-plugin-jest/src/index.js +12 -2
- package/packages/datadog-plugin-jest/src/util.js +2 -1
- package/packages/datadog-plugin-kafkajs/src/consumer.js +22 -12
- package/packages/datadog-plugin-kafkajs/src/producer.js +33 -22
- package/packages/datadog-plugin-mocha/src/index.js +9 -6
- package/packages/datadog-plugin-playwright/src/index.js +10 -6
- package/packages/datadog-plugin-vitest/src/index.js +13 -8
- package/packages/dd-trace/src/appsec/addresses.js +11 -0
- package/packages/dd-trace/src/appsec/channels.js +5 -1
- package/packages/dd-trace/src/appsec/downstream_requests.js +302 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/ssrf-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/unvalidated-redirect-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +4 -5
- package/packages/dd-trace/src/appsec/iast/path-line.js +36 -25
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +3 -4
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +3 -2
- package/packages/dd-trace/src/appsec/index.js +103 -0
- package/packages/dd-trace/src/appsec/rasp/ssrf.js +66 -4
- package/packages/dd-trace/src/azure_metadata.js +0 -2
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +14 -1
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +2 -0
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +1 -1
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -1
- package/packages/dd-trace/src/ci-visibility/requests/request.js +236 -0
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +1 -1
- package/packages/dd-trace/src/config/defaults.js +148 -195
- package/packages/dd-trace/src/config/helper.js +43 -1
- package/packages/dd-trace/src/config/index.js +42 -14
- package/packages/dd-trace/src/config/supported-configurations.json +4115 -510
- package/packages/dd-trace/src/constants.js +0 -2
- package/packages/dd-trace/src/crashtracking/crashtracker.js +10 -3
- package/packages/dd-trace/src/datastreams/pathway.js +22 -3
- package/packages/dd-trace/src/datastreams/processor.js +14 -1
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +47 -2
- package/packages/dd-trace/src/debugger/devtools_client/index.js +75 -23
- package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +23 -1
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +3 -3
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +168 -36
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +18 -0
- package/packages/dd-trace/src/encode/agentless-json.js +141 -0
- package/packages/dd-trace/src/exporter.js +2 -0
- package/packages/dd-trace/src/exporters/agent/writer.js +22 -8
- package/packages/dd-trace/src/exporters/agentless/index.js +89 -0
- package/packages/dd-trace/src/exporters/agentless/writer.js +184 -0
- package/packages/dd-trace/src/exporters/common/agents.js +1 -1
- package/packages/dd-trace/src/exporters/common/request.js +4 -4
- package/packages/dd-trace/src/llmobs/constants/writers.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/ai/index.js +5 -3
- package/packages/dd-trace/src/llmobs/sdk.js +34 -5
- package/packages/dd-trace/src/opentelemetry/context_manager.js +19 -46
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +3 -4
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +3 -5
- package/packages/dd-trace/src/opentracing/span.js +6 -4
- package/packages/dd-trace/src/plugins/ci_plugin.js +57 -5
- package/packages/dd-trace/src/plugins/database.js +57 -45
- package/packages/dd-trace/src/plugins/outbound.js +27 -2
- package/packages/dd-trace/src/plugins/tracing.js +39 -4
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +7 -0
- package/packages/dd-trace/src/plugins/util/test.js +48 -0
- package/packages/dd-trace/src/plugins/util/web.js +8 -7
- package/packages/dd-trace/src/profiling/exporter_cli.js +1 -0
- package/packages/dd-trace/src/propagation-hash/index.js +145 -0
- package/packages/dd-trace/src/proxy.js +4 -0
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +1 -1
- package/packages/dd-trace/src/startup-log.js +3 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/bullmq.json +0 -106
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +0 -741
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +0 -11
- package/packages/dd-trace/src/plugins/util/serverless.js +0 -8
- package/packages/dd-trace/src/scope/noop/scope.js +0 -21
|
@@ -6,6 +6,22 @@ const shimmer = require('../../datadog-shimmer')
|
|
|
6
6
|
const satisfies = require('../../../vendor/dist/semifies')
|
|
7
7
|
const { channel, addHook } = require('./helpers/instrument')
|
|
8
8
|
|
|
9
|
+
/** @type {WeakMap<object, Function>} */
|
|
10
|
+
const wrappedOnResult = new WeakMap()
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {unknown} sql
|
|
14
|
+
* @returns {string|undefined}
|
|
15
|
+
*/
|
|
16
|
+
function resolveSqlString (sql) {
|
|
17
|
+
return typeof sql === 'string' ? sql : /** @type {{ sql?: string }} */ (sql)?.sql
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {Function} Connection
|
|
22
|
+
* @param {string} version
|
|
23
|
+
* @returns {Function}
|
|
24
|
+
*/
|
|
9
25
|
function wrapConnection (Connection, version) {
|
|
10
26
|
const startCh = channel('apm:mysql2:query:start')
|
|
11
27
|
const finishCh = channel('apm:mysql2:query:finish')
|
|
@@ -19,15 +35,27 @@ function wrapConnection (Connection, version) {
|
|
|
19
35
|
shimmer.wrap(Connection.prototype, 'addCommand', addCommand => function (cmd) {
|
|
20
36
|
if (!startCh.hasSubscribers) return addCommand.apply(this, arguments)
|
|
21
37
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
38
|
+
const command = /** @type {{ execute?: Function, constructor?: { name?: string } }} */ (cmd)
|
|
39
|
+
if (typeof command.execute !== 'function') return addCommand.apply(this, arguments)
|
|
40
|
+
|
|
41
|
+
const name = command.constructor?.name
|
|
42
|
+
const isQuery = name === 'Execute' || name === 'Query'
|
|
25
43
|
const ctx = {}
|
|
26
44
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
45
|
+
if (isQuery) {
|
|
46
|
+
command.execute = wrapExecute(command, command.execute, ctx, this.config)
|
|
47
|
+
|
|
48
|
+
return commandAddCh.runStores(ctx, addCommand, this, ...arguments)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
wrapCommandOnResult(command, ctx)
|
|
52
|
+
|
|
53
|
+
command.execute = shimmer.wrapFunction(
|
|
54
|
+
command.execute,
|
|
55
|
+
execute => function executeWithTrace (_packet_, _connection_) {
|
|
56
|
+
return commandStartCh.runStores(ctx, execute, this, ...arguments)
|
|
57
|
+
}
|
|
58
|
+
)
|
|
31
59
|
|
|
32
60
|
return commandAddCh.runStores(ctx, addCommand, this, ...arguments)
|
|
33
61
|
})
|
|
@@ -35,12 +63,11 @@ function wrapConnection (Connection, version) {
|
|
|
35
63
|
shimmer.wrap(Connection.prototype, 'query', query => function (sql, values, cb) {
|
|
36
64
|
if (!startOuterQueryCh.hasSubscribers) return query.apply(this, arguments)
|
|
37
65
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (!sql) return query.apply(this, arguments)
|
|
66
|
+
const resolvedSql = resolveSqlString(sql)
|
|
67
|
+
if (resolvedSql === undefined) return query.apply(this, arguments)
|
|
41
68
|
|
|
42
69
|
const abortController = new AbortController()
|
|
43
|
-
startOuterQueryCh.publish({ sql, abortController })
|
|
70
|
+
startOuterQueryCh.publish({ sql: resolvedSql, abortController })
|
|
44
71
|
|
|
45
72
|
if (abortController.signal.aborted) {
|
|
46
73
|
const addCommand = this.addCommand
|
|
@@ -56,7 +83,7 @@ function wrapConnection (Connection, version) {
|
|
|
56
83
|
cb = queryCommand.onResult
|
|
57
84
|
|
|
58
85
|
process.nextTick(() => {
|
|
59
|
-
if (cb) {
|
|
86
|
+
if (typeof cb === 'function') {
|
|
60
87
|
cb(abortController.signal.reason)
|
|
61
88
|
} else {
|
|
62
89
|
queryCommand.emit('error', abortController.signal.reason)
|
|
@@ -76,12 +103,11 @@ function wrapConnection (Connection, version) {
|
|
|
76
103
|
shimmer.wrap(Connection.prototype, 'execute', execute => function (sql, values, cb) {
|
|
77
104
|
if (!startOuterQueryCh.hasSubscribers) return execute.apply(this, arguments)
|
|
78
105
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (!sql) return execute.apply(this, arguments)
|
|
106
|
+
const resolvedSql = resolveSqlString(sql)
|
|
107
|
+
if (resolvedSql === undefined) return execute.apply(this, arguments)
|
|
82
108
|
|
|
83
109
|
const abortController = new AbortController()
|
|
84
|
-
startOuterQueryCh.publish({ sql, abortController })
|
|
110
|
+
startOuterQueryCh.publish({ sql: resolvedSql, abortController })
|
|
85
111
|
|
|
86
112
|
if (abortController.signal.aborted) {
|
|
87
113
|
const addCommand = this.addCommand
|
|
@@ -94,7 +120,9 @@ function wrapConnection (Connection, version) {
|
|
|
94
120
|
this.addCommand = addCommand
|
|
95
121
|
}
|
|
96
122
|
|
|
97
|
-
result?.onResult
|
|
123
|
+
if (typeof result?.onResult === 'function') {
|
|
124
|
+
result.onResult(abortController.signal.reason)
|
|
125
|
+
}
|
|
98
126
|
|
|
99
127
|
return result
|
|
100
128
|
}
|
|
@@ -104,33 +132,48 @@ function wrapConnection (Connection, version) {
|
|
|
104
132
|
|
|
105
133
|
return Connection
|
|
106
134
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
135
|
+
/**
|
|
136
|
+
* @param {object} cmd
|
|
137
|
+
* @param {object} ctx
|
|
138
|
+
* @returns {void}
|
|
139
|
+
*/
|
|
140
|
+
function wrapCommandOnResult (cmd, ctx) {
|
|
141
|
+
const onResult = cmd?.onResult
|
|
142
|
+
if (typeof onResult !== 'function') return
|
|
110
143
|
|
|
111
|
-
|
|
112
|
-
this.onResult = function () {
|
|
113
|
-
return commandFinishCh.runStores(ctx, onResult, this, ...arguments)
|
|
114
|
-
}
|
|
115
|
-
}
|
|
144
|
+
const cached = wrappedOnResult.get(cmd)
|
|
116
145
|
|
|
117
|
-
|
|
118
|
-
|
|
146
|
+
if (cached === onResult) return
|
|
147
|
+
|
|
148
|
+
const wrapped = function () {
|
|
149
|
+
return commandFinishCh.runStores(ctx, onResult, this, ...arguments)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
wrappedOnResult.set(cmd, wrapped)
|
|
153
|
+
cmd.onResult = wrapped
|
|
119
154
|
}
|
|
120
155
|
|
|
156
|
+
/**
|
|
157
|
+
* @param {object} cmd
|
|
158
|
+
* @param {Function} execute
|
|
159
|
+
* @param {object} ctx
|
|
160
|
+
* @param {object} config
|
|
161
|
+
* @returns {Function}
|
|
162
|
+
*/
|
|
121
163
|
function wrapExecute (cmd, execute, ctx, config) {
|
|
122
164
|
return shimmer.wrapFunction(execute, execute => function executeWithTrace (packet, connection) {
|
|
123
|
-
|
|
165
|
+
const command = /** @type {{ statement?: { query?: unknown }, sql?: unknown }} */ (cmd)
|
|
166
|
+
ctx.sql = command.statement ? command.statement.query : command.sql
|
|
124
167
|
ctx.conf = config
|
|
125
168
|
|
|
126
169
|
return startCh.runStores(ctx, () => {
|
|
127
|
-
if (
|
|
128
|
-
|
|
170
|
+
if (command.statement) {
|
|
171
|
+
command.statement.query = ctx.sql
|
|
129
172
|
} else {
|
|
130
|
-
|
|
173
|
+
command.sql = ctx.sql
|
|
131
174
|
}
|
|
132
175
|
|
|
133
|
-
if (this.onResult) {
|
|
176
|
+
if (typeof this.onResult === 'function') {
|
|
134
177
|
const onResult = this.onResult
|
|
135
178
|
|
|
136
179
|
this.onResult = shimmer.wrapFunction(onResult, onResult => function (error) {
|
|
@@ -141,11 +184,14 @@ function wrapConnection (Connection, version) {
|
|
|
141
184
|
finishCh.runStores(ctx, onResult, this, ...arguments)
|
|
142
185
|
})
|
|
143
186
|
} else {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
187
|
+
const command = /** @type {{ once?: Function }} */ (this)
|
|
188
|
+
if (typeof command.once === 'function') {
|
|
189
|
+
command.once(errorMonitor, error => {
|
|
190
|
+
ctx.error = error
|
|
191
|
+
errorCh.publish(ctx)
|
|
192
|
+
})
|
|
193
|
+
command.once('end', () => finishCh.publish(ctx))
|
|
194
|
+
}
|
|
149
195
|
}
|
|
150
196
|
|
|
151
197
|
this.execute = execute
|
|
@@ -157,9 +203,14 @@ function wrapConnection (Connection, version) {
|
|
|
157
203
|
errorCh.publish(ctx)
|
|
158
204
|
}
|
|
159
205
|
})
|
|
160
|
-
}
|
|
206
|
+
})
|
|
161
207
|
}
|
|
162
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* @param {Function} Pool
|
|
211
|
+
* @param {string} version
|
|
212
|
+
* @returns {Function}
|
|
213
|
+
*/
|
|
163
214
|
function wrapPool (Pool, version) {
|
|
164
215
|
const startOuterQueryCh = channel('datadog:mysql2:outerquery:start')
|
|
165
216
|
const shouldEmitEndAfterQueryAbort = satisfies(version, '>=1.3.3')
|
|
@@ -167,12 +218,11 @@ function wrapPool (Pool, version) {
|
|
|
167
218
|
shimmer.wrap(Pool.prototype, 'query', query => function (sql, values, cb) {
|
|
168
219
|
if (!startOuterQueryCh.hasSubscribers) return query.apply(this, arguments)
|
|
169
220
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (!sql) return query.apply(this, arguments)
|
|
221
|
+
const resolvedSql = resolveSqlString(sql)
|
|
222
|
+
if (resolvedSql === undefined) return query.apply(this, arguments)
|
|
173
223
|
|
|
174
224
|
const abortController = new AbortController()
|
|
175
|
-
startOuterQueryCh.publish({ sql, abortController })
|
|
225
|
+
startOuterQueryCh.publish({ sql: resolvedSql, abortController })
|
|
176
226
|
|
|
177
227
|
if (abortController.signal.aborted) {
|
|
178
228
|
const getConnection = this.getConnection
|
|
@@ -206,21 +256,22 @@ function wrapPool (Pool, version) {
|
|
|
206
256
|
shimmer.wrap(Pool.prototype, 'execute', execute => function (sql, values, cb) {
|
|
207
257
|
if (!startOuterQueryCh.hasSubscribers) return execute.apply(this, arguments)
|
|
208
258
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if (!sql) return execute.apply(this, arguments)
|
|
259
|
+
const resolvedSql = resolveSqlString(sql)
|
|
260
|
+
if (resolvedSql === undefined) return execute.apply(this, arguments)
|
|
212
261
|
|
|
213
262
|
const abortController = new AbortController()
|
|
214
|
-
startOuterQueryCh.publish({ sql, abortController })
|
|
263
|
+
startOuterQueryCh.publish({ sql: resolvedSql, abortController })
|
|
215
264
|
|
|
216
265
|
if (abortController.signal.aborted) {
|
|
217
266
|
if (typeof values === 'function') {
|
|
218
267
|
cb = values
|
|
219
268
|
}
|
|
220
269
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
270
|
+
if (typeof cb === 'function') {
|
|
271
|
+
process.nextTick(() => {
|
|
272
|
+
/** @type {Function} */ (cb)(abortController.signal.reason)
|
|
273
|
+
})
|
|
274
|
+
}
|
|
224
275
|
return
|
|
225
276
|
}
|
|
226
277
|
|
|
@@ -230,6 +281,10 @@ function wrapPool (Pool, version) {
|
|
|
230
281
|
return Pool
|
|
231
282
|
}
|
|
232
283
|
|
|
284
|
+
/**
|
|
285
|
+
* @param {Function} PoolCluster
|
|
286
|
+
* @returns {Function}
|
|
287
|
+
*/
|
|
233
288
|
function wrapPoolCluster (PoolCluster) {
|
|
234
289
|
const startOuterQueryCh = channel('datadog:mysql2:outerquery:start')
|
|
235
290
|
const wrappedPoolNamespaces = new WeakSet()
|
|
@@ -239,12 +294,11 @@ function wrapPoolCluster (PoolCluster) {
|
|
|
239
294
|
|
|
240
295
|
if (startOuterQueryCh.hasSubscribers && !wrappedPoolNamespaces.has(poolNamespace)) {
|
|
241
296
|
shimmer.wrap(poolNamespace, 'query', query => function (sql, values, cb) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
if (!sql) return query.apply(this, arguments)
|
|
297
|
+
const resolvedSql = resolveSqlString(sql)
|
|
298
|
+
if (resolvedSql === undefined) return query.apply(this, arguments)
|
|
245
299
|
|
|
246
300
|
const abortController = new AbortController()
|
|
247
|
-
startOuterQueryCh.publish({ sql, abortController })
|
|
301
|
+
startOuterQueryCh.publish({ sql: resolvedSql, abortController })
|
|
248
302
|
|
|
249
303
|
if (abortController.signal.aborted) {
|
|
250
304
|
const getConnection = this.getConnection
|
|
@@ -274,21 +328,22 @@ function wrapPoolCluster (PoolCluster) {
|
|
|
274
328
|
})
|
|
275
329
|
|
|
276
330
|
shimmer.wrap(poolNamespace, 'execute', execute => function (sql, values, cb) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
if (!sql) return execute.apply(this, arguments)
|
|
331
|
+
const resolvedSql = resolveSqlString(sql)
|
|
332
|
+
if (resolvedSql === undefined) return execute.apply(this, arguments)
|
|
280
333
|
|
|
281
334
|
const abortController = new AbortController()
|
|
282
|
-
startOuterQueryCh.publish({ sql, abortController })
|
|
335
|
+
startOuterQueryCh.publish({ sql: resolvedSql, abortController })
|
|
283
336
|
|
|
284
337
|
if (abortController.signal.aborted) {
|
|
285
338
|
if (typeof values === 'function') {
|
|
286
339
|
cb = values
|
|
287
340
|
}
|
|
288
341
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
342
|
+
if (typeof cb === 'function') {
|
|
343
|
+
process.nextTick(() => {
|
|
344
|
+
/** @type {Function} */ (cb)(abortController.signal.reason)
|
|
345
|
+
})
|
|
346
|
+
}
|
|
292
347
|
|
|
293
348
|
return
|
|
294
349
|
}
|
|
@@ -305,9 +360,21 @@ function wrapPoolCluster (PoolCluster) {
|
|
|
305
360
|
return PoolCluster
|
|
306
361
|
}
|
|
307
362
|
|
|
308
|
-
addHook(
|
|
309
|
-
|
|
310
|
-
|
|
363
|
+
addHook(
|
|
364
|
+
{ name: 'mysql2', file: 'lib/base/connection.js', versions: ['>=3.11.5'] },
|
|
365
|
+
/** @type {(moduleExports: unknown, version: string) => unknown} */ (wrapConnection)
|
|
366
|
+
)
|
|
367
|
+
addHook(
|
|
368
|
+
{ name: 'mysql2', file: 'lib/connection.js', versions: ['1 - 3.11.4'] },
|
|
369
|
+
/** @type {(moduleExports: unknown, version: string) => unknown} */ (wrapConnection)
|
|
370
|
+
)
|
|
371
|
+
addHook(
|
|
372
|
+
{ name: 'mysql2', file: 'lib/pool.js', versions: ['1 - 3.11.4'] },
|
|
373
|
+
/** @type {(moduleExports: unknown, version: string) => unknown} */ (wrapPool)
|
|
374
|
+
)
|
|
311
375
|
|
|
312
376
|
// PoolNamespace.prototype.query does not exist in mysql2<2.3.0
|
|
313
|
-
addHook(
|
|
377
|
+
addHook(
|
|
378
|
+
{ name: 'mysql2', file: 'lib/pool_cluster.js', versions: ['2.3.0 - 3.11.4'] },
|
|
379
|
+
/** @type {(moduleExports: unknown, version: string) => unknown} */ (wrapPoolCluster)
|
|
380
|
+
)
|
|
@@ -41,7 +41,7 @@ const testSuiteToTestStatuses = new Map()
|
|
|
41
41
|
const testSuiteToErrors = new Map()
|
|
42
42
|
const testsToTestStatuses = new Map()
|
|
43
43
|
|
|
44
|
-
const RUM_FLUSH_WAIT_TIME = Number(getValueFromEnvSources('DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS')) ||
|
|
44
|
+
const RUM_FLUSH_WAIT_TIME = Number(getValueFromEnvSources('DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS')) || 500
|
|
45
45
|
|
|
46
46
|
let applyRepeatEachIndex = null
|
|
47
47
|
|
|
@@ -396,6 +396,14 @@ function testEndHandler ({
|
|
|
396
396
|
}
|
|
397
397
|
}
|
|
398
398
|
|
|
399
|
+
// Check if all EFD retries failed
|
|
400
|
+
if (testStatuses.length === earlyFlakeDetectionNumRetries + 1 &&
|
|
401
|
+
(test._ddIsNew || test._ddIsModified) &&
|
|
402
|
+
test._ddIsEfdRetry &&
|
|
403
|
+
testStatuses.every(status => status === 'fail')) {
|
|
404
|
+
test._ddHasFailedAllRetries = true
|
|
405
|
+
}
|
|
406
|
+
|
|
399
407
|
// this handles tests that do not go through the worker process (because they're skipped)
|
|
400
408
|
if (shouldCreateTestSpan) {
|
|
401
409
|
const testResult = results.at(-1)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const shimmer = require('../../datadog-shimmer')
|
|
4
|
+
const { channel, addHook } = require('./helpers/instrument')
|
|
5
|
+
|
|
6
|
+
const checkoutSessionCreateFinishCh = channel('datadog:stripe:checkoutSession:create:finish')
|
|
7
|
+
const paymentIntentCreateFinishCh = channel('datadog:stripe:paymentIntent:create:finish')
|
|
8
|
+
const constructEventFinishCh = channel('datadog:stripe:constructEvent:finish')
|
|
9
|
+
|
|
10
|
+
function wrapSessionCreate (create) {
|
|
11
|
+
return function wrappedSessionCreate () {
|
|
12
|
+
const promise = create.apply(this, arguments)
|
|
13
|
+
|
|
14
|
+
if (!checkoutSessionCreateFinishCh.hasSubscribers) return promise
|
|
15
|
+
|
|
16
|
+
return promise.then((result) => {
|
|
17
|
+
checkoutSessionCreateFinishCh.publish(result)
|
|
18
|
+
return result
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function wrapPaymentIntentCreate (create) {
|
|
24
|
+
return function wrappedPaymentIntentCreate () {
|
|
25
|
+
const promise = create.apply(this, arguments)
|
|
26
|
+
|
|
27
|
+
if (!paymentIntentCreateFinishCh.hasSubscribers) return promise
|
|
28
|
+
|
|
29
|
+
return promise.then((result) => {
|
|
30
|
+
paymentIntentCreateFinishCh.publish(result)
|
|
31
|
+
return result
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function wrapConstructEvent (constructEvent) {
|
|
37
|
+
return function wrappedConstructEvent () {
|
|
38
|
+
const result = constructEvent.apply(this, arguments)
|
|
39
|
+
|
|
40
|
+
// no need to check for hasSubscribers,
|
|
41
|
+
// if it's false, the publish function will be noop
|
|
42
|
+
constructEventFinishCh.publish(result)
|
|
43
|
+
|
|
44
|
+
return result
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function wrapConstructEventAsync (constructEventAsync) {
|
|
49
|
+
return function wrappedConstructEventAsync () {
|
|
50
|
+
const promise = constructEventAsync.apply(this, arguments)
|
|
51
|
+
|
|
52
|
+
if (!constructEventFinishCh.hasSubscribers) return promise
|
|
53
|
+
|
|
54
|
+
return promise.then((result) => {
|
|
55
|
+
constructEventFinishCh.publish(result)
|
|
56
|
+
return result
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function wrapStripe (Stripe) {
|
|
62
|
+
return function wrappedStripe () {
|
|
63
|
+
let stripe = Stripe.apply(this, arguments)
|
|
64
|
+
|
|
65
|
+
// to support both with and without "new" operator syntax
|
|
66
|
+
if (this instanceof Stripe) {
|
|
67
|
+
stripe = this
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (typeof stripe.checkout?.sessions?.create === 'function') {
|
|
71
|
+
shimmer.wrap(stripe.checkout.sessions, 'create', wrapSessionCreate)
|
|
72
|
+
}
|
|
73
|
+
if (typeof stripe.paymentIntents?.create === 'function') {
|
|
74
|
+
shimmer.wrap(stripe.paymentIntents, 'create', wrapPaymentIntentCreate)
|
|
75
|
+
}
|
|
76
|
+
if (typeof stripe.webhooks?.constructEvent === 'function') {
|
|
77
|
+
shimmer.wrap(stripe.webhooks, 'constructEvent', wrapConstructEvent)
|
|
78
|
+
}
|
|
79
|
+
if (typeof stripe.webhooks?.constructEventAsync === 'function') {
|
|
80
|
+
shimmer.wrap(stripe.webhooks, 'constructEventAsync', wrapConstructEventAsync)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return stripe
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
addHook({
|
|
88
|
+
name: 'stripe',
|
|
89
|
+
versions: ['9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '>=20.0.0'],
|
|
90
|
+
}, Stripe => {
|
|
91
|
+
return shimmer.wrapFunction(Stripe, wrapStripe)
|
|
92
|
+
})
|
|
@@ -1036,6 +1036,17 @@ addHook({
|
|
|
1036
1036
|
}
|
|
1037
1037
|
}
|
|
1038
1038
|
|
|
1039
|
+
// Check if all EFD retries failed
|
|
1040
|
+
const providedContext = getProvidedContext()
|
|
1041
|
+
if (providedContext.isEarlyFlakeDetectionEnabled && (newTasks.has(task) || modifiedTasks.has(task))) {
|
|
1042
|
+
const statuses = taskToStatuses.get(task)
|
|
1043
|
+
// statuses only includes repetitions (not the initial run), so we check against numRepeats (not +1)
|
|
1044
|
+
if (statuses && statuses.length === providedContext.numRepeats &&
|
|
1045
|
+
statuses.every(status => status === 'fail')) {
|
|
1046
|
+
hasFailedAllRetries = true
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1039
1050
|
if (testCtx) {
|
|
1040
1051
|
const isRetry = task.result?.retryCount > 0
|
|
1041
1052
|
// `duration` is the duration of all the retries, so it can't be used if there are retries
|
|
@@ -9,6 +9,19 @@ class AmqplibConsumerPlugin extends ConsumerPlugin {
|
|
|
9
9
|
static id = 'amqplib'
|
|
10
10
|
static operation = 'consume'
|
|
11
11
|
|
|
12
|
+
start (ctx) {
|
|
13
|
+
if (!this.config.dsmEnabled) return
|
|
14
|
+
const { fields = {}, message, queue } = ctx
|
|
15
|
+
if (!message?.properties?.headers) return
|
|
16
|
+
|
|
17
|
+
const { span } = ctx.currentStore
|
|
18
|
+
const queueName = queue || fields.queue || fields.routingKey
|
|
19
|
+
const payloadSize = getAmqpMessageSize({ headers: message.properties.headers, content: message.content })
|
|
20
|
+
this.tracer.decodeDataStreamsContext(message.properties.headers)
|
|
21
|
+
this.tracer
|
|
22
|
+
.setCheckpoint(['direction:in', `topic:${queueName}`, 'type:rabbitmq'], span, payloadSize)
|
|
23
|
+
}
|
|
24
|
+
|
|
12
25
|
bindStart (ctx) {
|
|
13
26
|
const { method, fields = {}, message, queue } = ctx
|
|
14
27
|
|
|
@@ -17,7 +30,7 @@ class AmqplibConsumerPlugin extends ConsumerPlugin {
|
|
|
17
30
|
const childOf = extract(this.tracer, message)
|
|
18
31
|
|
|
19
32
|
const queueName = queue || fields.queue || fields.routingKey
|
|
20
|
-
|
|
33
|
+
this.startSpan({
|
|
21
34
|
childOf,
|
|
22
35
|
resource: getResourceName(method, fields),
|
|
23
36
|
type: 'worker',
|
|
@@ -31,15 +44,6 @@ class AmqplibConsumerPlugin extends ConsumerPlugin {
|
|
|
31
44
|
},
|
|
32
45
|
}, ctx)
|
|
33
46
|
|
|
34
|
-
if (
|
|
35
|
-
this.config.dsmEnabled && message?.properties?.headers
|
|
36
|
-
) {
|
|
37
|
-
const payloadSize = getAmqpMessageSize({ headers: message.properties.headers, content: message.content })
|
|
38
|
-
this.tracer.decodeDataStreamsContext(message.properties.headers)
|
|
39
|
-
this.tracer
|
|
40
|
-
.setCheckpoint(['direction:in', `topic:${queueName}`, 'type:rabbitmq'], span, payloadSize)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
47
|
return ctx.currentStore
|
|
44
48
|
}
|
|
45
49
|
}
|
|
@@ -10,8 +10,30 @@ class AmqplibProducerPlugin extends ProducerPlugin {
|
|
|
10
10
|
static id = 'amqplib'
|
|
11
11
|
static operation = 'publish'
|
|
12
12
|
|
|
13
|
+
start (ctx) {
|
|
14
|
+
if (!this.config.dsmEnabled) return
|
|
15
|
+
const { fields, message } = ctx
|
|
16
|
+
const { span } = ctx.currentStore
|
|
17
|
+
|
|
18
|
+
const hasRoutingKey = fields.routingKey != null
|
|
19
|
+
const payloadSize = getAmqpMessageSize({ content: message, headers: fields.headers })
|
|
20
|
+
|
|
21
|
+
// there are two ways to send messages in RabbitMQ:
|
|
22
|
+
// 1. using an exchange and a routing key in which DSM connects via the exchange
|
|
23
|
+
// 2. using an unnamed exchange and a routing key in which DSM connects via the topic
|
|
24
|
+
const exchangeOrTopicTag = hasRoutingKey && !fields.exchange
|
|
25
|
+
? `topic:${fields.routingKey}`
|
|
26
|
+
: `exchange:${fields.exchange}`
|
|
27
|
+
|
|
28
|
+
const dataStreamsContext = this.tracer.setCheckpoint(
|
|
29
|
+
['direction:out', exchangeOrTopicTag, `has_routing_key:${hasRoutingKey}`, 'type:rabbitmq'],
|
|
30
|
+
span, payloadSize
|
|
31
|
+
)
|
|
32
|
+
DsmPathwayCodec.encode(dataStreamsContext, fields.headers)
|
|
33
|
+
}
|
|
34
|
+
|
|
13
35
|
bindStart (ctx) {
|
|
14
|
-
const { channel = {}, method, fields
|
|
36
|
+
const { channel = {}, method, fields } = ctx
|
|
15
37
|
|
|
16
38
|
if (method !== 'basic.publish') return
|
|
17
39
|
|
|
@@ -34,24 +56,6 @@ class AmqplibProducerPlugin extends ProducerPlugin {
|
|
|
34
56
|
|
|
35
57
|
this.tracer.inject(span, TEXT_MAP, fields.headers)
|
|
36
58
|
|
|
37
|
-
if (this.config.dsmEnabled) {
|
|
38
|
-
const hasRoutingKey = fields.routingKey != null
|
|
39
|
-
const payloadSize = getAmqpMessageSize({ content: message, headers: fields.headers })
|
|
40
|
-
|
|
41
|
-
// there are two ways to send messages in RabbitMQ:
|
|
42
|
-
// 1. using an exchange and a routing key in which DSM connects via the exchange
|
|
43
|
-
// 2. using an unnamed exchange and a routing key in which DSM connects via the topic
|
|
44
|
-
const exchangeOrTopicTag = hasRoutingKey && !fields.exchange
|
|
45
|
-
? `topic:${fields.routingKey}`
|
|
46
|
-
: `exchange:${fields.exchange}`
|
|
47
|
-
|
|
48
|
-
const dataStreamsContext = this.tracer
|
|
49
|
-
.setCheckpoint(
|
|
50
|
-
['direction:out', exchangeOrTopicTag, `has_routing_key:${hasRoutingKey}`, 'type:rabbitmq']
|
|
51
|
-
, span, payloadSize)
|
|
52
|
-
DsmPathwayCodec.encode(dataStreamsContext, fields.headers)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
59
|
return ctx.currentStore
|
|
56
60
|
}
|
|
57
61
|
}
|