dd-trace 6.9.0 → 6.11.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 (175) hide show
  1. package/README.md +0 -17
  2. package/ci/vitest-no-worker-init-setup.mjs +112 -10
  3. package/index.d.ts +150 -3
  4. package/initialize.mjs +28 -17
  5. package/openfeature.js +2 -2
  6. package/package.json +14 -10
  7. package/packages/datadog-esbuild/index.js +0 -34
  8. package/packages/datadog-instrumentations/src/anthropic.js +210 -15
  9. package/packages/datadog-instrumentations/src/aws-sdk.js +9 -1
  10. package/packages/datadog-instrumentations/src/browser-bunyan.js +11 -0
  11. package/packages/datadog-instrumentations/src/bunyan.js +3 -16
  12. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +111 -6
  13. package/packages/datadog-instrumentations/src/cucumber.js +26 -11
  14. package/packages/datadog-instrumentations/src/cypress-config.js +182 -16
  15. package/packages/datadog-instrumentations/src/cypress-legacy-finalizers.js +30 -0
  16. package/packages/datadog-instrumentations/src/cypress.js +2 -0
  17. package/packages/datadog-instrumentations/src/fastify.js +2 -0
  18. package/packages/datadog-instrumentations/src/helpers/bunyan.js +22 -0
  19. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -1
  20. package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +634 -0
  21. package/packages/datadog-instrumentations/src/helpers/register.js +10 -8
  22. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -1
  23. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +81 -0
  24. package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +1 -0
  25. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +83 -1
  26. package/packages/datadog-instrumentations/src/jest.js +26 -18
  27. package/packages/datadog-instrumentations/src/mariadb.js +278 -21
  28. package/packages/datadog-instrumentations/src/mocha/main.js +540 -56
  29. package/packages/datadog-instrumentations/src/mocha/utils.js +132 -25
  30. package/packages/datadog-instrumentations/src/mysql.js +45 -15
  31. package/packages/datadog-instrumentations/src/mysql2.js +119 -18
  32. package/packages/datadog-instrumentations/src/path-to-regexp.js +67 -1
  33. package/packages/datadog-instrumentations/src/pg.js +116 -92
  34. package/packages/datadog-instrumentations/src/playwright-reporter.js +99 -0
  35. package/packages/datadog-instrumentations/src/playwright.js +149 -2
  36. package/packages/datadog-instrumentations/src/router.js +2 -0
  37. package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +43 -4
  38. package/packages/datadog-instrumentations/src/vitest-main.js +180 -20
  39. package/packages/datadog-instrumentations/src/vitest-util.js +64 -5
  40. package/packages/datadog-instrumentations/src/vitest-worker.js +150 -25
  41. package/packages/datadog-instrumentations/src/webdriverio.js +31 -17
  42. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +12 -6
  43. package/packages/datadog-plugin-aws-sdk/src/base.js +1 -0
  44. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +163 -44
  45. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -13
  46. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -5
  47. package/packages/datadog-plugin-azure-functions/src/index.js +1 -1
  48. package/packages/datadog-plugin-browser-bunyan/src/index.js +9 -0
  49. package/packages/datadog-plugin-bunyan/src/index.js +5 -8
  50. package/packages/datadog-plugin-cucumber/src/index.js +11 -0
  51. package/packages/datadog-plugin-cypress/src/after-run.js +5 -1
  52. package/packages/datadog-plugin-cypress/src/after-spec.js +5 -1
  53. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +82 -30
  54. package/packages/datadog-plugin-cypress/src/finalization.js +76 -0
  55. package/packages/datadog-plugin-cypress/src/index.js +12 -6
  56. package/packages/datadog-plugin-cypress/src/plugin.js +16 -3
  57. package/packages/datadog-plugin-dd-trace-api/src/index.js +4 -0
  58. package/packages/datadog-plugin-electron/src/index.js +2 -0
  59. package/packages/datadog-plugin-fs/src/index.js +1 -1
  60. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +31 -17
  61. package/packages/datadog-plugin-jest/src/index.js +11 -4
  62. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -3
  63. package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -3
  64. package/packages/datadog-plugin-kafkajs/src/producer.js +3 -2
  65. package/packages/datadog-plugin-kafkajs/src/utils.js +65 -7
  66. package/packages/datadog-plugin-mocha/src/index.js +606 -40
  67. package/packages/datadog-plugin-mysql/src/index.js +37 -0
  68. package/packages/datadog-plugin-nats/src/index.js +1 -1
  69. package/packages/datadog-plugin-next/src/index.js +1 -19
  70. package/packages/datadog-plugin-openai/src/tracing.js +41 -30
  71. package/packages/datadog-plugin-openai-agents/src/integration.js +279 -69
  72. package/packages/datadog-plugin-openai-agents/src/processor.js +16 -4
  73. package/packages/datadog-plugin-pg/src/index.js +1 -0
  74. package/packages/datadog-plugin-playwright/src/index.js +42 -13
  75. package/packages/datadog-plugin-vitest/src/index.js +14 -20
  76. package/packages/datadog-plugin-ws/src/util.js +2 -1
  77. package/packages/datadog-webpack/index.js +0 -11
  78. package/packages/dd-trace/index.js +0 -1
  79. package/packages/dd-trace/src/agent/info.js +6 -5
  80. package/packages/dd-trace/src/aiguard/client.js +100 -1
  81. package/packages/dd-trace/src/aiguard/errors.js +41 -0
  82. package/packages/dd-trace/src/aiguard/evaluation.js +357 -0
  83. package/packages/dd-trace/src/aiguard/integrations/anthropic.js +70 -0
  84. package/packages/dd-trace/src/aiguard/integrations/index.js +4 -0
  85. package/packages/dd-trace/src/aiguard/messages/anthropic.js +423 -0
  86. package/packages/dd-trace/src/aiguard/messages/openai.js +1 -24
  87. package/packages/dd-trace/src/aiguard/messages/utils.js +28 -0
  88. package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +1 -11
  89. package/packages/dd-trace/src/aiguard/sdk.js +22 -278
  90. package/packages/dd-trace/src/appsec/api_security/normalized-route.js +453 -0
  91. package/packages/dd-trace/src/appsec/handlers/http-request.js +13 -0
  92. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +9 -12
  93. package/packages/dd-trace/src/carrier.js +356 -0
  94. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +1 -0
  95. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +27 -3
  96. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +22 -6
  97. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +21 -5
  98. package/packages/dd-trace/src/ci-visibility/exporters/agentless/request-tracker.js +164 -0
  99. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +22 -6
  100. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +365 -32
  101. package/packages/dd-trace/src/ci-visibility/exporters/request.js +201 -0
  102. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +5 -3
  103. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +9 -5
  104. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -1
  105. package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +39 -0
  106. package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -6
  107. package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +6 -2
  108. package/packages/dd-trace/src/config/generated-config-types.d.ts +7 -0
  109. package/packages/dd-trace/src/config/index.js +13 -2
  110. package/packages/dd-trace/src/config/major-overrides.js +7 -0
  111. package/packages/dd-trace/src/config/supported-configurations.json +24 -0
  112. package/packages/dd-trace/src/datastreams/context.js +6 -1
  113. package/packages/dd-trace/src/datastreams/index.js +2 -0
  114. package/packages/dd-trace/src/datastreams/manager.js +14 -3
  115. package/packages/dd-trace/src/datastreams/pathway.js +23 -22
  116. package/packages/dd-trace/src/datastreams/processor.js +16 -13
  117. package/packages/dd-trace/src/datastreams/size.js +5 -0
  118. package/packages/dd-trace/src/debugger/devtools_client/index.js +3 -2
  119. package/packages/dd-trace/src/exporters/agent/writer.js +49 -9
  120. package/packages/dd-trace/src/exporters/common/buffering-exporter.js +6 -4
  121. package/packages/dd-trace/src/exporters/common/writer.js +11 -6
  122. package/packages/dd-trace/src/llmobs/constants/tags.js +5 -0
  123. package/packages/dd-trace/src/llmobs/experiments/client.js +163 -5
  124. package/packages/dd-trace/src/llmobs/experiments/dataset.js +241 -87
  125. package/packages/dd-trace/src/llmobs/experiments/experiment.js +280 -20
  126. package/packages/dd-trace/src/llmobs/experiments/index.js +58 -59
  127. package/packages/dd-trace/src/llmobs/experiments/noop.js +71 -3
  128. package/packages/dd-trace/src/llmobs/experiments/result.js +1 -0
  129. package/packages/dd-trace/src/llmobs/experiments/util.js +41 -5
  130. package/packages/dd-trace/src/llmobs/index.js +34 -2
  131. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +12 -3
  132. package/packages/dd-trace/src/llmobs/plugins/base.js +4 -2
  133. package/packages/dd-trace/src/llmobs/span_processor.js +16 -0
  134. package/packages/dd-trace/src/llmobs/tagger.js +96 -0
  135. package/packages/dd-trace/src/llmobs/util.js +78 -0
  136. package/packages/dd-trace/src/noop/proxy.js +3 -4
  137. package/packages/dd-trace/src/openfeature/flagging_provider.js +18 -2
  138. package/packages/dd-trace/src/openfeature/remote_config.js +1 -1
  139. package/packages/dd-trace/src/opentelemetry/context_manager.js +7 -7
  140. package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +2 -1
  141. package/packages/dd-trace/src/opentelemetry/logs/logger.js +67 -11
  142. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +14 -3
  143. package/packages/dd-trace/src/opentelemetry/metrics/index.js +25 -12
  144. package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +2 -5
  145. package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +96 -43
  146. package/packages/dd-trace/src/opentracing/propagation/text_map.js +126 -120
  147. package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +4 -8
  148. package/packages/dd-trace/src/opentracing/tracer.js +5 -2
  149. package/packages/dd-trace/src/otel-thread-ctx.js +387 -0
  150. package/packages/dd-trace/src/plugin_manager.js +5 -3
  151. package/packages/dd-trace/src/plugins/ci_plugin.js +6 -1
  152. package/packages/dd-trace/src/plugins/index.js +1 -0
  153. package/packages/{datadog-plugin-jest/src/util.js → dd-trace/src/plugins/util/jest.js} +5 -65
  154. package/packages/dd-trace/src/plugins/util/test.js +93 -14
  155. package/packages/dd-trace/src/plugins/util/web.js +56 -2
  156. package/packages/dd-trace/src/profiling/profiler.js +1 -1
  157. package/packages/dd-trace/src/profiling/profilers/space.js +1 -3
  158. package/packages/dd-trace/src/profiling/profilers/wall.js +37 -90
  159. package/packages/dd-trace/src/profiling/webspan-utils.js +45 -0
  160. package/packages/dd-trace/src/proxy.js +38 -29
  161. package/packages/dd-trace/src/ritm.js +9 -2
  162. package/packages/dd-trace/src/serverless.js +37 -0
  163. package/packages/dd-trace/src/span_format.js +1 -0
  164. package/packages/dd-trace/src/span_stats.js +30 -3
  165. package/packages/dd-trace/src/storage-channels.js +86 -0
  166. package/packages/dd-trace/src/tracer.js +9 -2
  167. package/packages/dd-trace/src/tracer_metadata.js +14 -1
  168. package/packages/dd-trace/src/web-tags-cache.js +132 -0
  169. package/vendor/dist/@datadog/openfeature-node-server/LICENSE +201 -0
  170. package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -0
  171. package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +0 -65
  172. package/packages/datadog-webpack/src/optional-peer-loader.js +0 -17
  173. package/packages/dd-trace/src/feature-registry.js +0 -29
  174. package/packages/dd-trace/src/openfeature/register.js +0 -35
  175. package/packages/dd-trace/src/openfeature/require-provider.js +0 -18
