dd-trace 5.21.0 → 5.23.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.
Files changed (153) hide show
  1. package/LICENSE-3rdparty.csv +2 -0
  2. package/index.d.ts +20 -8
  3. package/package.json +11 -5
  4. package/packages/datadog-instrumentations/src/aerospike.js +1 -1
  5. package/packages/datadog-instrumentations/src/apollo-server.js +1 -1
  6. package/packages/datadog-instrumentations/src/aws-sdk.js +4 -4
  7. package/packages/datadog-instrumentations/src/body-parser.js +4 -4
  8. package/packages/datadog-instrumentations/src/cassandra-driver.js +2 -2
  9. package/packages/datadog-instrumentations/src/child_process.js +2 -2
  10. package/packages/datadog-instrumentations/src/connect.js +4 -4
  11. package/packages/datadog-instrumentations/src/cookie-parser.js +4 -4
  12. package/packages/datadog-instrumentations/src/couchbase.js +12 -12
  13. package/packages/datadog-instrumentations/src/cucumber.js +294 -56
  14. package/packages/datadog-instrumentations/src/dns.js +10 -10
  15. package/packages/datadog-instrumentations/src/elasticsearch.js +4 -4
  16. package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +3 -3
  17. package/packages/datadog-instrumentations/src/express.js +4 -4
  18. package/packages/datadog-instrumentations/src/fastify.js +6 -6
  19. package/packages/datadog-instrumentations/src/fetch.js +1 -1
  20. package/packages/datadog-instrumentations/src/find-my-way.js +2 -2
  21. package/packages/datadog-instrumentations/src/fs.js +2 -2
  22. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +2 -2
  23. package/packages/datadog-instrumentations/src/grpc/client.js +4 -6
  24. package/packages/datadog-instrumentations/src/grpc/server.js +2 -2
  25. package/packages/datadog-instrumentations/src/hapi.js +10 -13
  26. package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
  27. package/packages/datadog-instrumentations/src/http/client.js +3 -3
  28. package/packages/datadog-instrumentations/src/jest.js +8 -5
  29. package/packages/datadog-instrumentations/src/kafkajs.js +67 -31
  30. package/packages/datadog-instrumentations/src/knex.js +2 -2
  31. package/packages/datadog-instrumentations/src/koa.js +5 -5
  32. package/packages/datadog-instrumentations/src/ldapjs.js +1 -1
  33. package/packages/datadog-instrumentations/src/mariadb.js +8 -8
  34. package/packages/datadog-instrumentations/src/memcached.js +2 -2
  35. package/packages/datadog-instrumentations/src/microgateway-core.js +7 -5
  36. package/packages/datadog-instrumentations/src/mocha/common.js +1 -1
  37. package/packages/datadog-instrumentations/src/mocha/main.js +139 -53
  38. package/packages/datadog-instrumentations/src/mocha/utils.js +37 -18
  39. package/packages/datadog-instrumentations/src/mocha/worker.js +29 -1
  40. package/packages/datadog-instrumentations/src/mocha.js +4 -0
  41. package/packages/datadog-instrumentations/src/moleculer/server.js +2 -2
  42. package/packages/datadog-instrumentations/src/mongodb-core.js +7 -7
  43. package/packages/datadog-instrumentations/src/mongoose.js +5 -6
  44. package/packages/datadog-instrumentations/src/mysql.js +3 -3
  45. package/packages/datadog-instrumentations/src/mysql2.js +6 -6
  46. package/packages/datadog-instrumentations/src/net.js +2 -2
  47. package/packages/datadog-instrumentations/src/next.js +5 -5
  48. package/packages/datadog-instrumentations/src/openai.js +62 -71
  49. package/packages/datadog-instrumentations/src/oracledb.js +8 -8
  50. package/packages/datadog-instrumentations/src/passport-http.js +1 -1
  51. package/packages/datadog-instrumentations/src/passport-local.js +1 -1
  52. package/packages/datadog-instrumentations/src/passport-utils.js +1 -1
  53. package/packages/datadog-instrumentations/src/pg.js +60 -5
  54. package/packages/datadog-instrumentations/src/pino.js +4 -4
  55. package/packages/datadog-instrumentations/src/playwright.js +6 -4
  56. package/packages/datadog-instrumentations/src/redis.js +2 -2
  57. package/packages/datadog-instrumentations/src/restify.js +4 -4
  58. package/packages/datadog-instrumentations/src/rhea.js +4 -4
  59. package/packages/datadog-instrumentations/src/router.js +5 -5
  60. package/packages/datadog-instrumentations/src/sharedb.js +2 -2
  61. package/packages/datadog-instrumentations/src/vitest.js +188 -12
  62. package/packages/datadog-instrumentations/src/winston.js +2 -3
  63. package/packages/datadog-plugin-amqplib/src/consumer.js +1 -3
  64. package/packages/datadog-plugin-aws-sdk/src/base.js +33 -0
  65. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -1
  66. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +2 -0
  67. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -1
  68. package/packages/datadog-plugin-cucumber/src/index.js +24 -1
  69. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +39 -10
  70. package/packages/datadog-plugin-cypress/src/support.js +4 -1
  71. package/packages/datadog-plugin-hapi/src/index.js +2 -2
  72. package/packages/datadog-plugin-http/src/client.js +1 -42
  73. package/packages/datadog-plugin-http2/src/client.js +1 -26
  74. package/packages/datadog-plugin-jest/src/index.js +18 -1
  75. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +20 -0
  76. package/packages/datadog-plugin-kafkajs/src/consumer.js +1 -2
  77. package/packages/datadog-plugin-kafkajs/src/index.js +3 -1
  78. package/packages/datadog-plugin-mocha/src/index.js +18 -0
  79. package/packages/datadog-plugin-openai/src/index.js +85 -65
  80. package/packages/datadog-plugin-playwright/src/index.js +9 -0
  81. package/packages/datadog-plugin-rhea/src/consumer.js +1 -3
  82. package/packages/datadog-plugin-vitest/src/index.js +68 -3
  83. package/packages/datadog-shimmer/src/shimmer.js +144 -10
  84. package/packages/dd-trace/src/appsec/addresses.js +3 -1
  85. package/packages/dd-trace/src/appsec/blocking.js +23 -17
  86. package/packages/dd-trace/src/appsec/channels.js +4 -2
  87. package/packages/dd-trace/src/appsec/graphql.js +3 -1
  88. package/packages/dd-trace/src/appsec/iast/iast-log.js +2 -1
  89. package/packages/dd-trace/src/appsec/rasp/index.js +103 -0
  90. package/packages/dd-trace/src/appsec/rasp/sql_injection.js +86 -0
  91. package/packages/dd-trace/src/appsec/rasp/ssrf.js +37 -0
  92. package/packages/dd-trace/src/appsec/rasp/utils.js +63 -0
  93. package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -0
  94. package/packages/dd-trace/src/appsec/remote_config/index.js +16 -7
  95. package/packages/dd-trace/src/appsec/remote_config/manager.js +93 -52
  96. package/packages/dd-trace/src/appsec/rule_manager.js +8 -0
  97. package/packages/dd-trace/src/appsec/telemetry.js +3 -3
  98. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +33 -14
  99. package/packages/dd-trace/src/appsec/waf/waf_manager.js +2 -1
  100. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +4 -0
  101. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +15 -1
  102. package/packages/dd-trace/src/config.js +100 -40
  103. package/packages/dd-trace/src/constants.js +11 -1
  104. package/packages/dd-trace/src/data_streams_context.js +3 -0
  105. package/packages/dd-trace/src/datastreams/fnv.js +23 -0
  106. package/packages/dd-trace/src/datastreams/pathway.js +12 -5
  107. package/packages/dd-trace/src/datastreams/processor.js +35 -0
  108. package/packages/dd-trace/src/datastreams/schemas/schema.js +8 -0
  109. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +125 -0
  110. package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +29 -0
  111. package/packages/dd-trace/src/debugger/devtools_client/config.js +24 -0
  112. package/packages/dd-trace/src/debugger/devtools_client/index.js +57 -0
  113. package/packages/dd-trace/src/debugger/devtools_client/inspector_promises_polyfill.js +23 -0
  114. package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +164 -0
  115. package/packages/dd-trace/src/debugger/devtools_client/send.js +28 -0
  116. package/packages/dd-trace/src/debugger/devtools_client/session.js +7 -0
  117. package/packages/dd-trace/src/debugger/devtools_client/state.js +47 -0
  118. package/packages/dd-trace/src/debugger/devtools_client/status.js +109 -0
  119. package/packages/dd-trace/src/debugger/index.js +92 -0
  120. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +29 -2
  121. package/packages/dd-trace/src/exporters/common/request.js +1 -1
  122. package/packages/dd-trace/src/lambda/handler.js +1 -0
  123. package/packages/dd-trace/src/lambda/index.js +12 -1
  124. package/packages/dd-trace/src/opentracing/propagation/text_map.js +1 -6
  125. package/packages/dd-trace/src/payload-tagging/config/aws.json +30 -0
  126. package/packages/dd-trace/src/payload-tagging/config/index.js +30 -0
  127. package/packages/dd-trace/src/payload-tagging/index.js +93 -0
  128. package/packages/dd-trace/src/payload-tagging/tagging.js +83 -0
  129. package/packages/dd-trace/src/plugin_manager.js +11 -10
  130. package/packages/dd-trace/src/plugins/ci_plugin.js +33 -8
  131. package/packages/dd-trace/src/plugins/util/env.js +5 -2
  132. package/packages/dd-trace/src/plugins/util/test.js +24 -4
  133. package/packages/dd-trace/src/profiler.js +15 -5
  134. package/packages/dd-trace/src/profiling/config.js +7 -4
  135. package/packages/dd-trace/src/profiling/exporter_cli.js +13 -1
  136. package/packages/dd-trace/src/profiling/exporters/agent.js +8 -2
  137. package/packages/dd-trace/src/profiling/profiler.js +0 -9
  138. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns.js +13 -0
  139. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookup.js +16 -0
  140. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookupservice.js +16 -0
  141. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_resolve.js +24 -0
  142. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_reverse.js +16 -0
  143. package/packages/dd-trace/src/profiling/profilers/event_plugins/event.js +48 -0
  144. package/packages/dd-trace/src/profiling/profilers/event_plugins/net.js +24 -0
  145. package/packages/dd-trace/src/profiling/profilers/events.js +108 -32
  146. package/packages/dd-trace/src/profiling/profilers/shared.js +5 -0
  147. package/packages/dd-trace/src/profiling/profilers/wall.js +9 -3
  148. package/packages/dd-trace/src/profiling/ssi-heuristics.js +59 -60
  149. package/packages/dd-trace/src/proxy.js +31 -24
  150. package/packages/dd-trace/src/span_stats.js +4 -2
  151. package/packages/dd-trace/src/telemetry/index.js +23 -6
  152. package/packages/dd-trace/src/telemetry/logs/index.js +20 -0
  153. package/packages/dd-trace/src/appsec/rasp.js +0 -176
