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
@@ -7,6 +7,10 @@ const {
7
7
  channel,
8
8
  addHook,
9
9
  } = require('./helpers/instrument')
10
+ const {
11
+ clientToCluster,
12
+ cloneMessages,
13
+ } = require('./helpers/kafka')
10
14
 
11
15
  const producerStartCh = channel('apm:kafkajs:produce:start')
12
16
  const producerCommitCh = channel('apm:kafkajs:produce:commit')
@@ -24,6 +28,26 @@ const batchConsumerErrorCh = channel('apm:kafkajs:consume-batch:error')
24
28
 
25
29
  const disabledHeaderWeakSet = new WeakSet()
26
30
 
31
+ addHook({ name: 'kafkajs', file: 'src/producer/index.js', versions: ['>=1.4'] }, (createProducer) =>
32
+ shimmer.wrapFunction(createProducer, original => function wrappedCreateProducer (params) {
33
+ const producer = original(params)
34
+ if (params?.cluster) {
35
+ clientToCluster.set(producer, params.cluster)
36
+ }
37
+ return producer
38
+ })
39
+ )
40
+
41
+ addHook({ name: 'kafkajs', file: 'src/consumer/index.js', versions: ['>=1.4'] }, (createConsumer) =>
42
+ shimmer.wrapFunction(createConsumer, original => function wrappedCreateConsumer (params) {
43
+ const consumer = original(params)
44
+ if (params?.cluster) {
45
+ clientToCluster.set(consumer, params.cluster)
46
+ }
47
+ return consumer
48
+ })
49
+ )
50
+
27
51
  addHook({ name: 'kafkajs', file: 'src/index.js', versions: ['>=1.4'] }, (BaseKafka) => {
28
52
  class Kafka extends BaseKafka {
29
53
  constructor (options) {
@@ -36,103 +60,121 @@ addHook({ name: 'kafkajs', file: 'src/index.js', versions: ['>=1.4'] }, (BaseKaf
36
60
 
37
61
  shimmer.wrap(Kafka.prototype, 'producer', createProducer => function () {
38
62
  const producer = createProducer.apply(this, arguments)
39
- const send = producer.send
63
+ const originalSend = producer.send
40
64
  const bootstrapServers = this._brokers
65
+ const cluster = clientToCluster.get(producer)
41
66
 
42
- const kafkaClusterIdPromise = getKafkaClusterId(this)
43
-
44
- producer.send = function () {
45
- const wrappedSend = (clusterId) => {
46
- const { topic, messages = [] } = arguments[0]
47
-
48
- const ctx = {
49
- bootstrapServers,
50
- clusterId,
51
- disableHeaderInjection: disabledHeaderWeakSet.has(producer),
52
- messages,
53
- topic,
54
- }
67
+ producer.send = function (...args) {
68
+ if (!producerStartCh.hasSubscribers) {
69
+ return originalSend.apply(this, args)
70
+ }
55
71
 
56
- for (const message of messages) {
57
- if (message !== null && typeof message === 'object' && !ctx.disableHeaderInjection) {
58
- message.headers = message.headers || {}
59
- }
60
- }
72
+ // Fast path: kafkajs has fetched metadata, so clusterId is already on
73
+ // the broker pool.
74
+ const metadata = cluster?.brokerPool?.metadata
75
+ if (metadata) {
76
+ return runSend.call(this, args, metadata.clusterId)
77
+ }
61
78
 
62
- return producerStartCh.runStores(ctx, () => {
63
- try {
64
- const result = send.apply(this, arguments)
65
- result.then(
66
- (res) => {
67
- ctx.result = res
68
- producerFinishCh.publish(ctx)
69
- producerCommitCh.publish(ctx)
70
- },
71
- (err) => {
72
- ctx.error = err
73
- if (err) {
74
- // Fixes bug where we would inject message headers for kafka brokers that don't support headers
75
- // (version <0.11). On the error, we disable header injection.
76
- // Unfortunately the error name / type is not more specific.
77
- // This approach is implemented by other tracers as well.
78
- if (err.name === 'KafkaJSProtocolError' && err.type === 'UNKNOWN') {
79
- disabledHeaderWeakSet.add(producer)
80
- log.error(
81
- // eslint-disable-next-line @stylistic/max-len
82
- 'Kafka Broker responded with UNKNOWN_SERVER_ERROR (-1). Please look at broker logs for more information. Tracer message header injection for Kafka is disabled.'
83
- )
84
- }
85
- producerErrorCh.publish(err)
86
- }
87
- producerFinishCh.publish(ctx)
88
- })
79
+ // Slow path, taken at most once per producer connect cycle. Prime the
80
+ // metadata fetch kafkajs's send would do internally a few stack frames
81
+ // later. `sharedPromiseTo` collapses our call and kafkajs's call into a
82
+ // single round trip, so total latency is unchanged.
83
+ if (typeof cluster?.refreshMetadataIfNecessary !== 'function') {
84
+ return runSend.call(this, args)
85
+ }
86
+ return cluster.refreshMetadataIfNecessary().then(
87
+ () => runSend.call(this, args, cluster.brokerPool?.metadata?.clusterId),
88
+ () => runSend.call(this, args)
89
+ )
90
+ }
89
91
 
90
- return result
91
- } catch (e) {
92
- ctx.error = e
93
- producerErrorCh.publish(ctx)
94
- producerFinishCh.publish(ctx)
95
- throw e
96
- }
97
- })
92
+ function runSend (args, clusterId) {
93
+ const arg0 = args[0]
94
+ const topic = arg0?.topic
95
+ const inputMessages = Array.isArray(arg0?.messages) ? arg0.messages : []
96
+ const disableHeaderInjection = disabledHeaderWeakSet.has(producer)
97
+
98
+ // Hand kafkajs and the plugin a shallow clone so injection writes to
99
+ // tracer-owned objects instead of the caller's. With injection
100
+ // disabled the clone must not seed `headers: {}` either: brokers that
101
+ // reject any header field cannot recover otherwise.
102
+ let messages = inputMessages
103
+ if (inputMessages.length > 0) {
104
+ messages = cloneMessages(inputMessages, !disableHeaderInjection)
105
+ args[0] = { ...arg0, messages }
98
106
  }
99
107
 
100
- if (isPromise(kafkaClusterIdPromise)) {
101
- // promise is not resolved
102
- return kafkaClusterIdPromise.then((clusterId) => {
103
- return wrappedSend(clusterId)
104
- })
108
+ const ctx = {
109
+ bootstrapServers,
110
+ clusterId,
111
+ disableHeaderInjection,
112
+ messages,
113
+ topic,
105
114
  }
106
115
 
107
- // promise is already resolved
108
- return wrappedSend(kafkaClusterIdPromise)
116
+ return producerStartCh.runStores(ctx, () => {
117
+ try {
118
+ const result = originalSend.apply(this, args)
119
+ result.then(
120
+ (res) => {
121
+ ctx.result = res
122
+ producerFinishCh.publish(ctx)
123
+ producerCommitCh.publish(ctx)
124
+ },
125
+ (error) => {
126
+ ctx.error = error
127
+ if (error) {
128
+ if (error.name === 'KafkaJSProtocolError' && error.type === 'UNKNOWN') {
129
+ disabledHeaderWeakSet.add(producer)
130
+ log.error(
131
+ // eslint-disable-next-line @stylistic/max-len
132
+ 'Kafka Broker responded with UNKNOWN_SERVER_ERROR (-1). Please look at broker logs for more information. Tracer message header injection for Kafka is disabled.'
133
+ )
134
+ }
135
+ producerErrorCh.publish(error)
136
+ }
137
+ producerFinishCh.publish(ctx)
138
+ }
139
+ )
140
+ return result
141
+ } catch (error) {
142
+ ctx.error = error
143
+ producerErrorCh.publish(ctx)
144
+ producerFinishCh.publish(ctx)
145
+ throw error
146
+ }
147
+ })
109
148
  }
149
+
110
150
  return producer
111
151
  })
112
152
 
113
- shimmer.wrap(Kafka.prototype, 'consumer', createConsumer => function () {
153
+ shimmer.wrap(Kafka.prototype, 'consumer', createConsumer => function (...args) {
114
154
  if (!consumerStartCh.hasSubscribers) {
115
- return createConsumer.apply(this, arguments)
155
+ return createConsumer.apply(this, args)
116
156
  }
117
157
 
118
- const kafkaClusterIdPromise = getKafkaClusterId(this)
119
- let resolvedClusterId = null
158
+ const consumer = createConsumer.apply(this, arguments)
159
+ const cluster = clientToCluster.get(consumer)
160
+ const groupId = arguments[0].groupId
161
+
162
+ const readClusterId = () => cluster?.brokerPool?.metadata?.clusterId
120
163
 
121
- const eachMessageExtractor = (args, clusterId) => {
164
+ const eachMessageExtractor = (args) => {
122
165
  const { topic, partition, message } = args[0]
123
- return { topic, partition, message, groupId, clusterId }
166
+ return { topic, partition, message, groupId, clusterId: readClusterId() }
124
167
  }
125
168
 
126
- const eachBatchExtractor = (args, clusterId) => {
169
+ const eachBatchExtractor = (args) => {
127
170
  const { batch } = args[0]
128
171
  const { topic, partition, messages } = batch
129
- return { topic, partition, messages, groupId, clusterId }
172
+ return { topic, partition, messages, groupId, clusterId: readClusterId() }
130
173
  }
131
174
 
132
- const consumer = createConsumer.apply(this, arguments)
133
-
134
175
  consumer.on(consumer.events.COMMIT_OFFSETS, (event) => {
135
176
  const { payload: { groupId: commitGroupId, topics } } = event
177
+ const clusterId = readClusterId()
136
178
  const commitList = []
137
179
  for (const { topic, partitions } of topics) {
138
180
  for (const { partition, offset } of partitions) {
@@ -141,7 +183,7 @@ addHook({ name: 'kafkajs', file: 'src/index.js', versions: ['>=1.4'] }, (BaseKaf
141
183
  partition,
142
184
  offset,
143
185
  topic,
144
- clusterId: resolvedClusterId,
186
+ clusterId,
145
187
  })
146
188
  }
147
189
  }
@@ -149,118 +191,67 @@ addHook({ name: 'kafkajs', file: 'src/index.js', versions: ['>=1.4'] }, (BaseKaf
149
191
  })
150
192
 
151
193
  const run = consumer.run
152
- const groupId = arguments[0].groupId
153
194
 
154
195
  consumer.run = function ({ eachMessage, eachBatch, ...runArgs }) {
155
- const wrapConsume = (clusterId) => {
156
- // In kafkajs COMMIT_OFFSETS always happens in the context of one synchronous run
157
- // So this will always reference a correct cluster id
158
- resolvedClusterId = clusterId
159
- return run({
160
- eachMessage: wrappedCallback(
161
- eachMessage,
162
- consumerStartCh,
163
- consumerFinishCh,
164
- consumerErrorCh,
165
- eachMessageExtractor,
166
- clusterId
167
- ),
168
- eachBatch: wrappedCallback(
169
- eachBatch,
170
- batchConsumerStartCh,
171
- batchConsumerFinishCh,
172
- batchConsumerErrorCh,
173
- eachBatchExtractor,
174
- clusterId
175
- ),
176
- ...runArgs,
177
- })
178
- }
179
-
180
- if (isPromise(kafkaClusterIdPromise)) {
181
- // promise is not resolved
182
- return kafkaClusterIdPromise.then((clusterId) => {
183
- return wrapConsume(clusterId)
184
- })
185
- }
186
-
187
- // promise is already resolved
188
- return wrapConsume(kafkaClusterIdPromise)
196
+ return run({
197
+ eachMessage: wrappedCallback(
198
+ eachMessage,
199
+ consumerStartCh,
200
+ consumerFinishCh,
201
+ consumerErrorCh,
202
+ eachMessageExtractor
203
+ ),
204
+ eachBatch: wrappedCallback(
205
+ eachBatch,
206
+ batchConsumerStartCh,
207
+ batchConsumerFinishCh,
208
+ batchConsumerErrorCh,
209
+ eachBatchExtractor
210
+ ),
211
+ ...runArgs,
212
+ })
189
213
  }
214
+
190
215
  return consumer
191
216
  })
217
+
192
218
  return Kafka
193
219
  })
194
220
 
195
- const wrappedCallback = (fn, startCh, finishCh, errorCh, extractArgs, clusterId) => {
196
- return typeof fn === 'function'
197
- ? function (...args) {
198
- const extractedArgs = extractArgs(args, clusterId)
199
- const ctx = {
200
- extractedArgs,
201
- }
221
+ const wrappedCallback = (fn, startCh, finishCh, errorCh, extractArgs) => {
222
+ if (typeof fn !== 'function') return fn
223
+ return function (...args) {
224
+ const ctx = {
225
+ extractedArgs: extractArgs(args),
226
+ }
202
227
 
203
- return startCh.runStores(ctx, () => {
204
- try {
205
- const result = fn.apply(this, args)
206
- if (result && typeof result.then === 'function') {
207
- result.then(
208
- (res) => {
209
- ctx.result = res
210
- finishCh.publish(ctx)
211
- },
212
- (err) => {
213
- ctx.error = err
214
- if (err) {
215
- errorCh.publish(ctx)
216
- }
217
- finishCh.publish(ctx)
218
- })
219
- } else {
220
- finishCh.publish(ctx)
221
- }
222
- return result
223
- } catch (e) {
224
- ctx.error = e
225
- errorCh.publish(ctx)
228
+ return startCh.runStores(ctx, () => {
229
+ try {
230
+ const result = fn.apply(this, args)
231
+ if (result && typeof result.then === 'function') {
232
+ result.then(
233
+ (res) => {
234
+ ctx.result = res
235
+ finishCh.publish(ctx)
236
+ },
237
+ (error) => {
238
+ ctx.error = error
239
+ if (error) {
240
+ errorCh.publish(ctx)
241
+ }
242
+ finishCh.publish(ctx)
243
+ }
244
+ )
245
+ } else {
226
246
  finishCh.publish(ctx)
227
- throw e
228
247
  }
229
- })
230
- }
231
- : fn
232
- }
233
-
234
- const getKafkaClusterId = (kafka) => {
235
- if (kafka._ddKafkaClusterId) {
236
- return kafka._ddKafkaClusterId
237
- }
238
-
239
- if (!kafka.admin) {
240
- return null
241
- }
242
-
243
- const admin = kafka.admin()
244
-
245
- if (!admin.describeCluster) {
246
- return null
247
- }
248
-
249
- return admin.connect()
250
- .then(() => {
251
- return admin.describeCluster()
252
- })
253
- .then((clusterInfo) => {
254
- const clusterId = clusterInfo?.clusterId
255
- kafka._ddKafkaClusterId = clusterId
256
- admin.disconnect()
257
- return clusterId
258
- })
259
- .catch((error) => {
260
- throw error
248
+ return result
249
+ } catch (error) {
250
+ ctx.error = error
251
+ errorCh.publish(ctx)
252
+ finishCh.publish(ctx)
253
+ throw error
254
+ }
261
255
  })
262
- }
263
-
264
- function isPromise (obj) {
265
- return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'
256
+ }
266
257
  }
@@ -32,41 +32,41 @@ addHook({
32
32
  versions: ['>=2'],
33
33
  file: 'lib/knex-builder/Knex.js',
34
34
  }, Knex => {
35
- shimmer.wrap(Knex.Client.prototype, 'raw', raw => function () {
35
+ shimmer.wrap(Knex.Client.prototype, 'raw', raw => function (...args) {
36
36
  if (!startRawQueryCh.hasSubscribers) {
37
- return raw.apply(this, arguments)
37
+ return raw.apply(this, args)
38
38
  }
39
39
 
40
- const sql = arguments[0]
40
+ const sql = args[0]
41
41
 
42
42
  // Skip query done by Knex to get the value used for undefined
43
43
  if (sql === 'DEFAULT') {
44
- return raw.apply(this, arguments)
44
+ return raw.apply(this, args)
45
45
  }
46
46
 
47
47
  const context = { sql, dialect: this.dialect }
48
48
  return startRawQueryCh.runStores(context, () => {
49
- const rawResult = raw.apply(this, arguments)
50
- shimmer.wrap(rawResult, 'then', originalThen => function () {
49
+ const rawResult = raw.apply(this, args)
50
+ shimmer.wrap(rawResult, 'then', originalThen => function (...args) {
51
51
  return rawQuerySubscribes.runStores(context, () => {
52
- arguments[0] = wrapCallbackWithFinish(arguments[0], finish, context)
53
- if (arguments[1]) arguments[1] = wrapCallbackWithFinish(arguments[1], finish, context)
52
+ args[0] = wrapCallbackWithFinish(args[0], finish, context)
53
+ if (args[1]) args[1] = wrapCallbackWithFinish(args[1], finish, context)
54
54
 
55
- const originalThenResult = originalThen.apply(this, arguments)
55
+ const originalThenResult = originalThen.apply(this, args)
56
56
 
57
- shimmer.wrap(originalThenResult, 'catch', originalCatch => function () {
58
- arguments[0] = wrapCallbackWithFinish(arguments[0], finish, context)
59
- return originalCatch.apply(this, arguments)
57
+ shimmer.wrap(originalThenResult, 'catch', originalCatch => function (...args) {
58
+ args[0] = wrapCallbackWithFinish(args[0], finish, context)
59
+ return originalCatch.apply(this, args)
60
60
  })
61
61
 
62
62
  return originalThenResult
63
63
  })
64
64
  })
65
65
 
66
- shimmer.wrap(rawResult, 'asCallback', originalAsCallback => function () {
66
+ shimmer.wrap(rawResult, 'asCallback', originalAsCallback => function (...args) {
67
67
  return rawQuerySubscribes.runStores(context, () => {
68
- arguments[0] = wrapCallbackWithFinish(arguments[0], finish, context)
69
- return originalAsCallback.apply(this, arguments)
68
+ args[0] = wrapCallbackWithFinish(args[0], finish, context)
69
+ return originalAsCallback.apply(this, args)
70
70
  })
71
71
  })
72
72
 
@@ -80,7 +80,7 @@ addHook({
80
80
  function wrapCallbackWithFinish (callback, finish, context) {
81
81
  if (typeof callback !== 'function') return callback
82
82
 
83
- return shimmer.wrapFunction(callback, callback => function () {
84
- finish(context, () => callback.apply(this, arguments))
83
+ return shimmer.wrapFunction(callback, callback => function (...args) {
84
+ finish(context, () => callback.apply(this, args))
85
85
  })
86
86
  }
@@ -14,8 +14,8 @@ const routeChannel = channel('apm:koa:request:route')
14
14
  const originals = new WeakMap()
15
15
 
16
16
  function wrapCallback (callback) {
17
- return function callbackWithTrace () {
18
- const handleRequest = callback.apply(this, arguments)
17
+ return function callbackWithTrace (...args) {
18
+ const handleRequest = callback.apply(this, args)
19
19
 
20
20
  if (typeof handleRequest !== 'function') return handleRequest
21
21
 
@@ -28,14 +28,14 @@ function wrapCallback (callback) {
28
28
  }
29
29
 
30
30
  function wrapUse (use) {
31
- return function useWithTrace () {
32
- const result = use.apply(this, arguments)
31
+ return function useWithTrace (...args) {
32
+ const result = use.apply(this, args)
33
33
 
34
- if (!Array.isArray(this.middleware)) return result
34
+ if (Array.isArray(this.middleware)) {
35
+ const fn = this.middleware.pop()
35
36
 
36
- const fn = this.middleware.pop()
37
-
38
- this.middleware.push(wrapMiddleware(fn))
37
+ this.middleware.push(wrapMiddleware(fn))
38
+ }
39
39
 
40
40
  return result
41
41
  }
@@ -54,8 +54,8 @@ function wrapRegister (register) {
54
54
  }
55
55
 
56
56
  function wrapRouterUse (use) {
57
- return function useWithTrace () {
58
- const router = use.apply(this, arguments)
57
+ return function useWithTrace (...args) {
58
+ const router = use.apply(this, args)
59
59
 
60
60
  for (const layer of router.stack) {
61
61
  wrapStack(layer)
@@ -144,10 +144,10 @@ function fulfill (ctx, error) {
144
144
  }
145
145
 
146
146
  function wrapNext (req, next) {
147
- return shimmer.wrapFunction(next, next => function () {
147
+ return shimmer.wrapFunction(next, next => function (...args) {
148
148
  nextChannel.publish({ req })
149
149
 
150
- return next.apply(this, arguments)
150
+ return next.apply(this, args)
151
151
  })
152
152
  }
153
153
 
@@ -71,12 +71,12 @@ addHook({ name: 'ldapjs', versions: ['>=2'] }, ldapjs => {
71
71
  return search.apply(this, arguments)
72
72
  })
73
73
 
74
- shimmer.wrap(ldapjs.Client.prototype, '_send', _send => function () {
75
- const callbackIndex = getCallbackArgIndex(arguments)
74
+ shimmer.wrap(ldapjs.Client.prototype, '_send', _send => function (...args) {
75
+ const callbackIndex = getCallbackArgIndex(args)
76
76
  if (callbackIndex > -1) {
77
- const callback = arguments[callbackIndex]
77
+ const callback = args[callbackIndex]
78
78
  // eslint-disable-next-line n/handle-callback-err
79
- arguments[callbackIndex] = shimmer.wrapFunction(callback, callback => function (err, corkedEmitter) {
79
+ args[callbackIndex] = shimmer.wrapFunction(callback, callback => function (err, corkedEmitter) {
80
80
  if (corkedEmitter !== null && typeof corkedEmitter === 'object' && typeof corkedEmitter.on === 'function') {
81
81
  wrapEmitter(corkedEmitter)
82
82
  }
@@ -84,7 +84,7 @@ addHook({ name: 'ldapjs', versions: ['>=2'] }, ldapjs => {
84
84
  })
85
85
  }
86
86
 
87
- return _send.apply(this, arguments)
87
+ return _send.apply(this, args)
88
88
  })
89
89
 
90
90
  shimmer.wrap(ldapjs.Client.prototype, 'bind', bind => function (dn, password, controls, callback) {
@@ -69,8 +69,8 @@ function wrapDispatchFunc (dispatchFunc) {
69
69
  // Also wrap end() as fallback
70
70
  const originalEnd = res.end
71
71
  if (originalEnd) {
72
- res.end = function wrappedEnd () {
73
- const result = originalEnd.apply(this, arguments)
72
+ res.end = function wrappedEnd (...args) {
73
+ const result = originalEnd.apply(this, args)
74
74
  // Trigger finish if events don't fire
75
75
  setImmediate(onFinish)
76
76
  return result
@@ -4,10 +4,10 @@ const shimmer = require('../../datadog-shimmer')
4
4
  const { addHook, AsyncResource } = require('./helpers/instrument')
5
5
 
6
6
  function wrapRequest (original) {
7
- return function () {
8
- const id = arguments.length - 1
9
- arguments[id] = AsyncResource.bind(arguments[id])
10
- return original.apply(this, arguments)
7
+ return function (...args) {
8
+ const id = args.length - 1
9
+ args[id] = AsyncResource.bind(args[id])
10
+ return original.apply(this, args)
11
11
  }
12
12
  }
13
13
 
@@ -12,13 +12,13 @@ addHook({ name: 'lodash', versions: ['>=4'] }, lodash => {
12
12
  lodash,
13
13
  instrumentedLodashFn,
14
14
  lodashFn => {
15
- return function () {
15
+ return function (...args) {
16
16
  if (!lodashOperationCh.hasSubscribers) {
17
- return lodashFn.apply(this, arguments)
17
+ return lodashFn.apply(this, args)
18
18
  }
19
19
 
20
- const result = lodashFn.apply(this, arguments)
21
- const message = { operation: lodashFn.name, arguments, result }
20
+ const result = lodashFn.apply(this, args)
21
+ const message = { operation: lodashFn.name, arguments: args, result }
22
22
  lodashOperationCh.publish(message)
23
23
 
24
24
  return message.result
@@ -12,13 +12,13 @@ const errorCh = channel('apm:mariadb:query:error')
12
12
  const skipCh = channel('apm:mariadb:pool:skip')
13
13
 
14
14
  function wrapCommandStart (start, ctx) {
15
- return shimmer.wrapFunction(start, start => function () {
16
- if (!startCh.hasSubscribers) return start.apply(this, arguments)
15
+ return shimmer.wrapFunction(start, start => function (...args) {
16
+ if (!startCh.hasSubscribers) return start.apply(this, args)
17
17
 
18
18
  const { reject, resolve } = this
19
19
  shimmer.wrap(this, 'resolve', function wrapResolve () {
20
- return function () {
21
- return finishCh.runStores(ctx, resolve, this, ...arguments)
20
+ return function (...args) {
21
+ return finishCh.runStores(ctx, resolve, this, ...args)
22
22
  }
23
23
  })
24
24
 
@@ -32,7 +32,7 @@ function wrapCommandStart (start, ctx) {
32
32
  }
33
33
  })
34
34
 
35
- return startCh.runStores(ctx, start, this, ...arguments)
35
+ return startCh.runStores(ctx, start, this, ...args)
36
36
  })
37
37
  }
38
38
 
@@ -128,25 +128,25 @@ function wrapPoolBase (PoolBase) {
128
128
  // so instead we just skip instrumentation completely to avoid memory leaks
129
129
  // and/or orphan spans.
130
130
  function wrapPoolMethod (createConnection) {
131
- return function () {
132
- return skipCh.runStores({}, createConnection, this, ...arguments)
131
+ return function (...args) {
132
+ return skipCh.runStores({}, createConnection, this, ...args)
133
133
  }
134
134
  }
135
135
 
136
136
  function wrapPoolGetConnectionMethod (getConnection) {
137
- return function wrappedGetConnection () {
138
- const cb = arguments[arguments.length - 1]
139
- if (typeof cb !== 'function') return getConnection.apply(this, arguments)
137
+ return function wrappedGetConnection (...args) {
138
+ const cb = args[args.length - 1]
139
+ if (typeof cb !== 'function') return getConnection.apply(this, args)
140
140
 
141
141
  const ctx = {}
142
142
 
143
- arguments[arguments.length - 1] = function () {
144
- return connectionFinishCh.runStores(ctx, cb, this, ...arguments)
143
+ args[args.length - 1] = function (...args) {
144
+ return connectionFinishCh.runStores(ctx, cb, this, ...args)
145
145
  }
146
146
 
147
147
  connectionStartCh.publish(ctx)
148
148
 
149
- return getConnection.apply(this, arguments)
149
+ return getConnection.apply(this, args)
150
150
  }
151
151
  }
152
152