@@ -0,0 +1,634 @@
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
+ * @param {number} [poolWaitTime]
522
+ */
523
+ function reportPoolAcquireError (start, error, acquireCtx, channels, poolWaitTime) {
524
+ acquireCtx.error = error
525
+ acquireCtx.poolWaitTime = poolWaitTime ?? acquireWait(start)
526
+ if (start !== undefined) acquireCtx.startTime = performance.timeOrigin + start
527
+ channels.acquireStartCh.publish(acquireCtx)
528
+ channels.acquireFinishCh.publish(acquireCtx)
529
+ }
530
+
531
+ /**
532
+ * @param {number|undefined} start
533
+ * @param {unknown} error
534
+ * @param {Record<string, unknown>} acquireCtx
535
+ * @param {AcquireErrorChannels} channels
536
+ * @param {object} connectionCtx
537
+ * @param {Function} callback
538
+ * @param {unknown} thisArg
539
+ * @param {ArgumentsLike} args
540
+ * @param {number} [poolWaitTime]
541
+ * @returns {unknown}
542
+ */
543
+ function runPoolAcquireError (
544
+ start, error, acquireCtx, channels, connectionCtx, callback, thisArg, args, poolWaitTime
545
+ ) {
546
+ return channels.connectionFinishCh.runStores(connectionCtx, () => {
547
+ reportPoolAcquireError(start, error, acquireCtx, channels, poolWaitTime)
548
+ return callback.apply(thisArg, args)
549
+ })
550
+ }
551
+
552
+ /**
553
+ * @param {Function} callback
554
+ * @param {ClusterAcquire} acquire
555
+ * @param {AcquireChannels} channels
556
+ * @returns {Function}
557
+ */
558
+ function wrapClusterAcquireCallback (callback, acquire, channels) {
559
+ return function (error) {
560
+ if (error) reportClusterAcquireError(acquire, error, channels)
561
+ if (currentPoolQueryAcquire !== undefined) {
562
+ return runWithPoolQueryAcquire(undefined, callback, this, arguments)
563
+ }
564
+ return callback.apply(this, arguments)
565
+ }
566
+ }
567
+
568
+ /**
569
+ * @param {Function} callback
570
+ * @param {ClusterAcquire} acquire
571
+ * @param {AcquireChannels} channels
572
+ * @returns {Function}
573
+ */
574
+ function wrapClusterQueryCallback (callback, acquire, channels) {
575
+ return function (error) {
576
+ if (error) reportClusterAcquireError(acquire, error, channels)
577
+ return callback.apply(this, arguments)
578
+ }
579
+ }
580
+
581
+ /**
582
+ * @param {ClusterAcquire} acquire
583
+ * @param {unknown} error
584
+ * @param {AcquireChannels} channels
585
+ */
586
+ function reportClusterAcquireError (acquire, error, channels) {
587
+ if (acquire.acquired || acquire.errorReported || !channels.acquireStartCh.hasSubscribers) return
588
+ acquire.errorReported = true
589
+ reportPoolAcquireError(acquire.start, error, { conf: acquire.conf ?? {} }, channels)
590
+ }
591
+
592
+ /**
593
+ * @param {unknown} value
594
+ * @returns {value is ClusterAcquire}
595
+ */
596
+ function isClusterAcquire (value) {
597
+ return value !== undefined && value !== poolQueryAcquire
598
+ }
599
+
600
+ /**
601
+ * @param {unknown} value
602
+ * @returns {value is object}
603
+ */
604
+ function isWeakKey (value) {
605
+ return (typeof value === 'object' && value !== null) || typeof value === 'function'
606
+ }
607
+
608
+ /**
609
+ * @param {unknown} key
610
+ * @returns {ClusterAcquire|undefined}
611
+ */
612
+ function takeClusterAcquire (key) {
613
+ if (!isWeakKey(key)) return
614
+ const acquire = deferredClusterAcquires.get(key)
615
+ if (acquire !== undefined) deferredClusterAcquires.delete(key)
616
+ return acquire
617
+ }
618
+
619
+ module.exports = {
620
+ acquireWait,
621
+ clearPoolWaitTime,
622
+ dispatchesAcquireSynchronously,
623
+ isPoolQueryAcquire,
624
+ runOutsidePoolQueryAcquire,
625
+ runPoolAcquireError,
626
+ runWithPoolWait,
627
+ takePoolWaitTime,
628
+ wrapPoolAcquireCarrier,
629
+ wrapPoolClusterGetConnection,
630
+ wrapPoolClusterMethod,
631
+ wrapPoolClusterQueryMethod,
632
+ wrapPoolGetConnection,
633
+ wrapPoolQueryMethod,
634
+ }
@@ -112,14 +112,6 @@ for (const name of names) {
112
112
  }
113
113
 
114
114
  for (const { file, versions, hook, filePattern, patchDefault } of instrumentations[name]) {
115
- if (isIitm && patchDefault === !!moduleExports.default) {
116
- if (patchDefault) {
117
- moduleExports = moduleExports.default
118
- } else {
119
- return moduleExports
120
- }
121
- }
122
-
123
115
  const fullFilename = filename(name, file)
124
116
 
125
117
  let matchesFile = moduleName === fullFilename
@@ -134,6 +126,16 @@ for (const name of names) {
134
126
  }
135
127
 
136
128
  if (matchesFile && matchVersion(moduleVersion, versions)) {
129
+ // IITM invokes this callback for every module in the package. Only unwrap the namespace after its file and
130
+ // version match, otherwise a default export from an unrelated internal module can replace that module.
131
+ if (isIitm && patchDefault === !!moduleExports.default) {
132
+ if (patchDefault) {
133
+ moduleExports = moduleExports.default
134
+ } else {
135
+ return moduleExports
136
+ }
137
+ }
138
+
137
139
  // Do not log in case of an error to prevent duplicate telemetry for the same integration version.
138
140
  instrumentedIntegrationsSuccess.set(`${name}@${moduleVersion}`, true)
139
141
  try {
@@ -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