dd-trace 6.8.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 (209) hide show
  1. package/ci/diagnose.js +27 -25
  2. package/ci/init.js +6 -6
  3. package/ci/runbook.md +114 -20
  4. package/ci/test-optimization-validation/approval-artifacts.js +36 -3
  5. package/ci/test-optimization-validation/approval.js +78 -22
  6. package/ci/test-optimization-validation/blocker-category.js +24 -0
  7. package/ci/test-optimization-validation/ci-discovery.js +23 -17
  8. package/ci/test-optimization-validation/ci-package-scripts.js +34 -6
  9. package/ci/test-optimization-validation/ci-remediation.js +1 -1
  10. package/ci/test-optimization-validation/cli.js +280 -52
  11. package/ci/test-optimization-validation/command-blocker.js +159 -20
  12. package/ci/test-optimization-validation/command-output-policy.js +9 -3
  13. package/ci/test-optimization-validation/command-runner.js +9 -7
  14. package/ci/test-optimization-validation/environment.js +4 -2
  15. package/ci/test-optimization-validation/executable.js +15 -13
  16. package/ci/test-optimization-validation/execution-lock.js +70 -0
  17. package/ci/test-optimization-validation/framework-adapters/cucumber-validation.json +3 -0
  18. package/ci/test-optimization-validation/framework-adapters/cucumber.js +657 -5
  19. package/ci/test-optimization-validation/framework-adapters/vitest.js +517 -0
  20. package/ci/test-optimization-validation/generated-files.js +38 -28
  21. package/ci/test-optimization-validation/generated-test-contract.js +8 -4
  22. package/ci/test-optimization-validation/generated-verifier.js +24 -17
  23. package/ci/test-optimization-validation/literal-glob.js +52 -0
  24. package/ci/test-optimization-validation/manifest-loader.js +3 -0
  25. package/ci/test-optimization-validation/manifest-scaffold.js +300 -50
  26. package/ci/test-optimization-validation/manifest-schema.js +80 -17
  27. package/ci/test-optimization-validation/offline-fixtures.js +13 -4
  28. package/ci/test-optimization-validation/package-check.js +94 -0
  29. package/ci/test-optimization-validation/plan-writer.js +183 -10
  30. package/ci/test-optimization-validation/preflight-runner.js +110 -31
  31. package/ci/test-optimization-validation/project-build-artifact.js +31 -0
  32. package/ci/test-optimization-validation/redaction.js +18 -27
  33. package/ci/test-optimization-validation/report-writer.js +182 -48
  34. package/ci/test-optimization-validation/result-semantics.js +20 -3
  35. package/ci/test-optimization-validation/runner-command.js +40 -20
  36. package/ci/test-optimization-validation/runner-contract.js +79 -43
  37. package/ci/test-optimization-validation/scenarios/basic-reporting.js +59 -5
  38. package/ci/test-optimization-validation/scenarios/ci-wiring.js +141 -35
  39. package/ci/test-optimization-validation/scenarios/helpers.js +30 -6
  40. package/ci/test-optimization-validation/static-diagnosis.js +10 -3
  41. package/ci/test-optimization-validation/test-output.js +2 -1
  42. package/ci/test-optimization-validation/validation-blocker.js +21 -0
  43. package/ci/vitest-no-worker-init-setup.mjs +140 -42
  44. package/index.d.ts +140 -1
  45. package/init.js +1 -17
  46. package/initialize.mjs +11 -0
  47. package/loader-hook.mjs +6 -4
  48. package/package.json +8 -5
  49. package/packages/datadog-core/src/utils/src/parse-tags.js +0 -1
  50. package/packages/datadog-esbuild/src/utils.js +16 -1
  51. package/packages/datadog-instrumentations/src/ai.js +61 -34
  52. package/packages/datadog-instrumentations/src/bluebird.js +6 -6
  53. package/packages/datadog-instrumentations/src/claude-agent-sdk.js +81 -5
  54. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +111 -6
  55. package/packages/datadog-instrumentations/src/cucumber.js +124 -47
  56. package/packages/datadog-instrumentations/src/dns.js +21 -2
  57. package/packages/datadog-instrumentations/src/electron.js +1 -0
  58. package/packages/datadog-instrumentations/src/fastify.js +3 -1
  59. package/packages/datadog-instrumentations/src/grpc/client.js +4 -2
  60. package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +3 -1
  61. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
  62. package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +629 -0
  63. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +34 -9
  64. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +199 -0
  65. package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +20 -2
  66. package/packages/datadog-instrumentations/src/helpers/rewriter/targets.js +32 -0
  67. package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +62 -0
  68. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +83 -1
  69. package/packages/datadog-instrumentations/src/helpers/router-helper.js +37 -6
  70. package/packages/datadog-instrumentations/src/jest/coverage-backfill.js +1 -1
  71. package/packages/datadog-instrumentations/src/jest.js +980 -234
  72. package/packages/datadog-instrumentations/src/mocha/main.js +108 -10
  73. package/packages/datadog-instrumentations/src/mocha/utils.js +66 -50
  74. package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +25 -0
  75. package/packages/datadog-instrumentations/src/mocha/worker.js +12 -18
  76. package/packages/datadog-instrumentations/src/mysql.js +46 -16
  77. package/packages/datadog-instrumentations/src/mysql2.js +119 -18
  78. package/packages/datadog-instrumentations/src/next.js +155 -23
  79. package/packages/datadog-instrumentations/src/openai.js +14 -0
  80. package/packages/datadog-instrumentations/src/path-to-regexp.js +67 -1
  81. package/packages/datadog-instrumentations/src/pg.js +209 -11
  82. package/packages/datadog-instrumentations/src/playwright.js +173 -79
  83. package/packages/datadog-instrumentations/src/promise-js.js +4 -4
  84. package/packages/datadog-instrumentations/src/promise.js +3 -3
  85. package/packages/datadog-instrumentations/src/router.js +195 -19
  86. package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +85 -13
  87. package/packages/datadog-instrumentations/src/vitest-main.js +528 -72
  88. package/packages/datadog-instrumentations/src/vitest-util.js +106 -12
  89. package/packages/datadog-instrumentations/src/vitest-worker.js +382 -40
  90. package/packages/datadog-instrumentations/src/webdriverio.js +212 -22
  91. package/packages/datadog-instrumentations/src/when.js +3 -3
  92. package/packages/datadog-instrumentations/src/ws.js +5 -1
  93. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +12 -6
  94. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +59 -48
  95. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -5
  96. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -5
  97. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +1 -3
  98. package/packages/datadog-plugin-cucumber/src/index.js +5 -1
  99. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +51 -47
  100. package/packages/datadog-plugin-cypress/src/support.js +7 -4
  101. package/packages/datadog-plugin-electron/src/net.js +10 -4
  102. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +31 -17
  103. package/packages/datadog-plugin-http/src/client.js +1 -1
  104. package/packages/datadog-plugin-http2/src/client.js +1 -1
  105. package/packages/datadog-plugin-jest/src/index.js +6 -22
  106. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -3
  107. package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -3
  108. package/packages/datadog-plugin-kafkajs/src/producer.js +5 -3
  109. package/packages/datadog-plugin-kafkajs/src/utils.js +65 -7
  110. package/packages/datadog-plugin-mocha/src/index.js +832 -4
  111. package/packages/datadog-plugin-mysql/src/index.js +37 -0
  112. package/packages/datadog-plugin-next/src/index.js +51 -21
  113. package/packages/datadog-plugin-openai/src/tracing.js +4 -0
  114. package/packages/datadog-plugin-openai-agents/src/integration.js +278 -69
  115. package/packages/datadog-plugin-openai-agents/src/processor.js +16 -4
  116. package/packages/datadog-plugin-pg/src/index.js +66 -1
  117. package/packages/datadog-plugin-playwright/src/index.js +1 -1
  118. package/packages/datadog-plugin-vitest/src/index.js +103 -27
  119. package/packages/datadog-plugin-ws/src/util.js +2 -1
  120. package/packages/datadog-shimmer/src/shimmer.js +6 -2
  121. package/packages/dd-trace/src/aiguard/sdk.js +3 -0
  122. package/packages/dd-trace/src/appsec/api_security/normalized-route.js +453 -0
  123. package/packages/dd-trace/src/appsec/{blocking.js → blocking/index.js} +26 -6
  124. package/packages/dd-trace/src/appsec/handlers/auth.js +62 -0
  125. package/packages/dd-trace/src/appsec/handlers/http-request.js +228 -0
  126. package/packages/dd-trace/src/appsec/handlers/http-response.js +78 -0
  127. package/packages/dd-trace/src/appsec/handlers/http-shared.js +24 -0
  128. package/packages/dd-trace/src/appsec/handlers/payments.js +104 -0
  129. package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +1 -1
  130. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +1 -1
  131. package/packages/dd-trace/src/appsec/index.js +48 -476
  132. package/packages/dd-trace/src/appsec/sdk/track_event.js +9 -0
  133. package/packages/dd-trace/src/carrier.js +356 -0
  134. package/packages/dd-trace/src/ci-visibility/coverage-report-discovery.js +46 -14
  135. package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +89 -0
  136. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +27 -13
  137. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +17 -0
  138. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +21 -1
  139. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +22 -7
  140. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +9 -14
  141. package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +21 -5
  142. package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +1 -1
  143. package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +5 -1
  144. package/packages/dd-trace/src/config/generated-config-types.d.ts +5 -0
  145. package/packages/dd-trace/src/config/helper.js +2 -0
  146. package/packages/dd-trace/src/config/index.js +16 -5
  147. package/packages/dd-trace/src/config/remote_config.js +1 -1
  148. package/packages/dd-trace/src/config/supported-configurations.json +18 -0
  149. package/packages/dd-trace/src/datastreams/context.js +6 -1
  150. package/packages/dd-trace/src/datastreams/manager.js +5 -1
  151. package/packages/dd-trace/src/datastreams/pathway.js +23 -22
  152. package/packages/dd-trace/src/datastreams/processor.js +3 -2
  153. package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
  154. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +0 -1
  155. package/packages/dd-trace/src/guardrails/apply-pm2-env.js +16 -0
  156. package/packages/dd-trace/src/guardrails/log.js +1 -10
  157. package/packages/dd-trace/src/llmobs/constants/tags.js +5 -0
  158. package/packages/dd-trace/src/llmobs/eval-metric.js +249 -0
  159. package/packages/dd-trace/src/llmobs/experiments/index.js +33 -25
  160. package/packages/dd-trace/src/llmobs/experiments/util.js +4 -2
  161. package/packages/dd-trace/src/llmobs/index.js +34 -2
  162. package/packages/dd-trace/src/llmobs/noop.js +2 -0
  163. package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +1 -1
  164. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -1
  165. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +5 -5
  166. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +1 -1
  167. package/packages/dd-trace/src/llmobs/sdk.js +149 -68
  168. package/packages/dd-trace/src/llmobs/span_processor.js +16 -0
  169. package/packages/dd-trace/src/llmobs/tagger.js +96 -0
  170. package/packages/dd-trace/src/llmobs/telemetry.js +18 -0
  171. package/packages/dd-trace/src/llmobs/util.js +78 -0
  172. package/packages/dd-trace/src/llmobs/writers/base.js +3 -0
  173. package/packages/dd-trace/src/llmobs/writers/util.js +2 -0
  174. package/packages/dd-trace/src/log/channels.js +1 -9
  175. package/packages/dd-trace/src/log/levels.js +12 -0
  176. package/packages/dd-trace/src/openfeature/writers/exposures.js +1 -1
  177. package/packages/dd-trace/src/openfeature/writers/util.js +1 -1
  178. package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +1 -1
  179. package/packages/dd-trace/src/opentelemetry/metrics/meter.js +8 -4
  180. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -1
  181. package/packages/dd-trace/src/opentelemetry/span.js +4 -0
  182. package/packages/dd-trace/src/opentracing/propagation/text_map.js +126 -120
  183. package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +4 -8
  184. package/packages/dd-trace/src/plugin_manager.js +2 -0
  185. package/packages/dd-trace/src/plugins/ci_plugin.js +21 -5
  186. package/packages/dd-trace/src/plugins/index.js +1 -0
  187. package/packages/dd-trace/src/plugins/util/ci.js +6 -0
  188. package/packages/dd-trace/src/plugins/util/git.js +6 -4
  189. package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +2 -2
  190. package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
  191. package/packages/{datadog-plugin-jest/src/util.js → dd-trace/src/plugins/util/jest.js} +3 -62
  192. package/packages/dd-trace/src/plugins/util/stacktrace.js +3 -0
  193. package/packages/dd-trace/src/plugins/util/test.js +397 -74
  194. package/packages/dd-trace/src/plugins/util/url.js +1 -1
  195. package/packages/dd-trace/src/plugins/util/web.js +76 -3
  196. package/packages/dd-trace/src/profiler.js +1 -1
  197. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +1 -1
  198. package/packages/dd-trace/src/profiling/profilers/events.js +2 -2
  199. package/packages/dd-trace/src/proxy.js +1 -0
  200. package/packages/dd-trace/src/ritm.js +5 -0
  201. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +4 -2
  202. package/packages/dd-trace/src/sampling_rule.js +4 -2
  203. package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +1 -1
  204. package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +1 -1
  205. package/packages/dd-trace/src/telemetry/logs/index.js +3 -0
  206. package/packages/dd-trace/src/telemetry/telemetry.js +1 -1
  207. package/vendor/dist/pprof-format/index.js +1 -1
  208. package/version.js +10 -8
  209. /package/packages/dd-trace/src/appsec/{blocked_templates.js → blocking/templates.js} +0 -0
