dd-trace 5.101.0 → 5.103.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 (235) hide show
  1. package/ext/exporters.js +1 -0
  2. package/package.json +20 -17
  3. package/packages/datadog-esbuild/src/utils.js +2 -2
  4. package/packages/datadog-instrumentations/src/aerospike.js +2 -2
  5. package/packages/datadog-instrumentations/src/ai.js +9 -9
  6. package/packages/datadog-instrumentations/src/amqplib.js +6 -7
  7. package/packages/datadog-instrumentations/src/anthropic.js +10 -10
  8. package/packages/datadog-instrumentations/src/apollo-server-core.js +3 -3
  9. package/packages/datadog-instrumentations/src/apollo-server.js +5 -5
  10. package/packages/datadog-instrumentations/src/avsc.js +6 -6
  11. package/packages/datadog-instrumentations/src/aws-sdk.js +151 -67
  12. package/packages/datadog-instrumentations/src/azure-durable-functions.js +8 -8
  13. package/packages/datadog-instrumentations/src/bluebird.js +2 -2
  14. package/packages/datadog-instrumentations/src/body-parser.js +2 -2
  15. package/packages/datadog-instrumentations/src/cassandra-driver.js +7 -7
  16. package/packages/datadog-instrumentations/src/child_process.js +12 -12
  17. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +41 -24
  18. package/packages/datadog-instrumentations/src/connect.js +7 -7
  19. package/packages/datadog-instrumentations/src/cookie-parser.js +4 -4
  20. package/packages/datadog-instrumentations/src/cookie.js +2 -2
  21. package/packages/datadog-instrumentations/src/couchbase.js +73 -238
  22. package/packages/datadog-instrumentations/src/crypto.js +4 -4
  23. package/packages/datadog-instrumentations/src/cucumber.js +78 -17
  24. package/packages/datadog-instrumentations/src/dns.js +0 -3
  25. package/packages/datadog-instrumentations/src/elasticsearch.js +8 -11
  26. package/packages/datadog-instrumentations/src/electron/preload.js +42 -0
  27. package/packages/datadog-instrumentations/src/electron.js +240 -0
  28. package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +6 -6
  29. package/packages/datadog-instrumentations/src/express-session.js +4 -4
  30. package/packages/datadog-instrumentations/src/express.js +10 -11
  31. package/packages/datadog-instrumentations/src/fastify.js +2 -2
  32. package/packages/datadog-instrumentations/src/fetch.js +5 -5
  33. package/packages/datadog-instrumentations/src/fs.js +14 -14
  34. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +5 -7
  35. package/packages/datadog-instrumentations/src/google-genai.js +4 -4
  36. package/packages/datadog-instrumentations/src/graphql.js +13 -12
  37. package/packages/datadog-instrumentations/src/grpc/server.js +2 -2
  38. package/packages/datadog-instrumentations/src/hapi.js +2 -2
  39. package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +9 -9
  40. package/packages/datadog-instrumentations/src/helpers/hook.js +4 -1
  41. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  42. package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -2
  43. package/packages/datadog-instrumentations/src/helpers/kafka.js +41 -0
  44. package/packages/datadog-instrumentations/src/helpers/promise.js +2 -2
  45. package/packages/datadog-instrumentations/src/hono.js +2 -2
  46. package/packages/datadog-instrumentations/src/http/client.js +6 -6
  47. package/packages/datadog-instrumentations/src/http/server.js +9 -9
  48. package/packages/datadog-instrumentations/src/ioredis.js +16 -12
  49. package/packages/datadog-instrumentations/src/jest.js +382 -81
  50. package/packages/datadog-instrumentations/src/kafkajs.js +165 -174
  51. package/packages/datadog-instrumentations/src/knex.js +17 -17
  52. package/packages/datadog-instrumentations/src/koa.js +12 -12
  53. package/packages/datadog-instrumentations/src/ldapjs.js +5 -5
  54. package/packages/datadog-instrumentations/src/light-my-request.js +2 -2
  55. package/packages/datadog-instrumentations/src/limitd-client.js +4 -4
  56. package/packages/datadog-instrumentations/src/lodash.js +4 -4
  57. package/packages/datadog-instrumentations/src/mariadb.js +13 -13
  58. package/packages/datadog-instrumentations/src/memcached.js +2 -2
  59. package/packages/datadog-instrumentations/src/microgateway-core.js +2 -2
  60. package/packages/datadog-instrumentations/src/mocha/common.js +3 -3
  61. package/packages/datadog-instrumentations/src/mocha/main.js +85 -11
  62. package/packages/datadog-instrumentations/src/mocha/utils.js +133 -16
  63. package/packages/datadog-instrumentations/src/mocha/worker.js +7 -5
  64. package/packages/datadog-instrumentations/src/mongodb-core.js +42 -30
  65. package/packages/datadog-instrumentations/src/mongodb.js +5 -5
  66. package/packages/datadog-instrumentations/src/mongoose.js +21 -21
  67. package/packages/datadog-instrumentations/src/mquery.js +5 -5
  68. package/packages/datadog-instrumentations/src/multer.js +4 -4
  69. package/packages/datadog-instrumentations/src/mysql.js +16 -16
  70. package/packages/datadog-instrumentations/src/mysql2.js +4 -4
  71. package/packages/datadog-instrumentations/src/net.js +14 -8
  72. package/packages/datadog-instrumentations/src/nyc.js +5 -5
  73. package/packages/datadog-instrumentations/src/openai.js +19 -19
  74. package/packages/datadog-instrumentations/src/oracledb.js +6 -6
  75. package/packages/datadog-instrumentations/src/passport-utils.js +5 -5
  76. package/packages/datadog-instrumentations/src/pg.js +39 -25
  77. package/packages/datadog-instrumentations/src/pino.js +6 -10
  78. package/packages/datadog-instrumentations/src/playwright.js +445 -68
  79. package/packages/datadog-instrumentations/src/protobufjs.js +16 -16
  80. package/packages/datadog-instrumentations/src/redis.js +20 -12
  81. package/packages/datadog-instrumentations/src/restify.js +2 -2
  82. package/packages/datadog-instrumentations/src/router.js +12 -12
  83. package/packages/datadog-instrumentations/src/stripe.js +12 -12
  84. package/packages/datadog-instrumentations/src/vitest.js +107 -26
  85. package/packages/datadog-instrumentations/src/winston.js +4 -4
  86. package/packages/datadog-instrumentations/src/ws.js +7 -7
  87. package/packages/datadog-plugin-apollo/src/gateway/request.js +1 -21
  88. package/packages/datadog-plugin-aws-sdk/src/base.js +70 -28
  89. package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +1 -1
  90. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +20 -13
  91. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +46 -36
  92. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +34 -23
  93. package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -1
  94. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -1
  95. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +14 -15
  96. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +74 -55
  97. package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +20 -18
  98. package/packages/datadog-plugin-aws-sdk/src/util.js +22 -0
  99. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +6 -6
  100. package/packages/datadog-plugin-couchbase/src/index.js +58 -52
  101. package/packages/datadog-plugin-cucumber/src/index.js +5 -0
  102. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +215 -26
  103. package/packages/datadog-plugin-cypress/src/support.js +13 -1
  104. package/packages/datadog-plugin-electron/src/index.js +17 -0
  105. package/packages/datadog-plugin-electron/src/ipc.js +143 -0
  106. package/packages/datadog-plugin-electron/src/net.js +82 -0
  107. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -5
  108. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +27 -18
  109. package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +3 -1
  110. package/packages/datadog-plugin-graphql/src/execute.js +6 -28
  111. package/packages/datadog-plugin-graphql/src/resolve.js +30 -35
  112. package/packages/datadog-plugin-graphql/src/tools/signature.js +32 -7
  113. package/packages/datadog-plugin-graphql/src/tools/transforms.js +118 -100
  114. package/packages/datadog-plugin-graphql/src/utils.js +29 -0
  115. package/packages/datadog-plugin-grpc/src/client.js +6 -7
  116. package/packages/datadog-plugin-grpc/src/util.js +57 -22
  117. package/packages/datadog-plugin-http/src/client.js +3 -7
  118. package/packages/datadog-plugin-jest/src/index.js +92 -50
  119. package/packages/datadog-plugin-jest/src/util.js +1 -2
  120. package/packages/datadog-plugin-mocha/src/index.js +5 -0
  121. package/packages/datadog-plugin-mongodb-core/src/index.js +36 -69
  122. package/packages/datadog-plugin-mysql/src/index.js +1 -1
  123. package/packages/datadog-plugin-openai/src/services.js +2 -1
  124. package/packages/datadog-plugin-openai/src/tracing.js +12 -23
  125. package/packages/datadog-plugin-pg/src/index.js +3 -3
  126. package/packages/datadog-plugin-playwright/src/index.js +5 -1
  127. package/packages/datadog-plugin-redis/src/index.js +18 -23
  128. package/packages/datadog-plugin-vitest/src/index.js +8 -1
  129. package/packages/datadog-shimmer/src/shimmer.js +7 -1
  130. package/packages/dd-trace/src/aiguard/index.js +3 -1
  131. package/packages/dd-trace/src/aiguard/sdk.js +36 -30
  132. package/packages/dd-trace/src/aiguard/tags.js +20 -11
  133. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +1 -1
  134. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +81 -81
  135. package/packages/dd-trace/src/appsec/iast/security-controls/index.js +2 -2
  136. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +2 -2
  137. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +4 -4
  138. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
  139. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -0
  140. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -3
  141. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +83 -48
  142. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
  143. package/packages/dd-trace/src/appsec/index.js +21 -24
  144. package/packages/dd-trace/src/appsec/reporter.js +3 -1
  145. package/packages/dd-trace/src/appsec/rule_manager.js +4 -2
  146. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +31 -16
  147. package/packages/dd-trace/src/azure_metadata.js +17 -6
  148. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +4 -4
  149. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -2
  150. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +6 -4
  151. package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +1 -1
  152. package/packages/dd-trace/src/config/defaults.js +3 -14
  153. package/packages/dd-trace/src/config/generated-config-types.d.ts +3 -1
  154. package/packages/dd-trace/src/config/git_properties.js +2 -2
  155. package/packages/dd-trace/src/config/helper.js +4 -0
  156. package/packages/dd-trace/src/config/index.js +2 -2
  157. package/packages/dd-trace/src/config/major-overrides.js +98 -0
  158. package/packages/dd-trace/src/config/parsers.js +7 -1
  159. package/packages/dd-trace/src/config/supported-configurations.json +51 -38
  160. package/packages/dd-trace/src/datastreams/checkpointer.js +2 -2
  161. package/packages/dd-trace/src/datastreams/index.js +2 -1
  162. package/packages/dd-trace/src/datastreams/manager.js +1 -1
  163. package/packages/dd-trace/src/datastreams/processor.js +3 -4
  164. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +2 -2
  165. package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +1 -0
  166. package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
  167. package/packages/dd-trace/src/debugger/devtools_client/state.js +2 -1
  168. package/packages/dd-trace/src/debugger/index.js +7 -7
  169. package/packages/dd-trace/src/dogstatsd.js +2 -2
  170. package/packages/dd-trace/src/encode/0.4.js +748 -232
  171. package/packages/dd-trace/src/encode/0.5.js +47 -10
  172. package/packages/dd-trace/src/encode/agentless-json.js +1 -1
  173. package/packages/dd-trace/src/exporter.js +2 -0
  174. package/packages/dd-trace/src/exporters/agent/index.js +2 -1
  175. package/packages/dd-trace/src/exporters/agentless/index.js +3 -2
  176. package/packages/dd-trace/src/exporters/agentless/writer.js +2 -2
  177. package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -1
  178. package/packages/dd-trace/src/exporters/common/request.js +1 -1
  179. package/packages/dd-trace/src/exporters/electron/index.js +49 -0
  180. package/packages/dd-trace/src/external-logger/src/index.js +2 -1
  181. package/packages/dd-trace/src/git_metadata.js +10 -8
  182. package/packages/dd-trace/src/lambda/handler-paths.js +52 -0
  183. package/packages/dd-trace/src/lambda/index.js +62 -14
  184. package/packages/dd-trace/src/lambda/runtime/patch.js +21 -46
  185. package/packages/dd-trace/src/llmobs/index.js +13 -2
  186. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -2
  187. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +45 -15
  188. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +6 -3
  189. package/packages/dd-trace/src/llmobs/sdk.js +24 -26
  190. package/packages/dd-trace/src/llmobs/span_processor.js +25 -5
  191. package/packages/dd-trace/src/llmobs/util.js +1 -0
  192. package/packages/dd-trace/src/llmobs/writers/base.js +2 -1
  193. package/packages/dd-trace/src/msgpack/chunk.js +6 -3
  194. package/packages/dd-trace/src/openfeature/noop.js +40 -36
  195. package/packages/dd-trace/src/openfeature/writers/base.js +2 -1
  196. package/packages/dd-trace/src/openfeature/writers/exposures.js +33 -52
  197. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +2 -1
  198. package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +1 -2
  199. package/packages/dd-trace/src/opentelemetry/tracer.js +0 -22
  200. package/packages/dd-trace/src/opentracing/propagation/text_map.js +20 -9
  201. package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +2 -11
  202. package/packages/dd-trace/src/payload-tagging/config/index.js +2 -2
  203. package/packages/dd-trace/src/plugins/ci_plugin.js +49 -4
  204. package/packages/dd-trace/src/plugins/database.js +54 -12
  205. package/packages/dd-trace/src/plugins/index.js +1 -0
  206. package/packages/dd-trace/src/plugins/plugin.js +2 -4
  207. package/packages/dd-trace/src/plugins/util/ci.js +9 -9
  208. package/packages/dd-trace/src/plugins/util/git-cache.js +23 -23
  209. package/packages/dd-trace/src/plugins/util/stacktrace.js +2 -2
  210. package/packages/dd-trace/src/plugins/util/test.js +56 -12
  211. package/packages/dd-trace/src/plugins/util/url.js +1 -3
  212. package/packages/dd-trace/src/plugins/util/user-provided-git.js +18 -16
  213. package/packages/dd-trace/src/plugins/util/web.js +5 -7
  214. package/packages/dd-trace/src/priority_sampler.js +1 -1
  215. package/packages/dd-trace/src/profiling/profiler.js +1 -1
  216. package/packages/dd-trace/src/profiling/profilers/events.js +3 -23
  217. package/packages/dd-trace/src/profiling/profilers/wall.js +5 -6
  218. package/packages/dd-trace/src/profiling/ssi-heuristics.js +1 -1
  219. package/packages/dd-trace/src/rate_limiter.js +1 -1
  220. package/packages/dd-trace/src/remote_config/scheduler.js +1 -1
  221. package/packages/dd-trace/src/ritm.js +2 -1
  222. package/packages/dd-trace/src/runtime_metrics/index.js +2 -2
  223. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -8
  224. package/packages/dd-trace/src/scope.js +3 -10
  225. package/packages/dd-trace/src/serverless.js +6 -6
  226. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +27 -1
  227. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
  228. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +24 -0
  229. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
  230. package/packages/dd-trace/src/span_stats.js +1 -1
  231. package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
  232. package/packages/dd-trace/src/telemetry/endpoints.js +1 -1
  233. package/packages/dd-trace/src/telemetry/telemetry.js +2 -2
  234. package/packages/dd-trace/src/tracer.js +7 -7
  235. package/packages/dd-trace/src/lambda/runtime/ritm.js +0 -133
