dd-trace 5.103.0 → 5.105.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 (213) hide show
  1. package/LICENSE-3rdparty.csv +90 -102
  2. package/index.d.ts +107 -6
  3. package/package.json +18 -17
  4. package/packages/datadog-core/src/storage.js +1 -1
  5. package/packages/datadog-instrumentations/src/aerospike.js +1 -1
  6. package/packages/datadog-instrumentations/src/ai.js +8 -7
  7. package/packages/datadog-instrumentations/src/aws-sdk.js +15 -2
  8. package/packages/datadog-instrumentations/src/azure-cosmos.js +7 -0
  9. package/packages/datadog-instrumentations/src/azure-functions.js +3 -0
  10. package/packages/datadog-instrumentations/src/cassandra-driver.js +5 -2
  11. package/packages/datadog-instrumentations/src/cucumber.js +181 -35
  12. package/packages/datadog-instrumentations/src/dns.js +54 -18
  13. package/packages/datadog-instrumentations/src/elasticsearch.js +4 -4
  14. package/packages/datadog-instrumentations/src/fastify.js +142 -82
  15. package/packages/datadog-instrumentations/src/graphql.js +188 -67
  16. package/packages/datadog-instrumentations/src/grpc/client.js +48 -32
  17. package/packages/datadog-instrumentations/src/helpers/ai-messages.js +322 -14
  18. package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +1 -1
  19. package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -0
  20. package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -1
  21. package/packages/datadog-instrumentations/src/helpers/kafka.js +17 -0
  22. package/packages/datadog-instrumentations/src/helpers/openai-ai-guard.js +269 -0
  23. package/packages/datadog-instrumentations/src/helpers/promise-instrumentor.js +42 -0
  24. package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
  25. package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +3 -2
  26. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +19 -6
  27. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/azure-cosmos.js +50 -0
  28. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +2 -0
  29. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/langgraph.js +4 -2
  30. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +85 -0
  31. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +31 -229
  32. package/packages/datadog-instrumentations/src/hono.js +54 -3
  33. package/packages/datadog-instrumentations/src/http/client.js +2 -2
  34. package/packages/datadog-instrumentations/src/http/server.js +9 -4
  35. package/packages/datadog-instrumentations/src/ioredis.js +3 -3
  36. package/packages/datadog-instrumentations/src/jest/coverage-backfill.js +163 -0
  37. package/packages/datadog-instrumentations/src/jest.js +390 -183
  38. package/packages/datadog-instrumentations/src/kafkajs.js +140 -17
  39. package/packages/datadog-instrumentations/src/mariadb.js +1 -1
  40. package/packages/datadog-instrumentations/src/memcached.js +2 -1
  41. package/packages/datadog-instrumentations/src/mocha/main.js +399 -107
  42. package/packages/datadog-instrumentations/src/mocha/utils.js +48 -8
  43. package/packages/datadog-instrumentations/src/mongodb-core.js +1 -1
  44. package/packages/datadog-instrumentations/src/mongoose.js +10 -12
  45. package/packages/datadog-instrumentations/src/mysql.js +2 -2
  46. package/packages/datadog-instrumentations/src/mysql2.js +1 -1
  47. package/packages/datadog-instrumentations/src/nats.js +182 -0
  48. package/packages/datadog-instrumentations/src/nyc.js +38 -1
  49. package/packages/datadog-instrumentations/src/openai.js +33 -18
  50. package/packages/datadog-instrumentations/src/oracledb.js +6 -1
  51. package/packages/datadog-instrumentations/src/pg.js +1 -1
  52. package/packages/datadog-instrumentations/src/pino.js +17 -5
  53. package/packages/datadog-instrumentations/src/playwright.js +537 -297
  54. package/packages/datadog-instrumentations/src/router.js +80 -34
  55. package/packages/datadog-instrumentations/src/stripe.js +1 -1
  56. package/packages/datadog-instrumentations/src/vitest.js +246 -149
  57. package/packages/datadog-plugin-avsc/src/schema_iterator.js +1 -1
  58. package/packages/datadog-plugin-azure-cosmos/src/index.js +144 -0
  59. package/packages/datadog-plugin-azure-event-hubs/src/producer.js +1 -1
  60. package/packages/datadog-plugin-azure-functions/src/index.js +5 -2
  61. package/packages/datadog-plugin-azure-service-bus/src/producer.js +1 -1
  62. package/packages/datadog-plugin-bunyan/src/index.js +28 -0
  63. package/packages/datadog-plugin-cucumber/src/index.js +17 -3
  64. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +223 -45
  65. package/packages/datadog-plugin-cypress/src/support.js +69 -1
  66. package/packages/datadog-plugin-dns/src/lookup.js +8 -6
  67. package/packages/datadog-plugin-elasticsearch/src/index.js +28 -8
  68. package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +1 -1
  69. package/packages/datadog-plugin-graphql/src/execute.js +2 -0
  70. package/packages/datadog-plugin-graphql/src/resolve.js +64 -67
  71. package/packages/datadog-plugin-graphql/src/utils.js +4 -1
  72. package/packages/datadog-plugin-http/src/server.js +40 -15
  73. package/packages/datadog-plugin-jest/src/index.js +11 -3
  74. package/packages/datadog-plugin-jest/src/util.js +15 -8
  75. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +1 -1
  76. package/packages/datadog-plugin-kafkajs/src/producer.js +35 -0
  77. package/packages/datadog-plugin-langgraph/src/stream.js +1 -1
  78. package/packages/datadog-plugin-mocha/src/index.js +19 -4
  79. package/packages/datadog-plugin-mongodb-core/src/index.js +311 -35
  80. package/packages/datadog-plugin-nats/src/consumer.js +43 -0
  81. package/packages/datadog-plugin-nats/src/index.js +20 -0
  82. package/packages/datadog-plugin-nats/src/producer.js +62 -0
  83. package/packages/datadog-plugin-nats/src/util.js +33 -0
  84. package/packages/datadog-plugin-next/src/index.js +5 -3
  85. package/packages/datadog-plugin-openai/src/tracing.js +15 -2
  86. package/packages/datadog-plugin-oracledb/src/index.js +13 -2
  87. package/packages/datadog-plugin-pino/src/index.js +42 -0
  88. package/packages/datadog-plugin-playwright/src/index.js +4 -4
  89. package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +1 -1
  90. package/packages/datadog-plugin-redis/src/index.js +37 -2
  91. package/packages/datadog-plugin-rhea/src/producer.js +1 -1
  92. package/packages/datadog-plugin-router/src/index.js +33 -44
  93. package/packages/datadog-plugin-selenium/src/index.js +1 -1
  94. package/packages/datadog-plugin-undici/src/index.js +19 -0
  95. package/packages/datadog-plugin-vitest/src/index.js +24 -20
  96. package/packages/datadog-plugin-winston/src/index.js +30 -0
  97. package/packages/datadog-shimmer/src/shimmer.js +49 -21
  98. package/packages/dd-trace/src/aiguard/index.js +1 -1
  99. package/packages/dd-trace/src/aiguard/sdk.js +1 -1
  100. package/packages/dd-trace/src/appsec/api_security_sampler.js +1 -1
  101. package/packages/dd-trace/src/appsec/blocking.js +2 -2
  102. package/packages/dd-trace/src/appsec/index.js +11 -4
  103. package/packages/dd-trace/src/appsec/reporter.js +24 -11
  104. package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -1
  105. package/packages/dd-trace/src/appsec/sdk/utils.js +1 -1
  106. package/packages/dd-trace/src/appsec/user_tracking.js +5 -4
  107. package/packages/dd-trace/src/baggage.js +7 -1
  108. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +0 -1
  109. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +25 -13
  110. package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -1
  111. package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +5 -3
  112. package/packages/dd-trace/src/ci-visibility/test-optimization-cache.js +70 -6
  113. package/packages/dd-trace/src/config/generated-config-types.d.ts +7 -2
  114. package/packages/dd-trace/src/config/supported-configurations.json +36 -8
  115. package/packages/dd-trace/src/crashtracking/crashtracker.js +15 -3
  116. package/packages/dd-trace/src/datastreams/context.js +4 -2
  117. package/packages/dd-trace/src/datastreams/writer.js +2 -4
  118. package/packages/dd-trace/src/debugger/devtools_client/condition.js +5 -8
  119. package/packages/dd-trace/src/encode/0.4.js +124 -108
  120. package/packages/dd-trace/src/encode/0.5.js +114 -26
  121. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +57 -42
  122. package/packages/dd-trace/src/encode/agentless-json.js +4 -2
  123. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +32 -13
  124. package/packages/dd-trace/src/encode/span-stats.js +16 -16
  125. package/packages/dd-trace/src/encode/tags-processors.js +16 -0
  126. package/packages/dd-trace/src/exporters/common/agents.js +3 -1
  127. package/packages/dd-trace/src/exporters/common/request.js +3 -1
  128. package/packages/dd-trace/src/id.js +17 -4
  129. package/packages/dd-trace/src/lambda/handler.js +2 -4
  130. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -1
  131. package/packages/dd-trace/src/llmobs/plugins/genai/index.js +1 -1
  132. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +1 -1
  133. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +9 -7
  134. package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
  135. package/packages/dd-trace/src/llmobs/plugins/openai/index.js +1 -1
  136. package/packages/dd-trace/src/llmobs/sdk.js +10 -16
  137. package/packages/dd-trace/src/llmobs/span_processor.js +3 -3
  138. package/packages/dd-trace/src/llmobs/tagger.js +9 -1
  139. package/packages/dd-trace/src/llmobs/telemetry.js +1 -1
  140. package/packages/dd-trace/src/llmobs/util.js +66 -3
  141. package/packages/dd-trace/src/log/index.js +1 -1
  142. package/packages/dd-trace/src/log/writer.js +3 -1
  143. package/packages/dd-trace/src/msgpack/chunk.js +394 -10
  144. package/packages/dd-trace/src/msgpack/index.js +96 -2
  145. package/packages/dd-trace/src/noop/span.js +3 -1
  146. package/packages/dd-trace/src/openfeature/encoding.js +70 -0
  147. package/packages/dd-trace/src/openfeature/flagging_provider.js +20 -0
  148. package/packages/dd-trace/src/openfeature/span-enrichment-hook.js +143 -0
  149. package/packages/dd-trace/src/openfeature/span-enrichment.js +149 -0
  150. package/packages/dd-trace/src/openfeature/writers/exposures.js +51 -20
  151. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -1
  152. package/packages/dd-trace/src/opentelemetry/span-helpers.js +4 -3
  153. package/packages/dd-trace/src/opentelemetry/span.js +1 -1
  154. package/packages/dd-trace/src/opentracing/propagation/log.js +18 -7
  155. package/packages/dd-trace/src/opentracing/propagation/text_map.js +62 -67
  156. package/packages/dd-trace/src/opentracing/span.js +59 -19
  157. package/packages/dd-trace/src/opentracing/span_context.js +49 -0
  158. package/packages/dd-trace/src/plugins/apollo.js +3 -1
  159. package/packages/dd-trace/src/plugins/ci_plugin.js +23 -33
  160. package/packages/dd-trace/src/plugins/database.js +7 -6
  161. package/packages/dd-trace/src/plugins/index.js +4 -0
  162. package/packages/dd-trace/src/plugins/log_injection.js +56 -0
  163. package/packages/dd-trace/src/plugins/log_plugin.js +3 -46
  164. package/packages/dd-trace/src/plugins/outbound.js +1 -1
  165. package/packages/dd-trace/src/plugins/plugin.js +15 -17
  166. package/packages/dd-trace/src/plugins/tracing.js +48 -8
  167. package/packages/dd-trace/src/plugins/util/git.js +3 -1
  168. package/packages/dd-trace/src/plugins/util/test.js +318 -13
  169. package/packages/dd-trace/src/plugins/util/web.js +89 -64
  170. package/packages/dd-trace/src/priority_sampler.js +2 -2
  171. package/packages/dd-trace/src/profiling/profiler.js +2 -2
  172. package/packages/dd-trace/src/profiling/profilers/wall.js +10 -4
  173. package/packages/dd-trace/src/sampling_rule.js +7 -7
  174. package/packages/dd-trace/src/scope.js +7 -5
  175. package/packages/dd-trace/src/service-naming/extra-services.js +14 -0
  176. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +10 -0
  177. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +8 -0
  178. package/packages/dd-trace/src/service-naming/source-resolver.js +46 -0
  179. package/packages/dd-trace/src/span_format.js +190 -58
  180. package/packages/dd-trace/src/spanleak.js +1 -1
  181. package/packages/dd-trace/src/standalone/index.js +3 -3
  182. package/packages/dd-trace/src/tagger.js +0 -2
  183. package/vendor/dist/@apm-js-collab/code-transformer/index.js +70 -39
  184. package/vendor/dist/@datadog/sketches-js/LICENSE +10 -36
  185. package/vendor/dist/@datadog/sketches-js/index.js +1 -1
  186. package/vendor/dist/protobufjs/index.js +1 -1
  187. package/vendor/dist/protobufjs/minimal/index.js +1 -1
  188. package/packages/dd-trace/src/msgpack/encoder.js +0 -308
  189. package/packages/dd-trace/src/plugins/structured_log_plugin.js +0 -9
  190. package/vendor/dist/opentracing/LICENSE +0 -201
  191. package/vendor/dist/opentracing/binary_carrier.d.ts +0 -11
  192. package/vendor/dist/opentracing/constants.d.ts +0 -61
  193. package/vendor/dist/opentracing/examples/demo/demo.d.ts +0 -2
  194. package/vendor/dist/opentracing/ext/tags.d.ts +0 -90
  195. package/vendor/dist/opentracing/functions.d.ts +0 -20
  196. package/vendor/dist/opentracing/global_tracer.d.ts +0 -14
  197. package/vendor/dist/opentracing/index.d.ts +0 -12
  198. package/vendor/dist/opentracing/index.js +0 -1
  199. package/vendor/dist/opentracing/mock_tracer/index.d.ts +0 -5
  200. package/vendor/dist/opentracing/mock_tracer/mock_context.d.ts +0 -13
  201. package/vendor/dist/opentracing/mock_tracer/mock_report.d.ts +0 -16
  202. package/vendor/dist/opentracing/mock_tracer/mock_span.d.ts +0 -50
  203. package/vendor/dist/opentracing/mock_tracer/mock_tracer.d.ts +0 -26
  204. package/vendor/dist/opentracing/noop.d.ts +0 -8
  205. package/vendor/dist/opentracing/reference.d.ts +0 -33
  206. package/vendor/dist/opentracing/span.d.ts +0 -147
  207. package/vendor/dist/opentracing/span_context.d.ts +0 -26
  208. package/vendor/dist/opentracing/test/api_compatibility.d.ts +0 -16
  209. package/vendor/dist/opentracing/test/mocktracer_implemenation.d.ts +0 -3
  210. package/vendor/dist/opentracing/test/noop_implementation.d.ts +0 -4
  211. package/vendor/dist/opentracing/test/opentracing_api.d.ts +0 -3
  212. package/vendor/dist/opentracing/test/unittest.d.ts +0 -2
  213. package/vendor/dist/opentracing/tracer.d.ts +0 -127
