dd-trace 6.9.0 → 6.10.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 (59) hide show
  1. package/ci/vitest-no-worker-init-setup.mjs +112 -10
  2. package/index.d.ts +42 -0
  3. package/package.json +4 -3
  4. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +111 -6
  5. package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +629 -0
  6. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -1
  7. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +81 -0
  8. package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +1 -0
  9. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +83 -1
  10. package/packages/datadog-instrumentations/src/jest.js +1 -1
  11. package/packages/datadog-instrumentations/src/mocha/main.js +1 -1
  12. package/packages/datadog-instrumentations/src/mocha/utils.js +2 -8
  13. package/packages/datadog-instrumentations/src/mysql.js +45 -15
  14. package/packages/datadog-instrumentations/src/mysql2.js +119 -18
  15. package/packages/datadog-instrumentations/src/path-to-regexp.js +67 -1
  16. package/packages/datadog-instrumentations/src/pg.js +116 -92
  17. package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +43 -4
  18. package/packages/datadog-instrumentations/src/vitest-main.js +169 -17
  19. package/packages/datadog-instrumentations/src/vitest-util.js +64 -5
  20. package/packages/datadog-instrumentations/src/vitest-worker.js +150 -25
  21. package/packages/datadog-instrumentations/src/webdriverio.js +31 -17
  22. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +12 -6
  23. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -5
  24. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -5
  25. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +1 -1
  26. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +31 -17
  27. package/packages/datadog-plugin-jest/src/index.js +5 -4
  28. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -3
  29. package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -3
  30. package/packages/datadog-plugin-kafkajs/src/producer.js +3 -2
  31. package/packages/datadog-plugin-kafkajs/src/utils.js +65 -7
  32. package/packages/datadog-plugin-mocha/src/index.js +550 -39
  33. package/packages/datadog-plugin-mysql/src/index.js +37 -0
  34. package/packages/datadog-plugin-next/src/index.js +1 -19
  35. package/packages/datadog-plugin-openai-agents/src/integration.js +278 -69
  36. package/packages/datadog-plugin-openai-agents/src/processor.js +16 -4
  37. package/packages/datadog-plugin-pg/src/index.js +1 -0
  38. package/packages/datadog-plugin-vitest/src/index.js +8 -20
  39. package/packages/datadog-plugin-ws/src/util.js +2 -1
  40. package/packages/dd-trace/src/appsec/api_security/normalized-route.js +453 -0
  41. package/packages/dd-trace/src/appsec/handlers/http-request.js +13 -0
  42. package/packages/dd-trace/src/carrier.js +356 -0
  43. package/packages/dd-trace/src/config/generated-config-types.d.ts +3 -0
  44. package/packages/dd-trace/src/config/supported-configurations.json +10 -0
  45. package/packages/dd-trace/src/datastreams/context.js +6 -1
  46. package/packages/dd-trace/src/datastreams/manager.js +5 -1
  47. package/packages/dd-trace/src/datastreams/pathway.js +23 -22
  48. package/packages/dd-trace/src/datastreams/processor.js +3 -2
  49. package/packages/dd-trace/src/llmobs/constants/tags.js +5 -0
  50. package/packages/dd-trace/src/llmobs/index.js +34 -2
  51. package/packages/dd-trace/src/llmobs/span_processor.js +16 -0
  52. package/packages/dd-trace/src/llmobs/tagger.js +96 -0
  53. package/packages/dd-trace/src/llmobs/util.js +78 -0
  54. package/packages/dd-trace/src/opentracing/propagation/text_map.js +126 -120
  55. package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +4 -8
  56. package/packages/dd-trace/src/plugin_manager.js +2 -0
  57. package/packages/{datadog-plugin-jest/src/util.js → dd-trace/src/plugins/util/jest.js} +1 -62
  58. package/packages/dd-trace/src/plugins/util/test.js +84 -5
  59. package/packages/dd-trace/src/plugins/util/web.js +53 -2
