dd-trace 5.51.0 → 5.52.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 -6
- package/index.d.ts +35 -1
- package/package.json +3 -9
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +391 -0
- package/packages/datadog-instrumentations/src/cucumber.js +3 -0
- package/packages/datadog-instrumentations/src/dns.js +16 -14
- package/packages/datadog-instrumentations/src/fs.js +37 -46
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/jest.js +5 -0
- package/packages/datadog-instrumentations/src/mocha/utils.js +5 -0
- package/packages/datadog-instrumentations/src/net.js +24 -28
- package/packages/datadog-instrumentations/src/pg.js +19 -5
- package/packages/datadog-instrumentations/src/playwright.js +6 -0
- package/packages/datadog-instrumentations/src/vitest.js +18 -4
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/batch-consumer.js +11 -0
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/consumer.js +11 -0
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/index.js +19 -0
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/producer.js +11 -0
- package/packages/datadog-plugin-cucumber/src/index.js +3 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +3 -0
- package/packages/datadog-plugin-dns/src/lookup.js +10 -5
- package/packages/datadog-plugin-dns/src/lookup_service.js +6 -2
- package/packages/datadog-plugin-dns/src/resolve.js +5 -2
- package/packages/datadog-plugin-dns/src/reverse.js +6 -2
- package/packages/datadog-plugin-fs/src/index.js +9 -2
- package/packages/datadog-plugin-jest/src/index.js +3 -0
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -1
- package/packages/datadog-plugin-kafkajs/src/consumer.js +12 -21
- package/packages/datadog-plugin-kafkajs/src/producer.js +6 -2
- package/packages/datadog-plugin-kafkajs/src/utils.js +27 -0
- package/packages/datadog-plugin-langchain/src/index.js +0 -1
- package/packages/datadog-plugin-mocha/src/index.js +3 -0
- package/packages/datadog-plugin-net/src/ipc.js +6 -4
- package/packages/datadog-plugin-net/src/tcp.js +15 -9
- package/packages/datadog-plugin-pg/src/index.js +5 -1
- package/packages/datadog-plugin-playwright/src/index.js +3 -0
- package/packages/datadog-plugin-vitest/src/index.js +15 -3
- package/packages/dd-trace/src/appsec/api_security_sampler.js +20 -12
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +14 -9
- package/packages/dd-trace/src/appsec/index.js +1 -1
- package/packages/dd-trace/src/baggage.js +36 -0
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +4 -2
- package/packages/dd-trace/src/config.js +13 -1
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +2 -0
- package/packages/dd-trace/src/debugger/devtools_client/state.js +1 -1
- package/packages/dd-trace/src/exporters/common/docker.js +13 -31
- package/packages/dd-trace/src/guardrails/telemetry.js +2 -5
- package/packages/dd-trace/src/llmobs/writers/base.js +33 -12
- package/packages/dd-trace/src/noop/proxy.js +5 -0
- package/packages/dd-trace/src/opentelemetry/context_manager.js +2 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +17 -9
- package/packages/dd-trace/src/plugin_manager.js +2 -0
- package/packages/dd-trace/src/plugins/index.js +3 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +9 -20
- package/packages/dd-trace/src/plugins/outbound.js +11 -3
- package/packages/dd-trace/src/plugins/tracing.js +8 -4
- package/packages/dd-trace/src/plugins/util/test.js +1 -1
- package/packages/dd-trace/src/profiling/exporter_cli.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookup.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookupservice.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_resolve.js +2 -2
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_reverse.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/event_plugins/event.js +15 -14
- package/packages/dd-trace/src/proxy.js +12 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +8 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +8 -0
- package/packages/dd-trace/src/standalone/product.js +3 -5
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
channel,
|
|
5
|
-
addHook,
|
|
6
|
-
AsyncResource
|
|
7
|
-
} = require('./helpers/instrument')
|
|
3
|
+
const { channel, addHook } = require('./helpers/instrument')
|
|
8
4
|
const shimmer = require('../../datadog-shimmer')
|
|
9
5
|
|
|
10
6
|
const startChannel = channel('apm:fs:operation:start')
|
|
@@ -191,25 +187,23 @@ function wrapCreateStream (original) {
|
|
|
191
187
|
return function (path, options) {
|
|
192
188
|
if (!startChannel.hasSubscribers) return original.apply(this, arguments)
|
|
193
189
|
|
|
194
|
-
const
|
|
195
|
-
const message = getMessage(name, ['path', 'options'], arguments)
|
|
196
|
-
|
|
197
|
-
return innerResource.runInAsyncScope(() => {
|
|
198
|
-
startChannel.publish(message)
|
|
190
|
+
const ctx = getMessage(name, ['path', 'options'], arguments)
|
|
199
191
|
|
|
192
|
+
return startChannel.runStores(ctx, () => {
|
|
200
193
|
try {
|
|
201
194
|
const stream = original.apply(this, arguments)
|
|
202
|
-
const onError =
|
|
203
|
-
|
|
195
|
+
const onError = error => {
|
|
196
|
+
ctx.error = error
|
|
197
|
+
errorChannel.publish(ctx)
|
|
204
198
|
onFinish()
|
|
205
|
-
}
|
|
206
|
-
const onFinish =
|
|
207
|
-
finishChannel.
|
|
199
|
+
}
|
|
200
|
+
const onFinish = () => {
|
|
201
|
+
finishChannel.runStores(ctx, () => {})
|
|
208
202
|
stream.off('close', onFinish)
|
|
209
203
|
stream.off('end', onFinish)
|
|
210
204
|
stream.off('finish', onFinish)
|
|
211
205
|
stream.off('error', onError)
|
|
212
|
-
}
|
|
206
|
+
}
|
|
213
207
|
|
|
214
208
|
stream.once('close', onFinish)
|
|
215
209
|
stream.once('end', onFinish)
|
|
@@ -218,8 +212,9 @@ function wrapCreateStream (original) {
|
|
|
218
212
|
|
|
219
213
|
return stream
|
|
220
214
|
} catch (error) {
|
|
221
|
-
|
|
222
|
-
|
|
215
|
+
ctx.error = error
|
|
216
|
+
errorChannel.publish(ctx)
|
|
217
|
+
finishChannel.runStores(ctx, () => {})
|
|
223
218
|
}
|
|
224
219
|
})
|
|
225
220
|
}
|
|
@@ -239,17 +234,16 @@ function createWatchWrapFunction (override = '') {
|
|
|
239
234
|
const operation = name
|
|
240
235
|
return function () {
|
|
241
236
|
if (!startChannel.hasSubscribers) return original.apply(this, arguments)
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
return innerResource.runInAsyncScope(() => {
|
|
245
|
-
startChannel.publish(message)
|
|
237
|
+
const ctx = getMessage(method, watchMethods[operation], arguments, this)
|
|
238
|
+
return startChannel.runStores(ctx, () => {
|
|
246
239
|
try {
|
|
247
240
|
const result = original.apply(this, arguments)
|
|
248
|
-
finishChannel.
|
|
241
|
+
finishChannel.runStores(ctx, () => {})
|
|
249
242
|
return result
|
|
250
243
|
} catch (error) {
|
|
251
|
-
|
|
252
|
-
|
|
244
|
+
ctx.error = error
|
|
245
|
+
errorChannel.publish(ctx)
|
|
246
|
+
finishChannel.runStores(ctx, () => {})
|
|
253
247
|
throw error
|
|
254
248
|
}
|
|
255
249
|
})
|
|
@@ -268,30 +262,25 @@ function createWrapFunction (prefix = '', override = '') {
|
|
|
268
262
|
|
|
269
263
|
const lastIndex = arguments.length - 1
|
|
270
264
|
const cb = typeof arguments[lastIndex] === 'function' && arguments[lastIndex]
|
|
271
|
-
const innerResource = new AsyncResource('bound-anonymous-fn')
|
|
272
265
|
const params = getMethodParamsRelationByPrefix(prefix)[operation]
|
|
273
266
|
const abortController = new AbortController()
|
|
274
|
-
const
|
|
267
|
+
const ctx = { ...getMessage(method, params, arguments, this), abortController }
|
|
275
268
|
|
|
276
|
-
const finish =
|
|
269
|
+
const finish = function (error, cb = () => {}) {
|
|
277
270
|
if (error !== null && typeof error === 'object') { // fs.exists receives a boolean
|
|
278
|
-
|
|
271
|
+
ctx.error = error
|
|
272
|
+
errorChannel.publish(ctx)
|
|
279
273
|
}
|
|
280
|
-
finishChannel.
|
|
281
|
-
}
|
|
274
|
+
return finishChannel.runStores(ctx, cb)
|
|
275
|
+
}
|
|
282
276
|
|
|
283
277
|
if (cb) {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
finish(e)
|
|
288
|
-
return outerResource.runInAsyncScope(() => cb.apply(this, arguments))
|
|
289
|
-
}))
|
|
278
|
+
arguments[lastIndex] = shimmer.wrapFunction(cb, cb => function (e) {
|
|
279
|
+
return finish(e, () => cb.apply(this, arguments))
|
|
280
|
+
})
|
|
290
281
|
}
|
|
291
282
|
|
|
292
|
-
return
|
|
293
|
-
startChannel.publish(message)
|
|
294
|
-
|
|
283
|
+
return startChannel.runStores(ctx, () => {
|
|
295
284
|
if (abortController.signal.aborted) {
|
|
296
285
|
const error = abortController.signal.reason || new Error('Aborted')
|
|
297
286
|
|
|
@@ -318,23 +307,25 @@ function createWrapFunction (prefix = '', override = '') {
|
|
|
318
307
|
if (isFirstMethodReturningFileHandle(original)) {
|
|
319
308
|
wrapFileHandle(value)
|
|
320
309
|
}
|
|
321
|
-
finishChannel.
|
|
310
|
+
finishChannel.runStores(ctx, () => {})
|
|
322
311
|
return value
|
|
323
312
|
},
|
|
324
313
|
error => {
|
|
325
|
-
|
|
326
|
-
|
|
314
|
+
ctx.error = error
|
|
315
|
+
errorChannel.publish(ctx)
|
|
316
|
+
finishChannel.runStores(ctx, () => {})
|
|
327
317
|
throw error
|
|
328
318
|
}
|
|
329
319
|
)
|
|
330
320
|
}
|
|
331
321
|
|
|
332
|
-
finishChannel.
|
|
322
|
+
finishChannel.runStores(ctx, () => {})
|
|
333
323
|
|
|
334
324
|
return result
|
|
335
325
|
} catch (error) {
|
|
336
|
-
|
|
337
|
-
|
|
326
|
+
ctx.error = error
|
|
327
|
+
errorChannel.publish(ctx)
|
|
328
|
+
finishChannel.runStores(ctx, () => {})
|
|
338
329
|
throw error
|
|
339
330
|
}
|
|
340
331
|
})
|
|
@@ -70,6 +70,7 @@ module.exports = {
|
|
|
70
70
|
knex: () => require('../knex'),
|
|
71
71
|
koa: () => require('../koa'),
|
|
72
72
|
'koa-router': () => require('../koa'),
|
|
73
|
+
'@confluentinc/kafka-javascript': () => require('../confluentinc-kafka-javascript'),
|
|
73
74
|
kafkajs: () => require('../kafkajs'),
|
|
74
75
|
langchain: () => require('../langchain'),
|
|
75
76
|
ldapjs: () => require('../ldapjs'),
|
|
@@ -408,6 +408,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
408
408
|
event.test.fn = originalTestFns.get(event.test)
|
|
409
409
|
|
|
410
410
|
let attemptToFixPassed = false
|
|
411
|
+
let attemptToFixFailed = false
|
|
411
412
|
let failedAllTests = false
|
|
412
413
|
let isAttemptToFix = false
|
|
413
414
|
if (this.isTestManagementTestsEnabled) {
|
|
@@ -425,6 +426,9 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
425
426
|
// If it is, we'll set the failedAllTests flag to true if all the tests failed
|
|
426
427
|
// If all tests passed, we'll set the attemptToFixPassed flag to true
|
|
427
428
|
if (testStatuses.length === testManagementAttemptToFixRetries + 1) {
|
|
429
|
+
if (testStatuses.some(status => status === 'fail')) {
|
|
430
|
+
attemptToFixFailed = true
|
|
431
|
+
}
|
|
428
432
|
if (testStatuses.every(status => status === 'fail')) {
|
|
429
433
|
failedAllTests = true
|
|
430
434
|
} else if (testStatuses.every(status => status === 'pass')) {
|
|
@@ -490,6 +494,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
490
494
|
testStartLine: getTestLineStart(event.test.asyncError, this.testSuite),
|
|
491
495
|
attemptToFixPassed,
|
|
492
496
|
failedAllTests,
|
|
497
|
+
attemptToFixFailed,
|
|
493
498
|
isAtrRetry
|
|
494
499
|
})
|
|
495
500
|
})
|
|
@@ -265,6 +265,7 @@ function getOnTestEndHandler (config) {
|
|
|
265
265
|
|
|
266
266
|
let hasFailedAllRetries = false
|
|
267
267
|
let attemptToFixPassed = false
|
|
268
|
+
let attemptToFixFailed = false
|
|
268
269
|
|
|
269
270
|
const testName = getTestFullName(test)
|
|
270
271
|
|
|
@@ -278,6 +279,9 @@ function getOnTestEndHandler (config) {
|
|
|
278
279
|
const isLastAttempt = testStatuses.length === config.testManagementAttemptToFixRetries + 1
|
|
279
280
|
|
|
280
281
|
if (test._ddIsAttemptToFix && isLastAttempt) {
|
|
282
|
+
if (testStatuses.some(status => status === 'fail')) {
|
|
283
|
+
attemptToFixFailed = true
|
|
284
|
+
}
|
|
281
285
|
if (testStatuses.every(status => status === 'fail')) {
|
|
282
286
|
hasFailedAllRetries = true
|
|
283
287
|
} else if (testStatuses.every(status => status === 'pass')) {
|
|
@@ -299,6 +303,7 @@ function getOnTestEndHandler (config) {
|
|
|
299
303
|
isLastRetry: getIsLastRetry(test),
|
|
300
304
|
hasFailedAllRetries,
|
|
301
305
|
attemptToFixPassed,
|
|
306
|
+
attemptToFixFailed,
|
|
302
307
|
isAttemptToFixRetry,
|
|
303
308
|
isAtrRetry
|
|
304
309
|
})
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
channel,
|
|
5
|
-
addHook,
|
|
6
|
-
AsyncResource
|
|
7
|
-
} = require('./helpers/instrument')
|
|
3
|
+
const { channel, addHook } = require('./helpers/instrument')
|
|
8
4
|
const shimmer = require('../../datadog-shimmer')
|
|
9
5
|
|
|
10
6
|
const startICPCh = channel('apm:net:ipc:start')
|
|
@@ -15,6 +11,7 @@ const startTCPCh = channel('apm:net:tcp:start')
|
|
|
15
11
|
const finishTCPCh = channel('apm:net:tcp:finish')
|
|
16
12
|
const errorTCPCh = channel('apm:net:tcp:error')
|
|
17
13
|
|
|
14
|
+
const readyCh = channel('apm:net:tcp:ready')
|
|
18
15
|
const connectionCh = channel('apm:net:tcp:connection')
|
|
19
16
|
|
|
20
17
|
const names = ['net', 'node:net']
|
|
@@ -39,30 +36,27 @@ addHook({ name: names }, (net, version, name) => {
|
|
|
39
36
|
|
|
40
37
|
if (!options) return connect.apply(this, arguments)
|
|
41
38
|
|
|
42
|
-
const
|
|
43
|
-
const
|
|
39
|
+
const protocol = options.path ? 'ipc' : 'tcp'
|
|
40
|
+
const startCh = protocol === 'ipc' ? startICPCh : startTCPCh
|
|
41
|
+
const finishCh = protocol === 'ipc' ? finishICPCh : finishTCPCh
|
|
42
|
+
const errorCh = protocol === 'ipc' ? errorICPCh : errorTCPCh
|
|
43
|
+
const ctx = { options }
|
|
44
44
|
|
|
45
45
|
if (typeof callback === 'function') {
|
|
46
|
-
arguments[lastIndex] =
|
|
46
|
+
arguments[lastIndex] = function (...args) {
|
|
47
|
+
return finishCh.runStores(ctx, callback, this, ...args)
|
|
48
|
+
}
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return asyncResource.runInAsyncScope(() => {
|
|
52
|
-
if (protocol === 'ipc') {
|
|
53
|
-
startICPCh.publish({ options })
|
|
54
|
-
setupListeners(this, 'ipc', asyncResource)
|
|
55
|
-
} else {
|
|
56
|
-
startTCPCh.publish({ options })
|
|
57
|
-
setupListeners(this, 'tcp', asyncResource)
|
|
58
|
-
}
|
|
51
|
+
return startCh.runStores(ctx, () => {
|
|
52
|
+
setupListeners(this, protocol, ctx, finishCh, errorCh)
|
|
59
53
|
|
|
60
54
|
const emit = this.emit
|
|
61
55
|
this.emit = shimmer.wrapFunction(emit, emit => function (eventName) {
|
|
62
56
|
switch (eventName) {
|
|
63
57
|
case 'ready':
|
|
64
58
|
case 'connect':
|
|
65
|
-
return
|
|
59
|
+
return readyCh.runStores(ctx, () => {
|
|
66
60
|
return emit.apply(this, arguments)
|
|
67
61
|
})
|
|
68
62
|
default:
|
|
@@ -73,7 +67,7 @@ addHook({ name: names }, (net, version, name) => {
|
|
|
73
67
|
try {
|
|
74
68
|
return connect.apply(this, arguments)
|
|
75
69
|
} catch (err) {
|
|
76
|
-
|
|
70
|
+
errorCh.publish(err)
|
|
77
71
|
|
|
78
72
|
throw err
|
|
79
73
|
}
|
|
@@ -104,19 +98,21 @@ function getOptions (args) {
|
|
|
104
98
|
}
|
|
105
99
|
}
|
|
106
100
|
|
|
107
|
-
function setupListeners (socket, protocol,
|
|
101
|
+
function setupListeners (socket, protocol, ctx, finishCh, errorCh) {
|
|
108
102
|
const events = ['connect', 'error', 'close', 'timeout']
|
|
109
103
|
|
|
110
|
-
const wrapListener =
|
|
104
|
+
const wrapListener = function (error) {
|
|
111
105
|
if (error) {
|
|
112
|
-
|
|
106
|
+
ctx.error = error
|
|
107
|
+
errorCh.publish(ctx)
|
|
113
108
|
}
|
|
114
|
-
|
|
115
|
-
}
|
|
109
|
+
finishCh.runStores(ctx, () => {})
|
|
110
|
+
}
|
|
116
111
|
|
|
117
|
-
const localListener =
|
|
118
|
-
|
|
119
|
-
|
|
112
|
+
const localListener = function () {
|
|
113
|
+
ctx.socket = socket
|
|
114
|
+
connectionCh.publish(ctx)
|
|
115
|
+
}
|
|
120
116
|
|
|
121
117
|
const cleanupListener = function () {
|
|
122
118
|
socket.removeListener('connect', localListener)
|
|
@@ -14,6 +14,8 @@ const errorCh = channel('apm:pg:query:error')
|
|
|
14
14
|
const startPoolQueryCh = channel('datadog:pg:pool:query:start')
|
|
15
15
|
const finishPoolQueryCh = channel('datadog:pg:pool:query:finish')
|
|
16
16
|
|
|
17
|
+
const { errorMonitor } = require('node:events')
|
|
18
|
+
|
|
17
19
|
addHook({ name: 'pg', versions: ['>=8.0.3'] }, pg => {
|
|
18
20
|
shimmer.wrap(pg.Client.prototype, 'query', query => wrapQuery(query))
|
|
19
21
|
shimmer.wrap(pg.Pool.prototype, 'query', query => wrapPoolQuery(query))
|
|
@@ -39,13 +41,15 @@ function wrapQuery (query) {
|
|
|
39
41
|
? arguments[0]
|
|
40
42
|
: { text: arguments[0] }
|
|
41
43
|
|
|
42
|
-
const
|
|
44
|
+
const textPropObj = pgQuery.cursor ?? pgQuery
|
|
45
|
+
const textProp = Object.getOwnPropertyDescriptor(textPropObj, 'text')
|
|
46
|
+
const stream = typeof textPropObj.read === 'function'
|
|
43
47
|
|
|
44
48
|
// Only alter `text` property if safe to do so.
|
|
45
49
|
if (!textProp || textProp.configurable) {
|
|
46
|
-
const originalText =
|
|
50
|
+
const originalText = textPropObj.text
|
|
47
51
|
|
|
48
|
-
Object.defineProperty(
|
|
52
|
+
Object.defineProperty(textPropObj, 'text', {
|
|
49
53
|
get () {
|
|
50
54
|
return this?.__ddInjectableQuery || originalText
|
|
51
55
|
}
|
|
@@ -57,9 +61,10 @@ function wrapQuery (query) {
|
|
|
57
61
|
|
|
58
62
|
startCh.publish({
|
|
59
63
|
params: this.connectionParameters,
|
|
60
|
-
query:
|
|
64
|
+
query: textPropObj,
|
|
61
65
|
processId,
|
|
62
|
-
abortController
|
|
66
|
+
abortController,
|
|
67
|
+
stream
|
|
63
68
|
})
|
|
64
69
|
|
|
65
70
|
const finish = asyncResource.bind(function (error, res) {
|
|
@@ -130,6 +135,15 @@ function wrapQuery (query) {
|
|
|
130
135
|
newQuery.then((res) => finish(null, res), finish)
|
|
131
136
|
}
|
|
132
137
|
|
|
138
|
+
if (stream) {
|
|
139
|
+
newQuery.on('end', () => {
|
|
140
|
+
finish(null, [])
|
|
141
|
+
})
|
|
142
|
+
newQuery.on(errorMonitor, (err) => {
|
|
143
|
+
finish(err)
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
|
|
133
147
|
try {
|
|
134
148
|
return retval
|
|
135
149
|
} catch (err) {
|
|
@@ -337,6 +337,9 @@ function testEndHandler (test, annotations, testStatus, error, isTimeout, isMain
|
|
|
337
337
|
}
|
|
338
338
|
|
|
339
339
|
if (testStatuses.length === testManagementAttemptToFixRetries + 1) {
|
|
340
|
+
if (testStatuses.some(status => status === 'fail')) {
|
|
341
|
+
test._ddHasFailedAttemptToFixRetries = true
|
|
342
|
+
}
|
|
340
343
|
if (testStatuses.every(status => status === 'fail')) {
|
|
341
344
|
test._ddHasFailedAllRetries = true
|
|
342
345
|
} else if (testStatuses.every(status => status === 'pass')) {
|
|
@@ -366,6 +369,7 @@ function testEndHandler (test, annotations, testStatus, error, isTimeout, isMain
|
|
|
366
369
|
isEfdRetry: test._ddIsEfdRetry,
|
|
367
370
|
hasFailedAllRetries: test._ddHasFailedAllRetries,
|
|
368
371
|
hasPassedAttemptToFixRetries: test._ddHasPassedAttemptToFixRetries,
|
|
372
|
+
hasFailedAttemptToFixRetries: test._ddHasFailedAttemptToFixRetries,
|
|
369
373
|
isAtrRetry
|
|
370
374
|
})
|
|
371
375
|
})
|
|
@@ -492,6 +496,7 @@ function dispatcherHookNew (dispatcherExport, runWrapper) {
|
|
|
492
496
|
_ddIsEfdRetry: test._ddIsEfdRetry,
|
|
493
497
|
_ddHasFailedAllRetries: test._ddHasFailedAllRetries,
|
|
494
498
|
_ddHasPassedAttemptToFixRetries: test._ddHasPassedAttemptToFixRetries,
|
|
499
|
+
_ddHasFailedAttemptToFixRetries: test._ddHasFailedAttemptToFixRetries,
|
|
495
500
|
_ddIsAtrRetry: isAtrRetry
|
|
496
501
|
}
|
|
497
502
|
})
|
|
@@ -986,6 +991,7 @@ addHook({
|
|
|
986
991
|
isAttemptToFixRetry: test._ddIsAttemptToFixRetry,
|
|
987
992
|
hasFailedAllRetries: test._ddHasFailedAllRetries,
|
|
988
993
|
hasPassedAttemptToFixRetries: test._ddHasPassedAttemptToFixRetries,
|
|
994
|
+
hasFailedAttemptToFixRetries: test._ddHasFailedAttemptToFixRetries,
|
|
989
995
|
isAtrRetry: test._ddIsAtrRetry,
|
|
990
996
|
onDone
|
|
991
997
|
})
|
|
@@ -614,17 +614,22 @@ addHook({
|
|
|
614
614
|
}
|
|
615
615
|
|
|
616
616
|
let attemptToFixPassed = false
|
|
617
|
+
let attemptToFixFailed = false
|
|
617
618
|
if (attemptToFixTasks.has(task)) {
|
|
618
619
|
const statuses = taskToStatuses.get(task)
|
|
619
|
-
if (statuses.length === testManagementAttemptToFixRetries
|
|
620
|
-
|
|
620
|
+
if (statuses.length === testManagementAttemptToFixRetries) {
|
|
621
|
+
if (statuses.every(status => status === 'pass')) {
|
|
622
|
+
attemptToFixPassed = true
|
|
623
|
+
} else if (statuses.some(status => status === 'fail')) {
|
|
624
|
+
attemptToFixFailed = true
|
|
625
|
+
}
|
|
621
626
|
}
|
|
622
627
|
}
|
|
623
628
|
|
|
624
629
|
if (asyncResource) {
|
|
625
630
|
// We don't finish here because the test might fail in a later hook (afterEach)
|
|
626
631
|
asyncResource.runInAsyncScope(() => {
|
|
627
|
-
testFinishTimeCh.publish({ status, task, attemptToFixPassed })
|
|
632
|
+
testFinishTimeCh.publish({ status, task, attemptToFixPassed, attemptToFixFailed })
|
|
628
633
|
})
|
|
629
634
|
}
|
|
630
635
|
|
|
@@ -776,8 +781,12 @@ addHook({
|
|
|
776
781
|
}
|
|
777
782
|
|
|
778
783
|
let hasFailedAllRetries = false
|
|
784
|
+
let attemptToFixFailed = false
|
|
779
785
|
if (attemptToFixTasks.has(task)) {
|
|
780
786
|
const statuses = taskToStatuses.get(task)
|
|
787
|
+
if (statuses.some(status => status === 'fail')) {
|
|
788
|
+
attemptToFixFailed = true
|
|
789
|
+
}
|
|
781
790
|
if (statuses.every(status => status === 'fail')) {
|
|
782
791
|
hasFailedAllRetries = true
|
|
783
792
|
}
|
|
@@ -787,7 +796,12 @@ addHook({
|
|
|
787
796
|
const isRetry = task.result?.retryCount > 0
|
|
788
797
|
// `duration` is the duration of all the retries, so it can't be used if there are retries
|
|
789
798
|
testAsyncResource.runInAsyncScope(() => {
|
|
790
|
-
testErrorCh.publish({
|
|
799
|
+
testErrorCh.publish({
|
|
800
|
+
duration: !isRetry ? duration : undefined,
|
|
801
|
+
error: testError,
|
|
802
|
+
hasFailedAllRetries,
|
|
803
|
+
attemptToFixFailed
|
|
804
|
+
})
|
|
791
805
|
})
|
|
792
806
|
}
|
|
793
807
|
if (errors?.length) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const KafkajsBatchConsumerPlugin = require('../../datadog-plugin-kafkajs/src/batch-consumer')
|
|
4
|
+
|
|
5
|
+
class ConfluentKafkaJsBatchConsumerPlugin extends KafkajsBatchConsumerPlugin {
|
|
6
|
+
static get id () {
|
|
7
|
+
return '@confluentinc/kafka-javascript'
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
module.exports = ConfluentKafkaJsBatchConsumerPlugin
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const KafkajsConsumerPlugin = require('../../datadog-plugin-kafkajs/src/consumer')
|
|
4
|
+
|
|
5
|
+
class ConfluentKafkaJsConsumerPlugin extends KafkajsConsumerPlugin {
|
|
6
|
+
static get id () {
|
|
7
|
+
return '@confluentinc/kafka-javascript'
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
module.exports = ConfluentKafkaJsConsumerPlugin
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const ProducerPlugin = require('./producer')
|
|
4
|
+
const ConsumerPlugin = require('./consumer')
|
|
5
|
+
const BatchConsumerPlugin = require('./batch-consumer')
|
|
6
|
+
const KafkajsPlugin = require('../../datadog-plugin-kafkajs/src/index')
|
|
7
|
+
|
|
8
|
+
class ConfluentKafkaJsPlugin extends KafkajsPlugin {
|
|
9
|
+
static get id () { return '@confluentinc/kafka-javascript' }
|
|
10
|
+
static get plugins () {
|
|
11
|
+
return {
|
|
12
|
+
producer: ProducerPlugin,
|
|
13
|
+
consumer: ConsumerPlugin,
|
|
14
|
+
batchConsumer: BatchConsumerPlugin
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = ConfluentKafkaJsPlugin
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const KafkajsProducerPlugin = require('../../datadog-plugin-kafkajs/src/producer')
|
|
4
|
+
|
|
5
|
+
class ConfluentKafkaJsProducerPlugin extends KafkajsProducerPlugin {
|
|
6
|
+
static get id () {
|
|
7
|
+
return '@confluentinc/kafka-javascript'
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
module.exports = ConfluentKafkaJsProducerPlugin
|
|
@@ -341,6 +341,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
341
341
|
isAttemptToFixRetry,
|
|
342
342
|
hasFailedAllRetries,
|
|
343
343
|
hasPassedAllRetries,
|
|
344
|
+
hasFailedAttemptToFix,
|
|
344
345
|
isDisabled,
|
|
345
346
|
isQuarantined
|
|
346
347
|
}) => {
|
|
@@ -385,6 +386,8 @@ class CucumberPlugin extends CiPlugin {
|
|
|
385
386
|
span.setTag(TEST_RETRY_REASON, TEST_RETRY_REASON_TYPES.atf)
|
|
386
387
|
if (hasPassedAllRetries) {
|
|
387
388
|
span.setTag(TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED, 'true')
|
|
389
|
+
} else if (hasFailedAttemptToFix) {
|
|
390
|
+
span.setTag(TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED, 'false')
|
|
388
391
|
}
|
|
389
392
|
}
|
|
390
393
|
|
|
@@ -838,6 +838,9 @@ class CypressPlugin {
|
|
|
838
838
|
}
|
|
839
839
|
const isLastAttempt = testStatuses.length === this.testManagementAttemptToFixRetries + 1
|
|
840
840
|
if (isLastAttempt) {
|
|
841
|
+
if (testStatuses.some(status => status === 'fail')) {
|
|
842
|
+
this.activeTestSpan.setTag(TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED, 'false')
|
|
843
|
+
}
|
|
841
844
|
if (testStatuses.every(status => status === 'fail')) {
|
|
842
845
|
this.activeTestSpan.setTag(TEST_HAS_FAILED_ALL_RETRIES, 'true')
|
|
843
846
|
} else if (testStatuses.every(status => status === 'pass')) {
|
|
@@ -6,7 +6,9 @@ class DNSLookupPlugin extends ClientPlugin {
|
|
|
6
6
|
static get id () { return 'dns' }
|
|
7
7
|
static get operation () { return 'lookup' }
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
bindStart (ctx) {
|
|
10
|
+
const [hostname] = ctx.args
|
|
11
|
+
|
|
10
12
|
this.startSpan('dns.lookup', {
|
|
11
13
|
service: this.config.service,
|
|
12
14
|
resource: hostname,
|
|
@@ -16,11 +18,14 @@ class DNSLookupPlugin extends ClientPlugin {
|
|
|
16
18
|
'dns.address': '',
|
|
17
19
|
'dns.addresses': ''
|
|
18
20
|
}
|
|
19
|
-
})
|
|
21
|
+
}, ctx)
|
|
22
|
+
|
|
23
|
+
return ctx.currentStore
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
const span =
|
|
26
|
+
bindFinish (ctx) {
|
|
27
|
+
const span = ctx.currentStore.span
|
|
28
|
+
const result = ctx.result
|
|
24
29
|
|
|
25
30
|
if (Array.isArray(result)) {
|
|
26
31
|
const addresses = Array.isArray(result)
|
|
@@ -33,7 +38,7 @@ class DNSLookupPlugin extends ClientPlugin {
|
|
|
33
38
|
span.setTag('dns.address', result)
|
|
34
39
|
}
|
|
35
40
|
|
|
36
|
-
|
|
41
|
+
return ctx.parentStore
|
|
37
42
|
}
|
|
38
43
|
}
|
|
39
44
|
|
|
@@ -6,7 +6,9 @@ class DNSLookupServicePlugin extends ClientPlugin {
|
|
|
6
6
|
static get id () { return 'dns' }
|
|
7
7
|
static get operation () { return 'lookup_service' }
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
bindStart (ctx) {
|
|
10
|
+
const [address, port] = ctx.args
|
|
11
|
+
|
|
10
12
|
this.startSpan('dns.lookup_service', {
|
|
11
13
|
service: this.config.service,
|
|
12
14
|
resource: `${address}:${port}`,
|
|
@@ -17,7 +19,9 @@ class DNSLookupServicePlugin extends ClientPlugin {
|
|
|
17
19
|
metrics: {
|
|
18
20
|
'dns.port': port
|
|
19
21
|
}
|
|
20
|
-
})
|
|
22
|
+
}, ctx)
|
|
23
|
+
|
|
24
|
+
return ctx.currentStore
|
|
21
25
|
}
|
|
22
26
|
}
|
|
23
27
|
|
|
@@ -6,7 +6,8 @@ class DNSResolvePlugin extends ClientPlugin {
|
|
|
6
6
|
static get id () { return 'dns' }
|
|
7
7
|
static get operation () { return 'resolve' }
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
bindStart (ctx) {
|
|
10
|
+
const [hostname, maybeType] = ctx.args
|
|
10
11
|
const rrtype = typeof maybeType === 'string' ? maybeType : 'A'
|
|
11
12
|
|
|
12
13
|
this.startSpan('dns.resolve', {
|
|
@@ -17,7 +18,9 @@ class DNSResolvePlugin extends ClientPlugin {
|
|
|
17
18
|
'dns.hostname': hostname,
|
|
18
19
|
'dns.rrtype': rrtype
|
|
19
20
|
}
|
|
20
|
-
})
|
|
21
|
+
}, ctx)
|
|
22
|
+
|
|
23
|
+
return ctx.currentStore
|
|
21
24
|
}
|
|
22
25
|
}
|
|
23
26
|
|
|
@@ -6,7 +6,9 @@ class DNSReversePlugin extends ClientPlugin {
|
|
|
6
6
|
static get id () { return 'dns' }
|
|
7
7
|
static get operation () { return 'reverse' }
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
bindStart (ctx) {
|
|
10
|
+
const [ip] = ctx.args
|
|
11
|
+
|
|
10
12
|
this.startSpan('dns.reverse', {
|
|
11
13
|
service: this.config.service,
|
|
12
14
|
resource: ip,
|
|
@@ -14,7 +16,9 @@ class DNSReversePlugin extends ClientPlugin {
|
|
|
14
16
|
meta: {
|
|
15
17
|
'dns.ip': ip
|
|
16
18
|
}
|
|
17
|
-
})
|
|
19
|
+
}, ctx)
|
|
20
|
+
|
|
21
|
+
return ctx.currentStore
|
|
18
22
|
}
|
|
19
23
|
}
|
|
20
24
|
|