@@ -58,7 +58,7 @@ addHook({ name: names }, (net, version, name) => {
58
58
  }
59
59
 
60
60
  const emit = this.emit
61
- this.emit = function (eventName) {
61
+ this.emit = shimmer.wrapFunction(emit, emit => function (eventName) {
62
62
  switch (eventName) {
63
63
  case 'ready':
64
64
  case 'connect':
@@ -68,7 +68,7 @@ addHook({ name: names }, (net, version, name) => {
68
68
  default:
69
69
  return emit.apply(this, arguments)
70
70
  }
71
- }
71
+ })
72
72
 
73
73
  try {
74
74
  return connect.apply(this, arguments)
@@ -188,7 +188,7 @@ function finish (ctx, result, err) {
188
188
  // however, it is not provided as a class function or exported property
189
189
  addHook({
190
190
  name: 'next',
191
- versions: ['>=13.3.0'],
191
+ versions: ['>=13.3.0 <14.2.7'],
192
192
  file: 'dist/server/web/spec-extension/adapters/next-request.js'
193
193
  }, NextRequestAdapter => {
194
194
  shimmer.wrap(NextRequestAdapter.NextRequestAdapter, 'fromNodeNextRequest', fromNodeNextRequest => {
@@ -203,7 +203,7 @@ addHook({
203
203
 
204
204
  addHook({
205
205
  name: 'next',
206
- versions: ['>=11.1'],
206
+ versions: ['>=11.1 <14.2.7'],
207
207
  file: 'dist/server/serve-static.js'
208
208
  }, serveStatic => shimmer.wrap(serveStatic, 'serveStatic', wrapServeStatic))
209
209
 
@@ -213,7 +213,7 @@ addHook({
213
213
  file: 'dist/next-server/server/serve-static.js'
214
214
  }, serveStatic => shimmer.wrap(serveStatic, 'serveStatic', wrapServeStatic))
215
215
 
216
- addHook({ name: 'next', versions: ['>=11.1'], file: 'dist/server/next-server.js' }, nextServer => {
216
+ addHook({ name: 'next', versions: ['>=11.1 <14.2.7'], file: 'dist/server/next-server.js' }, nextServer => {
217
217
  const Server = nextServer.default
218
218
 
219
219
  shimmer.wrap(Server.prototype, 'handleRequest', wrapHandleRequest)
@@ -230,7 +230,7 @@ addHook({ name: 'next', versions: ['>=11.1'], file: 'dist/server/next-server.js'
230
230
  })
231
231
 
232
232
  // `handleApiRequest` changes parameters/implementation at 13.2.0
233
- addHook({ name: 'next', versions: ['>=13.2'], file: 'dist/server/next-server.js' }, nextServer => {
233
+ addHook({ name: 'next', versions: ['>=13.2 <14.2.7'], file: 'dist/server/next-server.js' }, nextServer => {
234
234
  const Server = nextServer.default
235
235
  shimmer.wrap(Server.prototype, 'handleApiRequest', wrapHandleApiRequestWithMatch)
236
236
  return nextServer
@@ -264,7 +264,7 @@ addHook({
264
264
 
265
265
  addHook({
266
266
  name: 'next',
267
- versions: ['>=13'],
267
+ versions: ['>=13 <14.2.7'],
268
268
  file: 'dist/server/web/spec-extension/request.js'
269
269
  }, request => {
270
270
  const nextUrlDescriptor = Object.getOwnPropertyDescriptor(request.NextRequest.prototype, 'nextUrl')
@@ -1,14 +1,10 @@
1
1
  'use strict'
2
2
 
3
- const {
4
- channel,
5
- addHook
6
- } = require('./helpers/instrument')
3
+ const { addHook } = require('./helpers/instrument')
7
4
  const shimmer = require('../../datadog-shimmer')
8
5
 
9
- const startCh = channel('apm:openai:request:start')
10
- const finishCh = channel('apm:openai:request:finish')
11
- const errorCh = channel('apm:openai:request:error')
6
+ const tracingChannel = require('dc-polyfill').tracingChannel
7
+ const ch = tracingChannel('apm:openai:request')
12
8
 
13
9
  const V4_PACKAGE_SHIMS = [
14
10
  {
@@ -110,33 +106,18 @@ addHook({ name: 'openai', file: 'dist/api.js', versions: ['>=3.0.0 <4'] }, expor
110
106
 
111
107
  for (const methodName of methodNames) {
112
108
  shimmer.wrap(exports.OpenAIApi.prototype, methodName, fn => function () {
113
- if (!startCh.hasSubscribers) {
109
+ if (!ch.start.hasSubscribers) {
114
110
  return fn.apply(this, arguments)
115
111
  }
116
112
 
117
- startCh.publish({
113
+ const ctx = {
118
114
  methodName,
119
115
  args: arguments,
120
116
  basePath: this.basePath,
121
117
  apiKey: this.configuration.apiKey
122
- })
123
-
124
- return fn.apply(this, arguments)
125
- .then((response) => {
126
- finish({
127
- headers: response.headers,
128
- body: response.data,
129
- path: response.request.path,
130
- method: response.request.method
131
- })
132
-
133
- return response
134
- })
135
- .catch(error => {
136
- finish(undefined, error)
118
+ }
137
119
 
138
- throw error
139
- })
120
+ return ch.tracePromise(fn, ctx, this, ...arguments)
140
121
  })
141
122
  }
142
123
 
@@ -184,10 +165,12 @@ function addStreamedChunk (content, chunk) {
184
165
 
185
166
  if (tools) {
186
167
  oldChoice.delta.tool_calls = tools.map((newTool, toolIdx) => {
187
- const oldTool = oldChoice.delta.tool_calls[toolIdx]
168
+ const oldTool = oldChoice.delta.tool_calls?.[toolIdx]
188
169
 
189
170
  if (oldTool) {
190
171
  oldTool.function.arguments += newTool.function.arguments
172
+ } else {
173
+ return newTool
191
174
  }
192
175
 
193
176
  return oldTool
@@ -213,7 +196,7 @@ function convertBufferstoObjects (chunks = []) {
213
196
  * the chunks, and let the combined content be the final response.
214
197
  * This way, spans look the same as when not streamed.
215
198
  */
216
- function wrapStreamIterator (response, options, n) {
199
+ function wrapStreamIterator (response, options, n, ctx) {
217
200
  let processChunksAsBuffers = false
218
201
  let chunks = []
219
202
  return function (itr) {
@@ -253,18 +236,20 @@ function wrapStreamIterator (response, options, n) {
253
236
  }
254
237
  }
255
238
 
256
- finish({
239
+ finish(ctx, {
257
240
  headers: response.headers,
258
- body,
259
- path: response.url,
260
- method: options.method
241
+ data: body,
242
+ request: {
243
+ path: response.url,
244
+ method: options.method
245
+ }
261
246
  })
262
247
  }
263
248
 
264
249
  return res
265
250
  })
266
251
  .catch(err => {
267
- finish(undefined, err)
252
+ finish(ctx, undefined, err)
268
253
 
269
254
  throw err
270
255
  })
@@ -281,7 +266,7 @@ for (const shim of V4_PACKAGE_SHIMS) {
281
266
 
282
267
  for (const methodName of methods) {
283
268
  shimmer.wrap(targetPrototype, methodName, methodFn => function () {
284
- if (!startCh.hasSubscribers) {
269
+ if (!ch.start.hasSubscribers) {
285
270
  return methodFn.apply(this, arguments)
286
271
  }
287
272
 
@@ -303,66 +288,72 @@ for (const shim of V4_PACKAGE_SHIMS) {
303
288
 
304
289
  const client = this._client || this.client
305
290
 
306
- startCh.publish({
291
+ const ctx = {
307
292
  methodName: `${baseResource}.${methodName}`,
308
293
  args: arguments,
309
294
  basePath: client.baseURL,
310
295
  apiKey: client.apiKey
311
- })
296
+ }
312
297
 
313
- const apiProm = methodFn.apply(this, arguments)
298
+ return ch.start.runStores(ctx, () => {
299
+ const apiProm = methodFn.apply(this, arguments)
314
300
 
315
- // wrapping `parse` avoids problematic wrapping of `then` when trying to call
316
- // `withResponse` in userland code after. This way, we can return the whole `APIPromise`
317
- shimmer.wrap(apiProm, 'parse', origApiPromParse => function () {
318
- return origApiPromParse.apply(this, arguments)
301
+ // wrapping `parse` avoids problematic wrapping of `then` when trying to call
302
+ // `withResponse` in userland code after. This way, we can return the whole `APIPromise`
303
+ shimmer.wrap(apiProm, 'parse', origApiPromParse => function () {
304
+ return origApiPromParse.apply(this, arguments)
319
305
  // the original response is wrapped in a promise, so we need to unwrap it
320
- .then(body => Promise.all([this.responsePromise, body]))
321
- .then(([{ response, options }, body]) => {
322
- if (stream) {
323
- if (body.iterator) {
324
- shimmer.wrap(body, 'iterator', wrapStreamIterator(response, options, n))
306
+ .then(body => Promise.all([this.responsePromise, body]))
307
+ .then(([{ response, options }, body]) => {
308
+ if (stream) {
309
+ if (body.iterator) {
310
+ shimmer.wrap(body, 'iterator', wrapStreamIterator(response, options, n, ctx))
311
+ } else {
312
+ shimmer.wrap(
313
+ body.response.body, Symbol.asyncIterator, wrapStreamIterator(response, options, n, ctx)
314
+ )
315
+ }
325
316
  } else {
326
- shimmer.wrap(
327
- body.response.body, Symbol.asyncIterator, wrapStreamIterator(response, options, n)
328
- )
317
+ finish(ctx, {
318
+ headers: response.headers,
319
+ data: body,
320
+ request: {
321
+ path: response.url,
322
+ method: options.method
323
+ }
324
+ })
329
325
  }
330
- } else {
331
- finish({
332
- headers: response.headers,
333
- body,
334
- path: response.url,
335
- method: options.method
336
- })
337
- }
338
326
 
339
- return body
340
- })
341
- .catch(error => {
342
- finish(undefined, error)
327
+ return body
328
+ })
329
+ .catch(error => {
330
+ finish(ctx, undefined, error)
343
331
 
344
- throw error
345
- })
346
- .finally(() => {
332
+ throw error
333
+ })
334
+ .finally(() => {
347
335
  // maybe we don't want to unwrap here in case the promise is re-used?
348
336
  // other hand: we want to avoid resource leakage
349
- shimmer.unwrap(apiProm, 'parse')
350
- })
351
- })
337
+ shimmer.unwrap(apiProm, 'parse')
338
+ })
339
+ })
352
340
 
353
- return apiProm
341
+ return apiProm
342
+ })
354
343
  })
355
344
  }
356
345
  return exports
357
346
  })
358
347
  }
359
348
 
360
- function finish (response, error) {
349
+ function finish (ctx, response, error) {
361
350
  if (error) {
362
- errorCh.publish({ error })
351
+ ctx.error = error
352
+ ch.error.publish(ctx)
363
353
  }
364
354
 
365
- finishCh.publish(response)
355
+ ctx.result = response
356
+ ch.asyncEnd.publish(ctx)
366
357
  }
367
358
 
368
359
  function getOption (args, option, defaultValue) {
@@ -31,10 +31,10 @@ addHook({ name: 'oracledb', versions: ['>=5'] }, oracledb => {
31
31
  if (arguments.length && typeof arguments[arguments.length - 1] === 'function') {
32
32
  const cb = arguments[arguments.length - 1]
33
33
  const outerAr = new AsyncResource('apm:oracledb:outer-scope')
34
- arguments[arguments.length - 1] = function wrappedCb (err, result) {
34
+ arguments[arguments.length - 1] = shimmer.wrapFunction(cb, cb => function wrappedCb (err, result) {
35
35
  finish(err)
36
36
  return outerAr.runInAsyncScope(() => cb.apply(this, arguments))
37
- }
37
+ })
38
38
  }
39
39
 
40
40
  return new AsyncResource('apm:oracledb:inner-scope').runInAsyncScope(() => {
@@ -67,12 +67,12 @@ addHook({ name: 'oracledb', versions: ['>=5'] }, oracledb => {
67
67
  shimmer.wrap(oracledb, 'getConnection', getConnection => {
68
68
  return function wrappedGetConnection (connAttrs, callback) {
69
69
  if (callback) {
70
- arguments[1] = (err, connection) => {
70
+ arguments[1] = shimmer.wrapFunction(callback, callback => (err, connection) => {
71
71
  if (connection) {
72
72
  connectionAttributes.set(connection, connAttrs)
73
73
  }
74
74
  callback(err, connection)
75
- }
75
+ })
76
76
 
77
77
  getConnection.apply(this, arguments)
78
78
  } else {
@@ -86,12 +86,12 @@ addHook({ name: 'oracledb', versions: ['>=5'] }, oracledb => {
86
86
  shimmer.wrap(oracledb, 'createPool', createPool => {
87
87
  return function wrappedCreatePool (poolAttrs, callback) {
88
88
  if (callback) {
89
- arguments[1] = (err, pool) => {
89
+ arguments[1] = shimmer.wrapFunction(callback, callback => (err, pool) => {
90
90
  if (pool) {
91
91
  poolAttributes.set(pool, poolAttrs)
92
92
  }
93
93
  callback(err, pool)
94
- }
94
+ })
95
95
 
96
96
  createPool.apply(this, arguments)
97
97
  } else {
@@ -109,12 +109,12 @@ addHook({ name: 'oracledb', versions: ['>=5'] }, oracledb => {
109
109
  callback = arguments[arguments.length - 1]
110
110
  }
111
111
  if (callback) {
112
- arguments[arguments.length - 1] = (err, connection) => {
112
+ arguments[arguments.length - 1] = shimmer.wrapFunction(callback, callback => (err, connection) => {
113
113
  if (connection) {
114
114
  connectionAttributes.set(connection, poolAttributes.get(this))
115
115
  }
116
116
  callback(err, connection)
117
- }
117
+ })
118
118
  getConnection.apply(this, arguments)
119
119
  } else {
120
120
  return getConnection.apply(this, arguments).then((connection) => {
@@ -9,7 +9,7 @@ addHook({
9
9
  file: 'lib/passport-http/strategies/basic.js',
10
10
  versions: ['>=0.3.0']
11
11
  }, BasicStrategy => {
12
- return shimmer.wrap(BasicStrategy, function () {
12
+ return shimmer.wrapFunction(BasicStrategy, BasicStrategy => function () {
13
13
  const type = 'http'
14
14
 
15
15
  if (typeof arguments[0] === 'function') {
@@ -9,7 +9,7 @@ addHook({
9
9
  file: 'lib/strategy.js',
10
10
  versions: ['>=1.0.0']
11
11
  }, Strategy => {
12
- return shimmer.wrap(Strategy, function () {
12
+ return shimmer.wrapFunction(Strategy, Strategy => function () {
13
13
  const type = 'local'
14
14
 
15
15
  if (typeof arguments[0] === 'function') {
@@ -11,7 +11,7 @@ function wrapVerifiedAndPublish (username, password, verified, type) {
11
11
  }
12
12
 
13
13
  // eslint-disable-next-line n/handle-callback-err
14
- return shimmer.wrap(verified, function (err, user, info) {
14
+ return shimmer.wrapFunction(verified, verified => function (err, user, info) {
15
15
  const credentials = { type, username }
16
16
  passportVerifyChannel.publish({ credentials, user })
17
17
  return verified.apply(this, arguments)
@@ -53,14 +53,15 @@ function wrapQuery (query) {
53
53
  }
54
54
 
55
55
  return asyncResource.runInAsyncScope(() => {
56
+ const abortController = new AbortController()
57
+
56
58
  startCh.publish({
57
59
  params: this.connectionParameters,
58
60
  query: pgQuery,
59
- processId
61
+ processId,
62
+ abortController
60
63
  })
61
64
 
62
- arguments[0] = pgQuery
63
-
64
65
  const finish = asyncResource.bind(function (error) {
65
66
  if (error) {
66
67
  errorCh.publish(error)
@@ -68,6 +69,43 @@ function wrapQuery (query) {
68
69
  finishCh.publish()
69
70
  })
70
71
 
72
+ if (abortController.signal.aborted) {
73
+ const error = abortController.signal.reason || new Error('Aborted')
74
+
75
+ // eslint-disable-next-line max-len
76
+ // Based on: https://github.com/brianc/node-postgres/blob/54eb0fa216aaccd727765641e7d1cf5da2bc483d/packages/pg/lib/client.js#L510
77
+ const reusingQuery = typeof pgQuery.submit === 'function'
78
+ const callback = arguments[arguments.length - 1]
79
+
80
+ finish(error)
81
+
82
+ if (reusingQuery) {
83
+ if (!pgQuery.callback && typeof callback === 'function') {
84
+ pgQuery.callback = callback
85
+ }
86
+
87
+ if (pgQuery.callback) {
88
+ pgQuery.callback(error)
89
+ } else {
90
+ process.nextTick(() => {
91
+ pgQuery.emit('error', error)
92
+ })
93
+ }
94
+
95
+ return pgQuery
96
+ }
97
+
98
+ if (typeof callback === 'function') {
99
+ callback(error)
100
+
101
+ return
102
+ }
103
+
104
+ return Promise.reject(error)
105
+ }
106
+
107
+ arguments[0] = pgQuery
108
+
71
109
  const retval = query.apply(this, arguments)
72
110
  const queryQueue = this.queryQueue || this._queryQueue
73
111
  const activeQuery = this.activeQuery || this._activeQuery
@@ -112,8 +150,11 @@ function wrapPoolQuery (query) {
112
150
  const pgQuery = arguments[0] !== null && typeof arguments[0] === 'object' ? arguments[0] : { text: arguments[0] }
113
151
 
114
152
  return asyncResource.runInAsyncScope(() => {
153
+ const abortController = new AbortController()
154
+
115
155
  startPoolQueryCh.publish({
116
- query: pgQuery
156
+ query: pgQuery,
157
+ abortController
117
158
  })
118
159
 
119
160
  const finish = asyncResource.bind(function () {
@@ -121,8 +162,22 @@ function wrapPoolQuery (query) {
121
162
  })
122
163
 
123
164
  const cb = arguments[arguments.length - 1]
165
+
166
+ if (abortController.signal.aborted) {
167
+ const error = abortController.signal.reason || new Error('Aborted')
168
+ finish()
169
+
170
+ if (typeof cb === 'function') {
171
+ cb(error)
172
+
173
+ return
174
+ } else {
175
+ return Promise.reject(error)
176
+ }
177
+ }
178
+
124
179
  if (typeof cb === 'function') {
125
- arguments[arguments.length - 1] = shimmer.wrap(cb, function () {
180
+ arguments[arguments.length - 1] = shimmer.wrapFunction(cb, cb => function () {
126
181
  finish()
127
182
  return cb.apply(this, arguments)
128
183
  })
@@ -76,19 +76,19 @@ function wrapPrettyFactory (prettyFactory) {
76
76
  addHook({ name: 'pino', versions: ['2 - 3', '4', '>=5 <5.14.0'] }, pino => {
77
77
  const asJsonSym = (pino.symbols && pino.symbols.asJsonSym) || 'asJson'
78
78
 
79
- return shimmer.wrap(pino, wrapPino(asJsonSym, wrapAsJson, pino))
79
+ return shimmer.wrapFunction(pino, pino => wrapPino(asJsonSym, wrapAsJson, pino))
80
80
  })
81
81
 
82
82
  addHook({ name: 'pino', versions: ['>=5.14.0 <6.8.0'] }, pino => {
83
83
  const mixinSym = pino.symbols.mixinSym
84
84
 
85
- return shimmer.wrap(pino, wrapPino(mixinSym, wrapMixin, pino))
85
+ return shimmer.wrapFunction(pino, pino => wrapPino(mixinSym, wrapMixin, pino))
86
86
  })
87
87
 
88
88
  addHook({ name: 'pino', versions: ['>=6.8.0'] }, pino => {
89
89
  const mixinSym = pino.symbols.mixinSym
90
90
 
91
- const wrapped = shimmer.wrap(pino, wrapPino(mixinSym, wrapMixin, pino))
91
+ const wrapped = shimmer.wrapFunction(pino, pino => wrapPino(mixinSym, wrapMixin, pino))
92
92
  wrapped.pino = wrapped
93
93
  wrapped.default = wrapped
94
94
 
@@ -101,5 +101,5 @@ addHook({ name: 'pino-pretty', file: 'lib/utils.js', versions: ['>=3'] }, utils
101
101
  })
102
102
 
103
103
  addHook({ name: 'pino-pretty', versions: ['1 - 2'] }, prettyFactory => {
104
- return shimmer.wrap(prettyFactory, wrapPrettyFactory(prettyFactory))
104
+ return shimmer.wrapFunction(prettyFactory, wrapPrettyFactory)
105
105
  })
@@ -2,7 +2,7 @@ const semver = require('semver')
2
2
 
3
3
  const { addHook, channel, AsyncResource } = require('./helpers/instrument')
4
4
  const shimmer = require('../../datadog-shimmer')
5
- const { parseAnnotations, getTestSuitePath, NUM_FAILED_TEST_RETRIES } = require('../../dd-trace/src/plugins/util/test')
5
+ const { parseAnnotations, getTestSuitePath } = require('../../dd-trace/src/plugins/util/test')
6
6
  const log = require('../../dd-trace/src/log')
7
7
 
8
8
  const testStartCh = channel('ci:playwright:test:start')
@@ -36,8 +36,9 @@ const STATUS_TO_TEST_STATUS = {
36
36
 
37
37
  let remainingTestsByFile = {}
38
38
  let isEarlyFlakeDetectionEnabled = false
39
- let isFlakyTestRetriesEnabled = false
40
39
  let earlyFlakeDetectionNumRetries = 0
40
+ let isFlakyTestRetriesEnabled = false
41
+ let flakyTestRetriesCount = 0
41
42
  let knownTests = {}
42
43
  let rootDir = ''
43
44
  const MINIMUM_SUPPORTED_VERSION_EFD = '1.38.0'
@@ -407,6 +408,7 @@ function runnerHook (runnerExport, playwrightVersion) {
407
408
  isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
408
409
  earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
409
410
  isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
411
+ flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount
410
412
  }
411
413
  } catch (e) {
412
414
  isEarlyFlakeDetectionEnabled = false
@@ -429,10 +431,10 @@ function runnerHook (runnerExport, playwrightVersion) {
429
431
 
430
432
  const projects = getProjectsFromRunner(this)
431
433
 
432
- if (isFlakyTestRetriesEnabled) {
434
+ if (isFlakyTestRetriesEnabled && flakyTestRetriesCount > 0) {
433
435
  projects.forEach(project => {
434
436
  if (project.retries === 0) { // Only if it hasn't been set by the user
435
- project.retries = NUM_FAILED_TEST_RETRIES
437
+ project.retries = flakyTestRetriesCount
436
438
  }
437
439
  })
438
440
  }
@@ -156,12 +156,12 @@ function start (client, command, args, url = {}) {
156
156
  }
157
157
 
158
158
  function wrapCallback (finishCh, errorCh, callback) {
159
- return function (err) {
159
+ return shimmer.wrapFunction(callback, callback => function (err) {
160
160
  finish(finishCh, errorCh, err)
161
161
  if (callback) {
162
162
  return callback.apply(this, arguments)
163
163
  }
164
- }
164
+ })
165
165
  }
166
166
 
167
167
  function finish (finishCh, errorCh, error) {
@@ -40,7 +40,7 @@ function wrapMiddleware (middleware) {
40
40
  function wrapFn (fn) {
41
41
  if (Array.isArray(fn)) return wrapMiddleware(fn)
42
42
 
43
- return function (req, res, next) {
43
+ return shimmer.wrapFunction(fn, fn => function (req, res, next) {
44
44
  if (typeof next === 'function') {
45
45
  arguments[2] = wrapNext(req, next)
46
46
  }
@@ -72,16 +72,16 @@ function wrapFn (fn) {
72
72
  } finally {
73
73
  exitChannel.publish({ req })
74
74
  }
75
- }
75
+ })
76
76
  }
77
77
 
78
78
  function wrapNext (req, next) {
79
- return function () {
79
+ return shimmer.wrapFunction(next, next => function () {
80
80
  nextChannel.publish({ req })
81
81
  finishChannel.publish({ req })
82
82
 
83
83
  next.apply(this, arguments)
84
- }
84
+ })
85
85
  }
86
86
 
87
87
  addHook({ name: 'restify', versions: ['>=3'], file: 'lib/server.js' }, Server => {
@@ -153,11 +153,11 @@ function wrapDeliveryUpdate (obj, update) {
153
153
  const asyncResource = context.asyncResource
154
154
  if (obj && asyncResource) {
155
155
  const cb = asyncResource.bind(update)
156
- return AsyncResource.bind(function wrappedUpdate (settled, stateData) {
156
+ return shimmer.wrapFunction(cb, cb => AsyncResource.bind(function wrappedUpdate (settled, stateData) {
157
157
  const state = getStateFromData(stateData)
158
158
  dispatchReceiveCh.publish({ state })
159
159
  return cb.apply(this, arguments)
160
- })
160
+ }))
161
161
  }
162
162
  return function wrappedUpdate (settled, stateData) {
163
163
  return update.apply(this, arguments)
@@ -178,7 +178,7 @@ function patchCircularBuffer (proto, Session) {
178
178
  }
179
179
  if (CircularBuffer && !patched.has(CircularBuffer.prototype)) {
180
180
  shimmer.wrap(CircularBuffer.prototype, 'pop_if', popIf => function (fn) {
181
- arguments[0] = AsyncResource.bind(function (entry) {
181
+ arguments[0] = shimmer.wrapFunction(fn, fn => AsyncResource.bind(function (entry) {
182
182
  const context = contexts.get(entry)
183
183
  const asyncResource = context && context.asyncResource
184
184
 
@@ -198,7 +198,7 @@ function patchCircularBuffer (proto, Session) {
198
198
  }
199
199
 
200
200
  return shouldPop
201
- })
201
+ }))
202
202
  return popIf.apply(this, arguments)
203
203
  })
204
204
  patched.add(CircularBuffer.prototype)
@@ -18,7 +18,7 @@ function createWrapRouterMethod (name) {
18
18
  function wrapLayerHandle (layer, original) {
19
19
  original._name = original._name || layer.name
20
20
 
21
- const handle = shimmer.wrap(original, function () {
21
+ const handle = shimmer.wrapFunction(original, original => function () {
22
22
  if (!enterChannel.hasSubscribers) return original.apply(this, arguments)
23
23
 
24
24
  const matchers = layerMatchers.get(layer)
@@ -89,7 +89,7 @@ function createWrapRouterMethod (name) {
89
89
  }
90
90
 
91
91
  function wrapNext (req, next) {
92
- return function (error) {
92
+ return shimmer.wrapFunction(next, next => function (error) {
93
93
  if (error && error !== 'route' && error !== 'router') {
94
94
  errorChannel.publish({ req, error })
95
95
  }
@@ -98,7 +98,7 @@ function createWrapRouterMethod (name) {
98
98
  finishChannel.publish({ req })
99
99
 
100
100
  next.apply(this, arguments)
101
- }
101
+ })
102
102
  }
103
103
 
104
104
  function extractMatchers (fn) {
@@ -151,7 +151,7 @@ function createWrapRouterMethod (name) {
151
151
  }
152
152
 
153
153
  function wrapMethod (original) {
154
- return function methodWithTrace (fn) {
154
+ return shimmer.wrapFunction(original, original => function methodWithTrace (fn) {
155
155
  const offset = this.stack ? [].concat(this.stack).length : 0
156
156
  const router = original.apply(this, arguments)
157
157
 
@@ -162,7 +162,7 @@ function createWrapRouterMethod (name) {
162
162
  wrapStack(this.stack, offset, extractMatchers(fn))
163
163
 
164
164
  return router
165
- }
165
+ })
166
166
  }
167
167
 
168
168
  return wrapMethod