@@ -8,6 +8,7 @@ const {
8
8
  addHook,
9
9
  } = require('./helpers/instrument')
10
10
  const {
11
+ brokerSupportsMessageHeaders,
11
12
  clientToCluster,
12
13
  cloneMessages,
13
14
  } = require('./helpers/kafka')
@@ -26,7 +27,7 @@ const batchConsumerStartCh = channel('apm:kafkajs:consume-batch:start')
26
27
  const batchConsumerFinishCh = channel('apm:kafkajs:consume-batch:finish')
27
28
  const batchConsumerErrorCh = channel('apm:kafkajs:consume-batch:error')
28
29
 
29
- const disabledHeaderWeakSet = new WeakSet()
30
+ const noop = () => {}
30
31
 
31
32
  addHook({ name: 'kafkajs', file: 'src/producer/index.js', versions: ['>=1.4'] }, (createProducer) =>
32
33
  shimmer.wrapFunction(createProducer, original => function wrappedCreateProducer (params) {
@@ -61,39 +62,64 @@ addHook({ name: 'kafkajs', file: 'src/index.js', versions: ['>=1.4'] }, (BaseKaf
61
62
  shimmer.wrap(Kafka.prototype, 'producer', createProducer => function () {
62
63
  const producer = createProducer.apply(this, arguments)
63
64
  const originalSend = producer.send
65
+ const originalSendBatch = producer.sendBatch
64
66
  const bootstrapServers = this._brokers
65
67
  const cluster = clientToCluster.get(producer)
66
68
 
67
- producer.send = function (...args) {
68
- if (!producerStartCh.hasSubscribers) {
69
- return originalSend.apply(this, args)
69
+ let disableHeaderInjection = false
70
+
71
+ let refreshHeaderSupport = () => {
72
+ if (!brokerSupportsMessageHeaders(cluster?.brokerPool)) {
73
+ disableHeaderInjection = true
74
+ refreshHeaderSupport = noop
75
+ log.info('kafkajs broker negotiated Produce <v3; tracer header injection disabled.')
70
76
  }
77
+ }
71
78
 
72
- // Fast path: kafkajs has fetched metadata, so clusterId is already on
73
- // the broker pool.
79
+ /**
80
+ * Resolve the negotiated clusterId once and hand it to `call`. Fast path reads
81
+ * `cluster.brokerPool.metadata` synchronously when kafkajs already fetched it.
82
+ * Slow path primes `refreshMetadataIfNecessary`, which `sharedPromiseTo`
83
+ * deduplicates with kafkajs's own internal fetch so total latency is unchanged.
84
+ *
85
+ * @param {(clusterId: string | undefined) => Promise<unknown>} call
86
+ */
87
+ const withClusterId = (call) => {
74
88
  const metadata = cluster?.brokerPool?.metadata
75
89
  if (metadata) {
76
- return runSend.call(this, args, metadata.clusterId)
90
+ refreshHeaderSupport()
91
+ return call(metadata.clusterId)
77
92
  }
78
-
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
93
  if (typeof cluster?.refreshMetadataIfNecessary !== 'function') {
84
- return runSend.call(this, args)
94
+ return call()
85
95
  }
86
96
  return cluster.refreshMetadataIfNecessary().then(
87
- () => runSend.call(this, args, cluster.brokerPool?.metadata?.clusterId),
88
- () => runSend.call(this, args)
97
+ () => {
98
+ refreshHeaderSupport()
99
+ return call(cluster.brokerPool?.metadata?.clusterId)
100
+ },
101
+ () => call()
89
102
  )
90
103
  }
91
104
 
105
+ producer.send = function (...args) {
106
+ if (!producerStartCh.hasSubscribers) {
107
+ return originalSend.apply(this, args)
108
+ }
109
+ return withClusterId((clusterId) => runSend.call(this, args, clusterId))
110
+ }
111
+
112
+ producer.sendBatch = function (...args) {
113
+ if (!producerStartCh.hasSubscribers) {
114
+ return originalSendBatch.apply(this, args)
115
+ }
116
+ return withClusterId((clusterId) => runSendBatch.call(this, args, clusterId))
117
+ }
118
+
92
119
  function runSend (args, clusterId) {
93
120
  const arg0 = args[0]
94
121
  const topic = arg0?.topic
95
122
  const inputMessages = Array.isArray(arg0?.messages) ? arg0.messages : []
96
- const disableHeaderInjection = disabledHeaderWeakSet.has(producer)
97
123
 
98
124
  // Hand kafkajs and the plugin a shallow clone so injection writes to
99
125
  // tracer-owned objects instead of the caller's. With injection
@@ -125,8 +151,13 @@ addHook({ name: 'kafkajs', file: 'src/index.js', versions: ['>=1.4'] }, (BaseKaf
125
151
  (error) => {
126
152
  ctx.error = error
127
153
  if (error) {
154
+ // Safety net for mixed-version clusters where the seed
155
+ // broker advertised Produce v3+ but the leader we shipped to
156
+ // could not parse the headers, surfacing as
157
+ // KafkaJSProtocolError UNKNOWN (server error code -1).
128
158
  if (error.name === 'KafkaJSProtocolError' && error.type === 'UNKNOWN') {
129
- disabledHeaderWeakSet.add(producer)
159
+ disableHeaderInjection = true
160
+ refreshHeaderSupport = noop
130
161
  log.error(
131
162
  // eslint-disable-next-line @stylistic/max-len
132
163
  'Kafka Broker responded with UNKNOWN_SERVER_ERROR (-1). Please look at broker logs for more information. Tracer message header injection for Kafka is disabled.'
@@ -147,6 +178,98 @@ addHook({ name: 'kafkajs', file: 'src/index.js', versions: ['>=1.4'] }, (BaseKaf
147
178
  })
148
179
  }
149
180
 
181
+ function runSendBatch (args, clusterId) {
182
+ const arg0 = args[0]
183
+ const inputTopicMessages = Array.isArray(arg0?.topicMessages) ? arg0.topicMessages : []
184
+ if (inputTopicMessages.length === 0) {
185
+ return originalSendBatch.apply(this, args)
186
+ }
187
+
188
+ // One ctx per topicMessages entry — kafkajs implements `send` as a single-entry
189
+ // `sendBatch` (`producer/messageProducer.js`), so one span per entry is the same
190
+ // unit `send` already produces. Cloning only happens for valid arrays so kafkajs
191
+ // still sees and rejects a caller's malformed `messages` field.
192
+ const outputEntries = new Array(inputTopicMessages.length)
193
+ const ctxList = []
194
+ let cloned = false
195
+ for (let i = 0; i < inputTopicMessages.length; i++) {
196
+ const entry = inputTopicMessages[i]
197
+ const topic = entry?.topic
198
+ const rawMessages = entry?.messages
199
+ let entryMessages = rawMessages
200
+ if (Array.isArray(rawMessages) && rawMessages.length > 0) {
201
+ entryMessages = cloneMessages(rawMessages, !disableHeaderInjection)
202
+ outputEntries[i] = { ...entry, messages: entryMessages }
203
+ cloned = true
204
+ } else {
205
+ outputEntries[i] = entry
206
+ }
207
+ ctxList.push({
208
+ bootstrapServers,
209
+ clusterId,
210
+ disableHeaderInjection,
211
+ messages: Array.isArray(entryMessages) ? entryMessages : [],
212
+ topic,
213
+ })
214
+ }
215
+ if (cloned) {
216
+ args[0] = { ...arg0, topicMessages: outputEntries }
217
+ }
218
+
219
+ for (const ctx of ctxList) {
220
+ producerStartCh.runStores(ctx, noop)
221
+ }
222
+
223
+ let result
224
+ try {
225
+ result = originalSendBatch.apply(this, args)
226
+ } catch (error) {
227
+ failProduceBatch(ctxList, error)
228
+ throw error
229
+ }
230
+
231
+ result.then(
232
+ (res) => {
233
+ for (const ctx of ctxList) {
234
+ ctx.result = res
235
+ producerFinishCh.publish(ctx)
236
+ }
237
+ // kafkajs returns a single aggregated response covering every topic;
238
+ // commit fires once so the plugin's `setOffset` loop runs once per
239
+ // entry of the response, not once per span.
240
+ producerCommitCh.publish(ctxList[0])
241
+ },
242
+ (error) => failProduceBatch(ctxList, error)
243
+ )
244
+
245
+ return result
246
+ }
247
+
248
+ /**
249
+ * Tag every open ctx with the shared error, then publish error + finish so the
250
+ * plugin closes each span. The mixed-version safety net (broker advertised
251
+ * Produce v3+ but the leader rejected the headers) fires at most once per
252
+ * failed batch and short-circuits subsequent sends to the disabled path.
253
+ *
254
+ * @param {Array<object>} ctxList
255
+ * @param {Error} error
256
+ */
257
+ function failProduceBatch (ctxList, error) {
258
+ if (error?.name === 'KafkaJSProtocolError' && error.type === 'UNKNOWN') {
259
+ disableHeaderInjection = true
260
+ refreshHeaderSupport = noop
261
+ log.error(
262
+ // eslint-disable-next-line @stylistic/max-len
263
+ 'Kafka Broker responded with UNKNOWN_SERVER_ERROR (-1). Please look at broker logs for more information. Tracer message header injection for Kafka is disabled.'
264
+ )
265
+ }
266
+ for (const ctx of ctxList) {
267
+ ctx.error = error
268
+ producerErrorCh.publish(ctx)
269
+ producerFinishCh.publish(ctx)
270
+ }
271
+ }
272
+
150
273
  return producer
151
274
  })
152
275
 
@@ -93,7 +93,7 @@ function createWrapQueryCallback (options) {
93
93
  }
94
94
 
95
95
  if (typeof cb === 'function') {
96
- arguments[arguments.length - 1] = shimmer.wrapFunction(cb, wrapper)
96
+ arguments[arguments.length - 1] = shimmer.wrapCallback(cb, wrapper)
97
97
  } else {
98
98
  arguments.length += 1
99
99
  arguments[arguments.length - 1] = wrapper()
@@ -23,7 +23,8 @@ addHook({ name: 'memcached', versions: ['>=2.2'] }, Memcached => {
23
23
 
24
24
  const ctx = { client, server, query }
25
25
  startCh.runStores(ctx, () => {
26
- query.callback = shimmer.wrapFunction(query.callback, callback => function (err) {
26
+ if (typeof query.callback !== 'function') return
27
+ query.callback = shimmer.wrapCallback(query.callback, callback => function (err) {
27
28
  if (err) {
28
29
  ctx.error = err
29
30
  errorCh.publish(ctx)