@@ -1,12 +1,24 @@
1
1
  'use strict'
2
2
 
3
3
  const { errorMonitor } = require('node:events')
4
+ const { performance } = require('node:perf_hooks')
4
5
 
5
6
  const shimmer = require('../../datadog-shimmer')
6
7
  const {
7
8
  channel,
8
9
  addHook,
9
10
  } = require('./helpers/instrument')
11
+ const {
12
+ clearPoolWaitTime,
13
+ dispatchesAcquireSynchronously,
14
+ isPoolQueryAcquire,
15
+ runOutsidePoolQueryAcquire,
16
+ runPoolAcquireError,
17
+ runWithPoolWait,
18
+ takePoolWaitTime,
19
+ wrapPoolAcquireCarrier,
20
+ wrapPoolQueryMethod,
21
+ } = require('./helpers/pool-acquire')
10
22
 
11
23
  const startCh = channel('apm:pg:query:start')
12
24
  const finishCh = channel('apm:pg:query:finish')
@@ -18,6 +30,14 @@ const finishPoolQueryCh = channel('datadog:pg:pool:query:finish')
18
30
  const poolConnectStartCh = channel('apm:pg:pool:connect:start')
19
31
  const poolConnectFinishCh = channel('apm:pg:pool:connect:finish')
20
32
 