@@ -59,16 +59,16 @@ function wrapLayerHandle (layer) {
59
59
 
60
60
  const original = layer.handle
61
61
 
62
- return shimmer.wrapFunction(original, original => function () {
63
- if (!enterChannel.hasSubscribers) return original.apply(this, arguments)
62
+ return shimmer.wrapFunction(original, original => function (...args) {
63
+ if (!enterChannel.hasSubscribers) return original.apply(this, args)
64
64
 
65
- const lastIndex = arguments.length - 1
65
+ const lastIndex = args.length - 1
66
66
  const name = original._name || original.name
67
- const req = arguments[arguments.length > 3 ? 1 : 0]
68
- const next = arguments[lastIndex]
67
+ const req = args[args.length > 3 ? 1 : 0]
68
+ const next = args[lastIndex]
69
69
 
70
70
  if (typeof next === 'function') {
71
- arguments[lastIndex] = wrapNext(req, next)
71
+ args[lastIndex] = wrapNext(req, next)
72
72
  }
73
73
 
74
74
  const route = layer.route
@@ -76,7 +76,7 @@ function wrapLayerHandle (layer) {
76
76
  enterChannel.publish({ name, req, route })
77
77
 
78
78
  try {
79
- return original.apply(this, arguments)
79
+ return original.apply(this, args)
80
80
  } catch (error) {
81
81
  errorChannel.publish({ req, error })
82
82
  nextChannel.publish({ req })
@@ -6,7 +6,7 @@ const { channel, addHook } = require('./helpers/instrument')
6
6
  const cookieParserReadCh = channel('datadog:cookie-parser:read:finish')
7
7
 
8
8
  function publishRequestCookieAndNext (req, res, next) {
9
- return shimmer.wrapFunction(next, next => function cookieParserWrapper () {
9
+ return shimmer.wrapFunction(next, next => function cookieParserWrapper (...args) {
10
10
  if (cookieParserReadCh.hasSubscribers && req) {
11
11
  const abortController = new AbortController()
12
12
 
@@ -17,7 +17,7 @@ function publishRequestCookieAndNext (req, res, next) {
17
17
  if (abortController.signal.aborted) return
18
18
  }
19
19
 
20
- return next.apply(this, arguments)
20
+ return next.apply(this, args)
21
21
  })
22
22
  }
23
23
 
@@ -25,8 +25,8 @@ addHook({
25
25
  name: 'cookie-parser',
26
26
  versions: ['>=1.0.0'],
27
27
  }, cookieParser => {
28
- return shimmer.wrapFunction(cookieParser, cookieParser => function () {
29
- const cookieMiddleware = cookieParser.apply(this, arguments)
28
+ return shimmer.wrapFunction(cookieParser, cookieParser => function (...args) {
29
+ const cookieMiddleware = cookieParser.apply(this, args)
30
30
 
31
31
  return shimmer.wrapFunction(cookieMiddleware, cookieMiddleware => function (req, res, next) {
32
32
  arguments[2] = publishRequestCookieAndNext(req, res, next)
@@ -6,8 +6,8 @@ const { channel, addHook } = require('./helpers/instrument')
6
6
  const cookieParseCh = channel('datadog:cookie:parse:finish')
7
7
 
8
8
  function wrapParse (originalParse) {
9
- return function () {
10
- const cookies = originalParse.apply(this, arguments)
9
+ return function (...args) {
10
+ const cookies = originalParse.apply(this, args)
11
11
  if (cookieParseCh.hasSubscribers && cookies) {
12
12
  cookieParseCh.publish({ cookies })
13
13
  }
@@ -1,12 +1,27 @@
1
1
  'use strict'
2
2
 
3
- const { errorMonitor } = require('events')
3
+ const { tracingChannel } = require('dc-polyfill')
4
+
4
5
  const shimmer = require('../../datadog-shimmer')
5
6
  const {
6
- channel,
7
7
  addHook,
8
8
  } = require('./helpers/instrument')
9
9
 
10
+ // One TracingChannel per traced operation, looked up at module init so the
11
+ // hot path only does property reads on a stable handle.
12
+ const queryCh = tracingChannel('apm:couchbase:query')
13
+ const upsertCh = tracingChannel('apm:couchbase:upsert')
14
+ const insertCh = tracingChannel('apm:couchbase:insert')
15
+ const replaceCh = tracingChannel('apm:couchbase:replace')
16
+
17
+ /** @type {Map<string, ReturnType<typeof tracingChannel>>} */
18
+ const opChannelByName = new Map([
19
+ ['query', queryCh],
20
+ ['upsert', upsertCh],
21
+ ['insert', insertCh],
22
+ ['replace', replaceCh],
23
+ ])
24
+
10
25
  function findCallbackIndex (args, lowerbound = 2) {
11
26
  for (let i = args.length - 1; i >= lowerbound; i--) {
12
27
  if (typeof args[i] === 'function') return i
@@ -19,274 +34,99 @@ function getQueryResource (q) {
19
34
  return q && (typeof q === 'string' ? q : q.statement)
20
35
  }
21
36
 
22
- function wrapAllNames (names, action) {
23
- for (const name of names) {
24
- action(name)
25
- }
26
- }
27
-
28
- function wrapCallback (callback, ctx, channelPrefix) {
29
- const callbackStartCh = channel(`${channelPrefix}:callback:start`)
30
- const callbackFinishCh = channel(`${channelPrefix}:callback:finish`)
31
-
32
- const wrapped = callbackStartCh.runStores(ctx, () => {
33
- return function (...args) {
34
- return callbackFinishCh.runStores(ctx, () => {
35
- return callback.apply(this, args)
36
- })
37
- }
38
- })
39
- Object.defineProperty(wrapped, '_dd_wrapped', { value: true })
40
- return wrapped
41
- }
42
-
43
- function wrapQuery (query) {
44
- return function (q, params, callback) {
45
- const cb = arguments[arguments.length - 1]
46
- if (typeof cb === 'function') {
47
- const ctx = {}
48
- arguments[arguments.length - 1] = wrapCallback(cb, ctx, 'apm:couchbase:query')
49
- }
50
-
51
- return query.apply(this, arguments)
37
+ // Hand-rolled instead of `tracingChannel.tracePromise`: synchronous
38
+ // `res.then(...)` dodges the `Promise.resolve(thenable)` microtask race on
39
+ // SDK v3.2.x / v4.0-v4.4 (lazy listener attachment), and external `.on()`
40
+ // is forbidden on v4.5.0+ (JSCBC-1301 depromisify). See commit body.
41
+ /**
42
+ * @param {import('node:diagnostics_channel').TracingChannel} ch
43
+ * Pinned per-op channel.
44
+ * @param {(...callArgs: unknown[]) => unknown} fn The SDK method being traced.
45
+ * @param {object} ctx Mutated to record `result` / `error`.
46
+ * @param {object} thisArg
47
+ * @param {unknown[]} args Forwarded to `fn` verbatim.
48
+ */
49
+ function traceV3 (ch, fn, ctx, thisArg, args) {
50
+ if (!ch.start.hasSubscribers) return fn.apply(thisArg, args)
51
+ const cbIndex = findCallbackIndex(args, 1)
52
+ if (cbIndex >= 0) {
53
+ return ch.traceCallback(fn, cbIndex, ctx, thisArg, ...args)
52
54
  }
53
- }
54
-
55
- function wrapCallbackFinish (callback, thisArg, _args, errorCh, finishCh, ctx, channelPrefix) {
56
- const callbackStartCh = channel(`${channelPrefix}:callback:start`)
57
- const callbackFinishCh = channel(`${channelPrefix}:callback:finish`)
58
-
59
- const wrapped = callbackStartCh.runStores(ctx, () => {
60
- return function finish (error, result) {
61
- return callbackFinishCh.runStores(ctx, () => {
62
- if (error) {
63
- ctx.error = error
64
- errorCh.publish(ctx)
65
- }
66
- finishCh.publish(ctx)
67
- return callback.apply(thisArg, [error, result])
68
- })
69
- }
70
- })
71
- Object.defineProperty(wrapped, '_dd_wrapped', { value: true })
72
- return wrapped
73
- }
74
-
75
- function wrap (prefix, fn) {
76
- const startCh = channel(prefix + ':start')
77
- const finishCh = channel(prefix + ':finish')
78
- const errorCh = channel(prefix + ':error')
79
-
80
- const wrapped = function () {
81
- if (!startCh.hasSubscribers) {
82
- return fn.apply(this, arguments)
83
- }
84
-
85
- const callbackIndex = findCallbackIndex(arguments, 1)
86
-
87
- if (callbackIndex < 0) return fn.apply(this, arguments)
88
-
89
- const ctx = { bucket: { name: this.name || this._name }, seedNodes: this._dd_hosts }
90
- return startCh.runStores(ctx, () => {
91
- const cb = arguments[callbackIndex]
92
-
93
- arguments[callbackIndex] = shimmer.wrapFunction(cb, (cb) => {
94
- return wrapCallbackFinish(cb, this, arguments, errorCh, finishCh, ctx, prefix)
95
- })
96
-
97
- try {
98
- return fn.apply(this, arguments)
99
- } catch (error) {
100
- ctx.error = error
101
- void error.stack // trigger getting the stack at the original throwing point
102
- errorCh.publish(ctx)
103
-
104
- throw error
105
- }
106
- })
107
- }
108
- return wrapped
109
- }
110
-
111
- // semver >=2 <3
112
- function wrapMaybeInvoke (_maybeInvoke, channelPrefix) {
113
- return function (fn, args) {
114
- if (!Array.isArray(args)) return _maybeInvoke.apply(this, arguments)
115
-
116
- const callbackIndex = findCallbackIndex(args, 0)
117
-
118
- if (callbackIndex === -1) return _maybeInvoke.apply(this, arguments)
119
-
120
- const callback = args[callbackIndex]
121
-
122
- if (typeof callback === 'function' && !callback._dd_wrapped) {
123
- const ctx = {}
124
- args[callbackIndex] = wrapCallback(callback, ctx, channelPrefix)
125
- }
126
-
127
- return _maybeInvoke.apply(this, arguments)
128
- }
129
- }
130
-
131
- // semver >=3
132
-
133
- function wrapCBandPromise (fn, name, startData, thisArg, args) {
134
- const startCh = channel(`apm:couchbase:${name}:start`)
135
- const finishCh = channel(`apm:couchbase:${name}:finish`)
136
- const errorCh = channel(`apm:couchbase:${name}:error`)
137
-
138
- if (!startCh.hasSubscribers) return fn.apply(thisArg, args)
139
-
140
- const ctx = startData
141
- return startCh.runStores(ctx, () => {
55
+ return ch.start.runStores(ctx, () => {
142
56
  try {
143
- const cbIndex = findCallbackIndex(args, 1)
144
- if (cbIndex >= 0) {
145
- // v3 offers callback or promises event handling
146
- // NOTE: this does not work with v3.2.0-3.2.1 cluster.query, as there is a bug in the couchbase source code
147
- args[cbIndex] = shimmer.wrapFunction(args[cbIndex], (cb) => {
148
- return wrapCallbackFinish(cb, thisArg, args, errorCh, finishCh, ctx, `apm:couchbase:${name}`)
149
- })
150
- }
151
57
  const res = fn.apply(thisArg, args)
152
-
153
- // semver >=3 will always return promise by default
154
58
  res.then(
155
59
  (result) => {
156
60
  ctx.result = result
157
- finishCh.publish(ctx)
61
+ ch.asyncStart.publish(ctx)
62
+ ch.asyncEnd.publish(ctx)
158
63
  },
159
- (err) => {
160
- ctx.error = err
161
- errorCh.publish(ctx)
162
- finishCh.publish(ctx)
64
+ (error) => {
65
+ ctx.error = error
66
+ ch.error.publish(ctx)
67
+ ch.asyncStart.publish(ctx)
68
+ ch.asyncEnd.publish(ctx)
163
69
  }
164
70
  )
165
71
  return res
166
- } catch (e) {
167
- void e.stack
168
- ctx.error = e
169
- errorCh.publish(ctx)
170
- throw e
72
+ } catch (error) {
73
+ ctx.error = error
74
+ ch.error.publish(ctx)
75
+ throw error
76
+ } finally {
77
+ ch.end.publish(ctx)
171
78
  }
172
79
  })
173
80
  }
174
81
 
175
- function wrapWithName (name) {
82
+ /**
83
+ * @param {string} name Operation name (`upsert`, `insert`, `replace`).
84
+ */
85
+ function wrapV3WithName (name) {
86
+ const ch = opChannelByName.get(name)
176
87
  return function (operation) {
177
- return function () { // no arguments used by us
178
- return wrapCBandPromise(operation, name, {
88
+ return function (...args) {
89
+ const ctx = {
179
90
  collection: { name: this._name || '_default' },
180
91
  bucket: { name: this._scope._bucket._name },
181
92
  seedNodes: this._dd_connStr,
182
- }, this, arguments)
93
+ }
94
+ return traceV3(ch, operation, ctx, this, args)
183
95
  }
184
96
  }
185
97
  }
186
98
 
99
+ /**
100
+ * @param {(...args: unknown[]) => unknown} query Original `Cluster.prototype.query`.
101
+ */
187
102
  function wrapV3Query (query) {
188
- return function (q) {
189
- const resource = getQueryResource(q)
190
- return wrapCBandPromise(query, 'query', { resource, seedNodes: this._connStr }, this, arguments)
103
+ return function (...args) {
104
+ const ctx = { resource: getQueryResource(args[0]), seedNodes: this._connStr }
105
+ return traceV3(queryCh, query, ctx, this, args)
191
106
  }
192
107
  }
193
108
 
194
- // semver >=2 <3
195
- addHook({ name: 'couchbase', file: 'lib/bucket.js', versions: ['^2.6.12'] }, Bucket => {
196
- shimmer.wrap(Bucket.prototype, '_maybeInvoke', maybeInvoke => {
197
- return wrapMaybeInvoke(maybeInvoke, 'apm:couchbase:bucket:maybeInvoke')
198
- })
199
-
200
- const startCh = channel('apm:couchbase:query:start')
201
- const finishCh = channel('apm:couchbase:query:finish')
202
- const errorCh = channel('apm:couchbase:query:error')
203
-
204
- shimmer.wrap(Bucket.prototype, 'query', query => wrapQuery(query))
205
-
206
- shimmer.wrap(Bucket.prototype, '_n1qlReq', _n1qlReq => function (host, q, adhoc, emitter) {
207
- if (!startCh.hasSubscribers) {
208
- return _n1qlReq.apply(this, arguments)
209
- }
210
-
211
- if (!emitter || !emitter.once) return _n1qlReq.apply(this, arguments)
212
-
213
- const n1qlQuery = getQueryResource(q)
214
-
215
- const ctx = { resource: n1qlQuery, bucket: { name: this.name || this._name }, seedNodes: this._dd_hosts }
216
- return startCh.runStores(ctx, () => {
217
- emitter.once('rows', () => {
218
- finishCh.publish(ctx)
219
- })
220
-
221
- emitter.once(errorMonitor, (error) => {
222
- if (!error) return
223
- ctx.error = error
224
- errorCh.publish(ctx)
225
- finishCh.publish(ctx)
226
- })
227
-
228
- try {
229
- return _n1qlReq.apply(this, arguments)
230
- } catch (err) {
231
- void err.stack // trigger getting the stack at the original throwing point
232
- ctx.error = err
233
- errorCh.publish(ctx)
234
-
235
- throw err
236
- }
237
- })
238
- })
239
-
240
- wrapAllNames(['upsert', 'insert', 'replace', 'append', 'prepend'], name => {
241
- shimmer.wrap(Bucket.prototype, name, fn => wrap(`apm:couchbase:${name}`, fn))
242
- })
243
-
244
- return Bucket
245
- })
246
-
247
- addHook({ name: 'couchbase', file: 'lib/cluster.js', versions: ['^2.6.12'] }, Cluster => {
248
- shimmer.wrap(Cluster.prototype, '_maybeInvoke', maybeInvoke => {
249
- return wrapMaybeInvoke(maybeInvoke, 'apm:couchbase:cluster:maybeInvoke')
250
- })
251
-
252
- shimmer.wrap(Cluster.prototype, 'query', query => wrapQuery(query))
253
- shimmer.wrap(Cluster.prototype, 'openBucket', openBucket => {
254
- return function () {
255
- const bucket = openBucket.apply(this, arguments)
256
- const hosts = this.dsnObj.hosts
257
- bucket._dd_hosts = hosts.map(hostAndPort => hostAndPort.join(':')).join(',')
258
- return bucket
259
- }
260
- })
261
- return Cluster
262
- })
263
-
264
109
  // semver >=3 <3.2.0
265
110
 
266
111
  addHook({ name: 'couchbase', file: 'lib/bucket.js', versions: ['^3.0.7', '^3.1.3'] }, Bucket => {
267
112
  shimmer.wrap(Bucket.prototype, 'collection', getCollection => {
268
- return function () {
269
- const collection = getCollection.apply(this, arguments)
113
+ return function (...args) {
114
+ const collection = getCollection.apply(this, args)
270
115
  const connStr = this._cluster._connStr
271
116
  collection._dd_connStr = connStr
272
117
  return collection
273
118
  }
274
119
  })
275
-
276
- return Bucket
277
120
  })
278
121
 
279
122
  addHook({ name: 'couchbase', file: 'lib/collection.js', versions: ['^3.0.7', '^3.1.3'] }, Collection => {
280
- wrapAllNames(['upsert', 'insert', 'replace'], name => {
281
- shimmer.wrap(Collection.prototype, name, wrapWithName(name))
282
- })
283
-
284
- return Collection
123
+ for (const name of ['upsert', 'insert', 'replace']) {
124
+ shimmer.wrap(Collection.prototype, name, wrapV3WithName(name))
125
+ }
285
126
  })
286
127
 
287
128
  addHook({ name: 'couchbase', file: 'lib/cluster.js', versions: ['^3.0.7', '^3.1.3'] }, Cluster => {
288
129
  shimmer.wrap(Cluster.prototype, 'query', wrapV3Query)
289
- return Cluster
290
130
  })
291
131
 
292
132
  // semver >=3.2.2
@@ -295,30 +135,25 @@ addHook({ name: 'couchbase', file: 'lib/cluster.js', versions: ['^3.0.7', '^3.1.
295
135
  addHook({ name: 'couchbase', file: 'dist/collection.js', versions: ['>=3.2.2'] }, collection => {
296
136
  const Collection = collection.Collection
297
137
 
298
- wrapAllNames(['upsert', 'insert', 'replace'], name => {
299
- shimmer.wrap(Collection.prototype, name, wrapWithName(name))
300
- })
301
-
302
- return collection
138
+ for (const name of ['upsert', 'insert', 'replace']) {
139
+ shimmer.wrap(Collection.prototype, name, wrapV3WithName(name))
140
+ }
303
141
  })
304
142
 
305
143
  addHook({ name: 'couchbase', file: 'dist/bucket.js', versions: ['>=3.2.2'] }, bucket => {
306
144
  const Bucket = bucket.Bucket
307
145
  shimmer.wrap(Bucket.prototype, 'collection', getCollection => {
308
- return function () {
309
- const collection = getCollection.apply(this, arguments)
146
+ return function (...args) {
147
+ const collection = getCollection.apply(this, args)
310
148
  const connStr = this._cluster._connStr
311
149
  collection._dd_connStr = connStr
312
150
  return collection
313
151
  }
314
152
  })
315
-
316
- return bucket
317
153
  })
318
154
 
319
155
  addHook({ name: 'couchbase', file: 'dist/cluster.js', versions: ['>=3.2.2'] }, (cluster) => {
320
156
  const Cluster = cluster.Cluster
321
157
 
322
158
  shimmer.wrap(Cluster.prototype, 'query', wrapV3Query)
323
- return cluster
324
159
  })
@@ -47,12 +47,12 @@ addHook({ name: 'crypto' }, crypto => {
47
47
 
48
48
  function wrapCryptoMethod (channel) {
49
49
  function wrapMethod (cryptoMethod) {
50
- return function () {
51
- if (channel.hasSubscribers && arguments.length > 0) {
52
- const algorithm = arguments[0]
50
+ return function (...args) {
51
+ if (channel.hasSubscribers && args.length > 0) {
52
+ const algorithm = args[0]
53
53
  channel.publish({ algorithm })
54
54
  }
55
- return cryptoMethod.apply(this, arguments)
55
+ return cryptoMethod.apply(this, args)
56
56
  }
57
57
  }
58
58
  return wrapMethod