@@ -0,0 +1,629 @@
1
+ 'use strict'
2
+
3
+ const { errorMonitor } = require('node:events')
4
+ const { performance } = require('node:perf_hooks')
5
+
6
+ /**
7
+ * @typedef {import('node:diagnostics_channel').Channel} Channel
8
+ * @typedef {{ length: number, [index: number]: unknown } & Iterable<unknown>} ArgumentsLike
9
+ * @typedef {{
10
+ * acquired?: boolean,
11
+ * callback?: Function,
12
+ * conf?: Record<string, unknown>,
13
+ * errorReported?: boolean,
14
+ * key?: object,
15
+ * observesError?: boolean,
16
+ * start?: number
17
+ * }} ClusterAcquire
18
+ * @typedef {{ _freeConnections?: { length: number } }} Pool
19
+ * @typedef {{ deferred: boolean }} PoolWaitTransfer
20
+ * @typedef {{ transfer: PoolWaitTransfer, waitTime: number }} DeferredPoolWait
21
+ * @typedef {{ pending: boolean, pool: object }} DeferredPoolQueryAcquire
22
+ * @typedef {{
23
+ * connectionFinishCh: Channel,
24
+ * acquireStartCh: Channel,
25
+ * acquireFinishCh: Channel
26
+ * }} AcquireErrorChannels
27
+ * @typedef {{
28
+ * connectionStartCh: Channel,
29
+ * connectionFinishCh: Channel,
30
+ * acquireStartCh: Channel,
31
+ * acquireFinishCh: Channel,
32
+ * reentersQueuedCallbacks?: boolean
33
+ * }} AcquireChannels
34
+ */
35
+
36
+ const poolQueryAcquire = {}
37
+
38
+ /** @type {ClusterAcquire | typeof poolQueryAcquire | undefined} */
39
+ let currentPoolQueryAcquire
40
+
41
+ /** @type {import('node:async_hooks').AsyncLocalStorage<DeferredPoolQueryAcquire>|undefined} */
42
+ let deferredPoolQueryAcquireStorage
43
+
44
+ /** @type {WeakMap<object, ClusterAcquire>} */
45
+ const deferredClusterAcquires = new WeakMap()
46
+
47
+ // Keep synchronous wait handoff allocation-free; a delayed consumer promotes only its pool wrapper.
48
+ const poolWaitConnections = []
49
+ const poolWaitTimes = []
50
+
51
+ /** @type {WeakMap<object, DeferredPoolWait>} */
52
+ const deferredPoolWaitTimes = new WeakMap()
53
+ let deferredPoolWaitCount = 0
54
+
55
+ /**
56
+ * @param {Function} method
57
+ * @param {Channel} connectionStartCh
58
+ * @param {boolean} [deferred]
59
+ * @returns {Function}
60
+ */
61
+ function wrapPoolQueryMethod (method, connectionStartCh, deferred) {
62
+ if (deferred) {
63
+ return function () {
64
+ if (!connectionStartCh.hasSubscribers) return method.apply(this, arguments)
65
+
66
+ const storage = getDeferredPoolQueryAcquireStorage()
67
+ return storage.run({ pending: true, pool: this }, () => method.apply(this, arguments))
68
+ }
69
+ }
70
+
71
+ return function () {
72
+ if (!connectionStartCh.hasSubscribers) return method.apply(this, arguments)
73
+ return runWithPoolQueryAcquire(poolQueryAcquire, method, this, arguments)
74
+ }
75
+ }
76
+
77
+ /**
78
+ * @param {Function} method
79
+ * @param {Function} inactiveMethod
80
+ * @param {Channel} connectionStartCh
81
+ * @param {boolean} deferred
82
+ * @returns {Function}
83
+ */
84
+ function wrapPoolAcquireCarrier (method, inactiveMethod, connectionStartCh, deferred) {
85
+ if (!deferred) return method
86
+
87
+ return function (callback) {
88
+ if (!connectionStartCh.hasSubscribers) return inactiveMethod.apply(this, arguments)
89
+ if (typeof callback !== 'function' || !takeDeferredPoolQueryAcquire(this)) {
90
+ return method.apply(this, arguments)
91
+ }
92
+
93
+ return runWithPoolQueryAcquire(poolQueryAcquire, method, this, arguments)
94
+ }
95
+ }
96
+
97
+ /**
98
+ * @param {Function} method
99
+ * @param {AcquireChannels} channels
100
+ * @returns {Function}
101
+ */
102
+ function wrapPoolClusterQueryMethod (method, channels) {
103
+ return function () {
104
+ if (!channels.connectionStartCh.hasSubscribers) return method.apply(this, arguments)
105
+
106
+ const key = arguments[0]
107
+ const acquire = takeClusterAcquire(key) ?? {}
108
+ const result = runWithPoolQueryAcquire(acquire, method, this, arguments)
109
+
110
+ if (isWeakKey(result)) acquire.key = result
111
+ if (!acquire.observesError) {
112
+ const callback = result?._callback
113
+ if (typeof callback === 'function') {
114
+ acquire.observesError = true
115
+ result._callback = wrapClusterQueryCallback(callback, acquire, channels)
116
+ } else if (typeof result?.once === 'function') {
117
+ acquire.observesError = true
118
+ result.once(errorMonitor, error => reportClusterAcquireError(acquire, error, channels))
119
+ }
120
+ }
121
+ return result
122
+ }
123
+ }
124
+
125
+ /**
126
+ * @param {Function} method
127
+ * @param {Channel} connectionStartCh
128
+ * @returns {Function}
129
+ */
130
+ function wrapPoolClusterMethod (method, connectionStartCh) {
131
+ return function () {
132
+ if (!connectionStartCh.hasSubscribers) return method.apply(this, arguments)
133
+ return runWithPoolQueryAcquire({}, method, this, arguments)
134
+ }
135
+ }
136
+
137
+ /**
138
+ * @param {Function} method
139
+ * @param {AcquireChannels} channels
140
+ * @returns {Function}
141
+ */
142
+ function wrapPoolClusterGetConnection (method, channels) {
143
+ return function (callback) {
144
+ if (!channels.connectionStartCh.hasSubscribers) return method.apply(this, arguments)
145
+
146
+ const previous = currentPoolQueryAcquire
147
+ const acquire = isClusterAcquire(previous) && previous.key === undefined
148
+ ? previous
149
+ : takeClusterAcquire(callback)
150
+
151
+ if (acquire === undefined && previous === undefined) return method.apply(this, arguments)
152
+ if (acquire !== undefined) {
153
+ if (acquire.callback === undefined) {
154
+ acquire.callback = wrapClusterAcquireCallback(callback, acquire, channels)
155
+ }
156
+ arguments[0] = acquire.callback
157
+ acquire.key = acquire.callback
158
+ }
159
+
160
+ return runWithPoolQueryAcquire(acquire, method, this, arguments)
161
+ }
162
+ }
163
+
164
+ /**
165
+ * @param {Function} getConnection
166
+ * @param {AcquireChannels} channels
167
+ * @param {boolean} [deferred]
168
+ * @returns {Function}
169
+ */
170
+ function wrapPoolGetConnection (getConnection, channels, deferred) {
171
+ const wrapped = wrapSynchronousPoolGetConnection(getConnection, channels)
172
+ return wrapPoolAcquireCarrier(wrapped, getConnection, channels.connectionStartCh, deferred === true)
173
+ }
174
+
175
+ /**
176
+ * @param {Function} getConnection
177
+ * @param {AcquireChannels} channels
178
+ * @returns {Function}
179
+ */
180
+ function wrapSynchronousPoolGetConnection (getConnection, channels) {
181
+ const {
182
+ connectionStartCh,
183
+ connectionFinishCh,
184
+ acquireStartCh,
185
+ acquireFinishCh,
186
+ } = channels
187
+ const poolWaitTransfer = { deferred: false }
188
+ const queuedCallbacks = channels.reentersQueuedCallbacks ? new WeakSet() : undefined
189
+
190
+ return function (callback) {
191
+ if (!connectionStartCh.hasSubscribers || queuedCallbacks?.has(callback)) {
192
+ return getConnection.apply(this, arguments)
193
+ }
194
+
195
+ const pool = this
196
+ const ctx = {}
197
+ const acquire = currentPoolQueryAcquire
198
+ const acquireCtx = acquire === undefined && acquireStartCh.hasSubscribers
199
+ ? { conf: pool.config.connectionConfig }
200
+ : undefined
201
+ const start = acquireStart(pool, acquire)
202
+
203
+ if (acquireCtx !== undefined) acquireStartCh.publish(acquireCtx)
204
+
205
+ /**
206
+ * @param {unknown} error
207
+ * @param {object|undefined} connection
208
+ * @returns {unknown}
209
+ */
210
+ const wrappedCallback = function (error, connection) {
211
+ if (acquire === undefined) {
212
+ if (!error && connection !== undefined) clearPoolWaitTime(connection)
213
+ if (acquireCtx !== undefined) {
214
+ acquireCtx.error = error
215
+ acquireCtx.poolWaitTime = acquireWait(start)
216
+ acquireFinishCh.publish(acquireCtx)
217
+ }
218
+ return connectionFinishCh.runStores(ctx, callback, this, ...arguments)
219
+ }
220
+
221
+ return runPoolQueryConnectionCallback(
222
+ poolWaitTransfer,
223
+ acquire,
224
+ start,
225
+ error,
226
+ connection,
227
+ pool,
228
+ channels,
229
+ ctx,
230
+ callback,
231
+ this,
232
+ arguments
233
+ )
234
+ }
235
+ if (queuedCallbacks !== undefined) queuedCallbacks.add(wrappedCallback)
236
+ arguments[0] = wrappedCallback
237
+
238
+ connectionStartCh.publish(ctx)
239
+ if (acquire !== undefined) {
240
+ return runWithPoolQueryAcquire(undefined, getConnection, pool, arguments)
241
+ }
242
+ if (acquireCtx !== undefined) {
243
+ return getConnectionForAcquire(getConnection, pool, arguments, acquireCtx, start, acquireFinishCh)
244
+ }
245
+ return getConnection.apply(pool, arguments)
246
+ }
247
+ }
248
+
249
+ /**
250
+ * @param {Function} getConnection
251
+ * @param {object} pool
252
+ * @param {ArgumentsLike} args
253
+ * @param {Record<string, unknown>} acquireCtx
254
+ * @param {number|undefined} start
255
+ * @param {Channel} acquireFinishCh
256
+ * @returns {unknown}
257
+ */
258
+ function getConnectionForAcquire (getConnection, pool, args, acquireCtx, start, acquireFinishCh) {
259
+ try {
260
+ return getConnection.apply(pool, args)
261
+ } catch (error) {
262
+ if (acquireCtx.poolWaitTime === undefined) {
263
+ acquireCtx.error = error
264
+ acquireCtx.poolWaitTime = acquireWait(start)
265
+ acquireFinishCh.publish(acquireCtx)
266
+ }
267
+ throw error
268
+ }
269
+ }
270
+
271
+ /**
272
+ * @returns {boolean}
273
+ */
274
+ function isPoolQueryAcquire () {
275
+ return currentPoolQueryAcquire !== undefined
276
+ }
277
+
278
+ /**
279
+ * @param {Function} method
280
+ * @param {object} receiver
281
+ * @param {ArgumentsLike} args
282
+ * @returns {unknown}
283
+ */
284
+ function runOutsidePoolQueryAcquire (method, receiver, args) {
285
+ return runWithPoolQueryAcquire(undefined, method, receiver, args)
286
+ }
287
+
288
+ /**
289
+ * @param {ClusterAcquire | typeof poolQueryAcquire | undefined} acquire
290
+ * @param {Function} method
291
+ * @param {unknown} receiver
292
+ * @param {ArgumentsLike} args
293
+ * @returns {unknown}
294
+ */
295
+ function runWithPoolQueryAcquire (acquire, method, receiver, args) {
296
+ const previous = currentPoolQueryAcquire
297
+ currentPoolQueryAcquire = acquire
298
+ try {
299
+ return method.apply(receiver, args)
300
+ } finally {
301
+ currentPoolQueryAcquire = previous
302
+ }
303
+ }
304
+
305
+ /**
306
+ * @param {object} pool
307
+ * @returns {boolean}
308
+ */
309
+ function takeDeferredPoolQueryAcquire (pool) {
310
+ const acquire = deferredPoolQueryAcquireStorage?.getStore()
311
+ if (acquire === undefined || acquire.pool !== pool || !acquire.pending) return false
312
+
313
+ acquire.pending = false
314
+ return true
315
+ }
316
+
317
+ /**
318
+ * @returns {import('node:async_hooks').AsyncLocalStorage<DeferredPoolQueryAcquire>}
319
+ */
320
+ function getDeferredPoolQueryAcquireStorage () {
321
+ if (deferredPoolQueryAcquireStorage === undefined) {
322
+ const { AsyncLocalStorage } = require('node:async_hooks')
323
+ deferredPoolQueryAcquireStorage = new AsyncLocalStorage()
324
+ }
325
+ return deferredPoolQueryAcquireStorage
326
+ }
327
+
328
+ /**
329
+ * @param {Function} method
330
+ * @param {Record<string, unknown>} receiver
331
+ * @param {string} acquireMethod
332
+ * @param {unknown[]} args
333
+ * @returns {boolean}
334
+ */
335
+ function dispatchesAcquireSynchronously (method, receiver, acquireMethod, args) {
336
+ let dispatched = false
337
+ // Prevent an async probe from executing beyond its fake acquisition.
338
+ // eslint-disable-next-line unicorn/no-thenable
339
+ const pending = { then () {} }
340
+
341
+ try {
342
+ if (method.constructor.name === 'AsyncFunction') return false
343
+
344
+ receiver[acquireMethod] = () => {
345
+ dispatched = true
346
+ return pending
347
+ }
348
+ method.apply(receiver, args)
349
+ } catch {
350
+ return false
351
+ }
352
+
353
+ return dispatched
354
+ }
355
+
356
+ /**
357
+ * @param {Pool} pool
358
+ * @param {ClusterAcquire | typeof poolQueryAcquire} [acquire]
359
+ * @returns {number|undefined}
360
+ */
361
+ function acquireStart (pool, acquire) {
362
+ if (isClusterAcquire(acquire) && acquire.start !== undefined) return acquire.start
363
+ if (pool._freeConnections?.length > 0) return
364
+
365
+ const start = performance.now()
366
+ if (isClusterAcquire(acquire)) acquire.start = start
367
+ return start
368
+ }
369
+
370
+ /**
371
+ * @param {number|undefined} start
372
+ * @returns {number}
373
+ */
374
+ function acquireWait (start) {
375
+ return start === undefined ? 0 : performance.now() - start
376
+ }
377
+
378
+ /**
379
+ * @param {object} connection
380
+ * @returns {number|undefined}
381
+ */
382
+ function takePoolWaitTime (connection) {
383
+ for (let i = poolWaitConnections.length - 1; i >= 0; i--) {
384
+ if (poolWaitConnections[i] === connection) {
385
+ poolWaitConnections[i] = undefined
386
+ return poolWaitTimes[i]
387
+ }
388
+ }
389
+
390
+ if (deferredPoolWaitCount !== 0) {
391
+ const candidate = deferredPoolWaitTimes.get(connection)
392
+ if (candidate !== undefined) {
393
+ deferredPoolWaitTimes.delete(connection)
394
+ deferredPoolWaitCount--
395
+ candidate.transfer.deferred = true
396
+ return candidate.waitTime
397
+ }
398
+ }
399
+ }
400
+
401
+ /**
402
+ * @param {PoolWaitTransfer} transfer
403
+ * @param {object} connection
404
+ * @param {number} waitTime
405
+ * @param {Channel} channel
406
+ * @param {object} ctx
407
+ * @param {Function} callback
408
+ * @param {unknown} thisArg
409
+ * @param {ArgumentsLike} args
410
+ * @returns {unknown}
411
+ */
412
+ function runWithPoolWait (transfer, connection, waitTime, channel, ctx, callback, thisArg, args) {
413
+ clearPoolWaitTime(connection)
414
+
415
+ if (transfer.deferred) {
416
+ deferPoolWaitTime(transfer, connection, waitTime)
417
+ return channel.runStores(ctx, callback, thisArg, ...args)
418
+ }
419
+
420
+ const index = poolWaitConnections.length
421
+ poolWaitConnections.push(connection)
422
+ poolWaitTimes.push(waitTime)
423
+ try {
424
+ return channel.runStores(ctx, callback, thisArg, ...args)
425
+ } finally {
426
+ if (poolWaitConnections[index] !== undefined) deferPoolWaitTime(transfer, connection, waitTime)
427
+ poolWaitConnections.pop()
428
+ poolWaitTimes.pop()
429
+ }
430
+ }
431
+
432
+ /**
433
+ * @param {object} connection
434
+ */
435
+ function clearPoolWaitTime (connection) {
436
+ if (deferredPoolWaitCount !== 0 && deferredPoolWaitTimes.delete(connection)) deferredPoolWaitCount--
437
+ }
438
+
439
+ /**
440
+ * @param {PoolWaitTransfer} transfer
441
+ * @param {object} connection
442
+ * @param {number} waitTime
443
+ */
444
+ function deferPoolWaitTime (transfer, connection, waitTime) {
445
+ if (!deferredPoolWaitTimes.has(connection)) deferredPoolWaitCount++
446
+ deferredPoolWaitTimes.set(connection, { transfer, waitTime })
447
+ }
448
+
449
+ /**
450
+ * @param {PoolWaitTransfer} poolWaitTransfer
451
+ * @param {ClusterAcquire | typeof poolQueryAcquire} acquire
452
+ * @param {number|undefined} start
453
+ * @param {unknown} error
454
+ * @param {object|undefined} connection
455
+ * @param {{ config: { connectionConfig: Record<string, unknown> } }} pool
456
+ * @param {AcquireChannels} channels
457
+ * @param {object} ctx
458
+ * @param {Function} callback
459
+ * @param {unknown} thisArg
460
+ * @param {ArgumentsLike} args
461
+ * @returns {unknown}
462
+ */
463
+ function runPoolQueryConnectionCallback (
464
+ poolWaitTransfer,
465
+ acquire,
466
+ start,
467
+ error,
468
+ connection,
469
+ pool,
470
+ channels,
471
+ ctx,
472
+ callback,
473
+ thisArg,
474
+ args
475
+ ) {
476
+ if (error || connection === undefined) {
477
+ const conf = pool.config.connectionConfig
478
+ if (error && isClusterAcquire(acquire)) {
479
+ acquire.conf = conf
480
+ if (acquire.key !== undefined) deferredClusterAcquires.set(acquire.key, acquire)
481
+ return channels.connectionFinishCh.runStores(ctx, callback, thisArg, ...args)
482
+ }
483
+ if (error && channels.acquireStartCh.hasSubscribers) {
484
+ return runPoolAcquireError(
485
+ start,
486
+ error,
487
+ { conf },
488
+ channels,
489
+ ctx,
490
+ callback,
491
+ thisArg,
492
+ args
493
+ )
494
+ }
495
+ return channels.connectionFinishCh.runStores(ctx, callback, thisArg, ...args)
496
+ }
497
+
498
+ if (isClusterAcquire(acquire)) {
499
+ if (acquire.key !== undefined) deferredClusterAcquires.delete(acquire.key)
500
+ acquire.acquired = true
501
+ acquire.key = undefined
502
+ }
503
+
504
+ return runWithPoolWait(
505
+ poolWaitTransfer,
506
+ connection,
507
+ acquireWait(start),
508
+ channels.connectionFinishCh,
509
+ ctx,
510
+ callback,
511
+ thisArg,
512
+ args
513
+ )
514
+ }
515
+
516
+ /**
517
+ * @param {number|undefined} start
518
+ * @param {unknown} error
519
+ * @param {Record<string, unknown>} acquireCtx
520
+ * @param {AcquireErrorChannels} channels
521
+ */
522
+ function reportPoolAcquireError (start, error, acquireCtx, channels) {
523
+ acquireCtx.error = error
524
+ acquireCtx.poolWaitTime = acquireWait(start)
525
+ if (start !== undefined) acquireCtx.startTime = performance.timeOrigin + start
526
+ channels.acquireStartCh.publish(acquireCtx)
527
+ channels.acquireFinishCh.publish(acquireCtx)
528
+ }
529
+
530
+ /**
531
+ * @param {number|undefined} start
532
+ * @param {unknown} error
533
+ * @param {Record<string, unknown>} acquireCtx
534
+ * @param {AcquireErrorChannels} channels
535
+ * @param {object} connectionCtx
536
+ * @param {Function} callback
537
+ * @param {unknown} thisArg
538
+ * @param {ArgumentsLike} args
539
+ * @returns {unknown}
540
+ */
541
+ function runPoolAcquireError (start, error, acquireCtx, channels, connectionCtx, callback, thisArg, args) {
542
+ return channels.connectionFinishCh.runStores(connectionCtx, () => {
543
+ reportPoolAcquireError(start, error, acquireCtx, channels)
544
+ return callback.apply(thisArg, args)
545
+ })
546
+ }
547
+
548
+ /**
549
+ * @param {Function} callback
550
+ * @param {ClusterAcquire} acquire
551
+ * @param {AcquireChannels} channels
552
+ * @returns {Function}
553
+ */
554
+ function wrapClusterAcquireCallback (callback, acquire, channels) {
555
+ return function (error) {
556
+ if (error) reportClusterAcquireError(acquire, error, channels)
557
+ if (currentPoolQueryAcquire !== undefined) {
558
+ return runWithPoolQueryAcquire(undefined, callback, this, arguments)
559
+ }
560
+ return callback.apply(this, arguments)
561
+ }
562
+ }
563
+
564
+ /**
565
+ * @param {Function} callback
566
+ * @param {ClusterAcquire} acquire
567
+ * @param {AcquireChannels} channels
568
+ * @returns {Function}
569
+ */
570
+ function wrapClusterQueryCallback (callback, acquire, channels) {
571
+ return function (error) {
572
+ if (error) reportClusterAcquireError(acquire, error, channels)
573
+ return callback.apply(this, arguments)
574
+ }
575
+ }
576
+
577
+ /**
578
+ * @param {ClusterAcquire} acquire
579
+ * @param {unknown} error
580
+ * @param {AcquireChannels} channels
581
+ */
582
+ function reportClusterAcquireError (acquire, error, channels) {
583
+ if (acquire.acquired || acquire.errorReported || !channels.acquireStartCh.hasSubscribers) return
584
+ acquire.errorReported = true
585
+ reportPoolAcquireError(acquire.start, error, { conf: acquire.conf ?? {} }, channels)
586
+ }
587
+
588
+ /**
589
+ * @param {unknown} value
590
+ * @returns {value is ClusterAcquire}
591
+ */
592
+ function isClusterAcquire (value) {
593
+ return value !== undefined && value !== poolQueryAcquire
594
+ }
595
+
596
+ /**
597
+ * @param {unknown} value
598
+ * @returns {value is object}
599
+ */
600
+ function isWeakKey (value) {
601
+ return (typeof value === 'object' && value !== null) || typeof value === 'function'
602
+ }
603
+
604
+ /**
605
+ * @param {unknown} key
606
+ * @returns {ClusterAcquire|undefined}
607
+ */
608
+ function takeClusterAcquire (key) {
609
+ if (!isWeakKey(key)) return
610
+ const acquire = deferredClusterAcquires.get(key)
611
+ if (acquire !== undefined) deferredClusterAcquires.delete(key)
612
+ return acquire
613
+ }
614
+
615
+ module.exports = {
616
+ clearPoolWaitTime,
617
+ dispatchesAcquireSynchronously,
618
+ isPoolQueryAcquire,
619
+ runOutsidePoolQueryAcquire,
620
+ runPoolAcquireError,
621
+ runWithPoolWait,
622
+ takePoolWaitTime,
623
+ wrapPoolAcquireCarrier,
624
+ wrapPoolClusterGetConnection,
625
+ wrapPoolClusterMethod,
626
+ wrapPoolClusterQueryMethod,
627
+ wrapPoolGetConnection,
628
+ wrapPoolQueryMethod,
629
+ }
@@ -7,7 +7,7 @@ const log = require('../../../../dd-trace/src/log')
7
7
  const { create } = require('../../../../../vendor/dist/@apm-js-collab/code-transformer')
8
8
  const instrumentations = require('./instrumentations')
9
9
  const { getRewriteTarget } = require('./targets')
10
- const { waitForAsyncEnd } = require('./transforms')
10
+ const { awaitContextCallback, waitForAsyncEnd } = require('./transforms')
11
11
 
12
12
  // `dc-polyfill` is referenced from injected `require()` (CJS) and `import`
13
13
  // (ESM) statements that the transformer splices into the rewritten module.
@@ -35,6 +35,7 @@ const matcherCjs = create(instrumentations, dcPolyfillCjs)
35
35
  const matcherEsm = create(instrumentations, dcPolyfillEsm)
36
36
 
37
37
  for (const matcher of [matcherCjs, matcherEsm]) {
38
+ matcher.addTransform('awaitContextCallback', awaitContextCallback)
38
39
  matcher.addTransform('waitForAsyncEnd', waitForAsyncEnd)
39
40
  }
40
41