33
+ const poolAcquireStartCh = channel('apm:pg:pool:acquire:start')
34
+ const poolAcquireFinishCh = channel('apm:pg:pool:acquire:finish')
35
+ const poolAcquireChannels = {
36
+ connectionFinishCh: poolConnectFinishCh,
37
+ acquireStartCh: poolAcquireStartCh,
38
+ acquireFinishCh: poolAcquireFinishCh,
39
+ }
40
+
21
41
  // Drivers like pg-promise reuse the same prepared-statement query object across executions; cache
22
42
  // the un-injected `text` so the wrap doesn't capture a previous DBM injection as the new original.
23
43
  const originalTextCache = new WeakMap()
@@ -33,23 +53,118 @@ addHook({ name: 'pg', versions: ['>=8.0.3'], file: 'lib/client.js' }, Client =>
33
53
  })
34
54
 
35
55
  addHook({ name: 'pg', versions: ['>=8.0.3'] }, pg => {
56
+ const poolWaitTransfer = { deferred: false }
57
+ const deferredPoolAcquire = !dispatchesAcquireSynchronously(
58
+ pg.Pool.prototype.query,
59
+ Object.assign(Object.create(pg.Pool.prototype), { Promise }),
60
+ 'connect',
61
+ ['SELECT 1', () => {}]
62
+ )
63
+
36
64
  // pg defers a busy pool's connect callback and runs it in the releasing query's async context;
37
65
  // capture the caller's context and restore it around the callback so spans attach to the caller.
38
- shimmer.wrap(pg.Pool.prototype, 'connect', connect => function (cb) {
39
- if (typeof cb !== 'function' || !poolConnectStartCh.hasSubscribers) {
40
- return connect.apply(this, arguments)
41
- }
66
+ shimmer.wrap(pg.Pool.prototype, 'connect', connect => {
67
+ /**
68
+ * @param {Function|undefined} callback
69
+ * @returns {unknown}
70
+ */
71
+ const wrappedConnect = function (callback) {
72
+ // Pool.query always supplies a callback, so a missing callback is an explicit acquire.
73
+ if (typeof callback !== 'function') {
74
+ if (!poolAcquireStartCh.hasSubscribers) {
75
+ return connect.apply(this, arguments)
76
+ }
42
77
 
43
- const ctx = {}
44
- arguments[0] = function (...args) {
45
- return poolConnectFinishCh.runStores(ctx, cb, this, ...args)
46
- }
78
+ const start = acquireStart(this)
79
+ const acquireCtx = { poolOptions: this.options }
80
+ poolAcquireStartCh.publish(acquireCtx)
81
+
82
+ return connectForAcquire(connect, this, arguments, acquireCtx, start).then(client => {
83
+ clearPoolWaitTime(client)
84
+ acquireCtx.params = client.connectionParameters
85
+ finishAcquire(acquireCtx, start)
86
+ return client
87
+ }, error => {
88
+ acquireCtx.error = error
89
+ finishAcquire(acquireCtx, start)
90
+ throw error
91
+ })
92
+ }
93
+
94
+ if (!poolConnectStartCh.hasSubscribers) {
95
+ return connect.apply(this, arguments)
96
+ }
97
+
98
+ const ctx = {}
99
+ const poolOptions = this.options
100
+ const start = acquireStart(this)
101
+ const poolQueryAcquire = isPoolQueryAcquire()
102
+ let acquireCtx
103
+
104
+ if (poolQueryAcquire) {
105
+ arguments[0] = function (...args) {
106
+ const client = args[1]
107
+ if (client !== undefined) {
108
+ const waitTime = acquireWait(start)
109
+ return runWithPoolWait(
110
+ poolWaitTransfer,
111
+ client,
112
+ waitTime,
113
+ poolConnectFinishCh,
114
+ ctx,
115
+ callback,
116
+ this,
117
+ args
118
+ )
119
+ }
120
+ if (args[0] && poolAcquireStartCh.hasSubscribers) {
121
+ return runPoolAcquireError(
122
+ start,
123
+ args[0],
124
+ { poolOptions },
125
+ poolAcquireChannels,
126
+ ctx,
127
+ callback,
128
+ this,
129
+ args
130
+ )
131
+ }
132
+ return poolConnectFinishCh.runStores(ctx, callback, this, ...args)
133
+ }
134
+ } else {
135
+ acquireCtx = { poolOptions: this.options }
136
+ poolAcquireStartCh.publish(acquireCtx)
137
+
138
+ arguments[0] = function (...args) {
139
+ const client = args[1]
140
+ acquireCtx.error = args[0]
141
+ // A failed acquire has no client, so keep the parameters `connectForAcquire` snapshotted.
142
+ if (client !== undefined) {
143
+ clearPoolWaitTime(client)
144
+ acquireCtx.params = client.connectionParameters
145
+ }
146
+ finishAcquire(acquireCtx, start)
147
+ return poolConnectFinishCh.runStores(ctx, callback, this, ...args)
148
+ }
149
+ }
47
150
 
48
- poolConnectStartCh.publish(ctx)
151
+ poolConnectStartCh.publish(ctx)
49
152
 
50
- return connect.apply(this, arguments)
153
+ if (acquireCtx === undefined) return runOutsidePoolQueryAcquire(connect, this, arguments)
154
+
155
+ return connectForAcquire(connect, this, arguments, acquireCtx, start)
156
+ }
157
+
158
+ return wrapPoolAcquireCarrier(
159
+ wrappedConnect,
160
+ connect,
161
+ poolConnectStartCh,
162
+ deferredPoolAcquire
163
+ )
51
164
  })
52
- shimmer.wrap(pg.Pool.prototype, 'query', query => wrapPoolQuery(query))
165
+ shimmer.wrap(pg.Pool.prototype, 'query', query => wrapPoolQuery(
166
+ wrapPoolQueryMethod(query, poolConnectStartCh, deferredPoolAcquire)
167
+ ))
53
168
  return pg
54
169
  })
55
170
 
@@ -83,6 +198,12 @@ function wrapQuery (query) {
83
198
  abortController,
84
199
  stream,
85
200
  }
201
+
202
+ const waitTime = takePoolWaitTime(this)
203
+ if (waitTime !== undefined) {
204
+ ctx.poolWaitTime = waitTime
205
+ }
206
+
86
207
  const finish = (error, res) => {
87
208
  if (error) {
88
209
  ctx.error = error
@@ -185,6 +306,83 @@ function wrapQuery (query) {
185
306
  const finish = (ctx) => {
186
307
  finishPoolQueryCh.publish(ctx)
187
308
  }
309
+
310
+ /**
311
+ * @typedef {{ database?: string, user?: string, host?: string, port?: number }} PoolConnectionParameters
312
+ * @typedef {{ connectionParameters?: PoolConnectionParameters }} PoolClient
313
+ * @typedef {{
314
+ * options?: PoolConnectionParameters,
315
+ * idleCount: number,
316
+ * waitingCount: number,
317
+ * _clients?: PoolClient[]
318
+ * }} InstrumentedPool
319
+ * @typedef {{
320
+ * poolOptions?: PoolConnectionParameters,
321
+ * params?: PoolConnectionParameters,
322
+ * error?: unknown,
323
+ * poolWaitTime?: number
324
+ * }} AcquireContext
325
+ * @typedef {{ length: number, [index: number]: unknown } & Iterable<unknown>} ArgumentsLike
326
+ */
327
+
328
+ // pg drains its pending queue FIFO on the next tick, so an idle client is only ours when it
329
+ // outnumbers the requests already queued ahead of us. That handoff is not a wait on the pool.
330
+ /**
331
+ * @param {InstrumentedPool} pool
332
+ */
333
+ function acquireStart (pool) {
334
+ return pool.idleCount > pool.waitingCount ? undefined : performance.now()
335
+ }
336
+
337
+ /**
338
+ * @param {number | undefined} start
339
+ */
340
+ function acquireWait (start) {
341
+ return start === undefined ? 0 : performance.now() - start
342
+ }
343
+
344
+ /**
345
+ * @param {InstrumentedPool} pool
346
+ */
347
+ function latestPoolConnectionParameters (pool) {
348
+ // pg-pool removes a failed client before invoking the acquire callback, so snapshot it while
349
+ // connect is still pending.
350
+ const clients = pool._clients
351
+ return clients?.at(-1)?.connectionParameters
352
+ }
353
+
354
+ /**
355
+ * @param {Function} connect
356
+ * @param {InstrumentedPool} pool
357
+ * @param {ArgumentsLike} args
358
+ * @param {AcquireContext} acquireCtx
359
+ * @param {number | undefined} start
360
+ */
361
+ function connectForAcquire (connect, pool, args, acquireCtx, start) {
362
+ let result
363
+ try {
364
+ result = connect.apply(pool, args)
365
+ } catch (error) {
366
+ // pg throws synchronously when it cannot even build a client, from a malformed connection
367
+ // string or a caller-supplied `Client` constructor, so the span needs finishing here.
368
+ acquireCtx.error = error
369
+ finishAcquire(acquireCtx, start)
370
+ throw error
371
+ }
372
+
373
+ acquireCtx.params = latestPoolConnectionParameters(pool)
374
+ return result
375
+ }
376
+
377
+ /**
378
+ * @param {AcquireContext} ctx
379
+ * @param {number | undefined} start
380
+ */
381
+ function finishAcquire (ctx, start) {
382
+ ctx.poolWaitTime = acquireWait(start)
383
+ poolAcquireFinishCh.publish(ctx)
384
+ }
385
+
188
386
  function wrapPoolQuery (query) {
189
387
  return function (...args) {
190
388
  if (!startPoolQueryCh.hasSubscribers) {