dd-trace 5.51.0 → 5.53.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 (98) hide show
  1. package/LICENSE-3rdparty.csv +0 -6
  2. package/README.md +5 -0
  3. package/index.d.ts +88 -6
  4. package/package.json +3 -9
  5. package/packages/datadog-instrumentations/src/amqplib.js +8 -5
  6. package/packages/datadog-instrumentations/src/child_process.js +2 -1
  7. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +406 -0
  8. package/packages/datadog-instrumentations/src/couchbase.js +2 -1
  9. package/packages/datadog-instrumentations/src/cucumber.js +43 -45
  10. package/packages/datadog-instrumentations/src/dns.js +16 -14
  11. package/packages/datadog-instrumentations/src/express.js +2 -6
  12. package/packages/datadog-instrumentations/src/fs.js +43 -51
  13. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
  14. package/packages/datadog-instrumentations/src/helpers/register.js +17 -12
  15. package/packages/datadog-instrumentations/src/http/client.js +2 -1
  16. package/packages/datadog-instrumentations/src/iovalkey.js +51 -0
  17. package/packages/datadog-instrumentations/src/jest.js +53 -40
  18. package/packages/datadog-instrumentations/src/kafkajs.js +21 -8
  19. package/packages/datadog-instrumentations/src/mocha/main.js +33 -46
  20. package/packages/datadog-instrumentations/src/mocha/utils.js +76 -74
  21. package/packages/datadog-instrumentations/src/mysql2.js +3 -1
  22. package/packages/datadog-instrumentations/src/net.js +27 -29
  23. package/packages/datadog-instrumentations/src/next.js +6 -14
  24. package/packages/datadog-instrumentations/src/pg.js +15 -7
  25. package/packages/datadog-instrumentations/src/playwright.js +64 -67
  26. package/packages/datadog-instrumentations/src/url.js +9 -17
  27. package/packages/datadog-instrumentations/src/vitest.js +66 -72
  28. package/packages/datadog-plugin-confluentinc-kafka-javascript/src/batch-consumer.js +11 -0
  29. package/packages/datadog-plugin-confluentinc-kafka-javascript/src/consumer.js +11 -0
  30. package/packages/datadog-plugin-confluentinc-kafka-javascript/src/index.js +19 -0
  31. package/packages/datadog-plugin-confluentinc-kafka-javascript/src/producer.js +11 -0
  32. package/packages/datadog-plugin-cucumber/src/index.js +32 -18
  33. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +3 -0
  34. package/packages/datadog-plugin-dns/src/lookup.js +10 -5
  35. package/packages/datadog-plugin-dns/src/lookup_service.js +6 -2
  36. package/packages/datadog-plugin-dns/src/resolve.js +5 -2
  37. package/packages/datadog-plugin-dns/src/reverse.js +6 -2
  38. package/packages/datadog-plugin-fs/src/index.js +9 -2
  39. package/packages/datadog-plugin-iovalkey/src/index.js +18 -0
  40. package/packages/datadog-plugin-jest/src/index.js +17 -8
  41. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -1
  42. package/packages/datadog-plugin-kafkajs/src/consumer.js +12 -21
  43. package/packages/datadog-plugin-kafkajs/src/producer.js +12 -5
  44. package/packages/datadog-plugin-kafkajs/src/utils.js +27 -0
  45. package/packages/datadog-plugin-langchain/src/index.js +0 -1
  46. package/packages/datadog-plugin-mocha/src/index.js +58 -35
  47. package/packages/datadog-plugin-net/src/ipc.js +6 -4
  48. package/packages/datadog-plugin-net/src/tcp.js +15 -9
  49. package/packages/datadog-plugin-pg/src/index.js +5 -1
  50. package/packages/datadog-plugin-playwright/src/index.js +29 -20
  51. package/packages/datadog-plugin-redis/src/index.js +8 -3
  52. package/packages/datadog-plugin-vitest/src/index.js +67 -44
  53. package/packages/datadog-shimmer/src/shimmer.js +164 -33
  54. package/packages/dd-trace/src/appsec/api_security_sampler.js +20 -12
  55. package/packages/dd-trace/src/appsec/graphql.js +2 -2
  56. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +14 -9
  57. package/packages/dd-trace/src/appsec/index.js +15 -12
  58. package/packages/dd-trace/src/appsec/rasp/index.js +4 -2
  59. package/packages/dd-trace/src/appsec/rasp/utils.js +11 -6
  60. package/packages/dd-trace/src/appsec/sdk/user_blocking.js +2 -2
  61. package/packages/dd-trace/src/appsec/telemetry/index.js +1 -2
  62. package/packages/dd-trace/src/appsec/telemetry/rasp.js +0 -9
  63. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +6 -6
  64. package/packages/dd-trace/src/baggage.js +36 -0
  65. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +4 -2
  66. package/packages/dd-trace/src/config.js +14 -2
  67. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +61 -7
  68. package/packages/dd-trace/src/debugger/devtools_client/index.js +10 -26
  69. package/packages/dd-trace/src/debugger/devtools_client/send.js +8 -7
  70. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +15 -7
  71. package/packages/dd-trace/src/debugger/devtools_client/state.js +22 -2
  72. package/packages/dd-trace/src/dogstatsd.js +2 -0
  73. package/packages/dd-trace/src/exporters/common/docker.js +13 -31
  74. package/packages/dd-trace/src/guardrails/telemetry.js +2 -5
  75. package/packages/dd-trace/src/llmobs/tagger.js +3 -3
  76. package/packages/dd-trace/src/llmobs/writers/base.js +33 -12
  77. package/packages/dd-trace/src/noop/proxy.js +5 -0
  78. package/packages/dd-trace/src/opentelemetry/context_manager.js +2 -0
  79. package/packages/dd-trace/src/opentracing/propagation/text_map.js +17 -9
  80. package/packages/dd-trace/src/plugin_manager.js +2 -0
  81. package/packages/dd-trace/src/plugins/index.js +4 -0
  82. package/packages/dd-trace/src/plugins/log_plugin.js +9 -20
  83. package/packages/dd-trace/src/plugins/outbound.js +11 -3
  84. package/packages/dd-trace/src/plugins/tracing.js +8 -4
  85. package/packages/dd-trace/src/plugins/util/test.js +1 -1
  86. package/packages/dd-trace/src/profiling/exporter_cli.js +1 -1
  87. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookup.js +1 -1
  88. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookupservice.js +1 -1
  89. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_resolve.js +2 -2
  90. package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_reverse.js +1 -1
  91. package/packages/dd-trace/src/profiling/profilers/event_plugins/event.js +15 -14
  92. package/packages/dd-trace/src/proxy.js +12 -4
  93. package/packages/dd-trace/src/serverless.js +0 -48
  94. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +8 -0
  95. package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +8 -0
  96. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +8 -0
  97. package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +4 -0
  98. package/packages/dd-trace/src/standalone/product.js +3 -5
@@ -0,0 +1,19 @@
1
+ 'use strict'
2
+
3
+ const ProducerPlugin = require('./producer')
4
+ const ConsumerPlugin = require('./consumer')
5
+ const BatchConsumerPlugin = require('./batch-consumer')
6
+ const KafkajsPlugin = require('../../datadog-plugin-kafkajs/src/index')
7
+
8
+ class ConfluentKafkaJsPlugin extends KafkajsPlugin {
9
+ static get id () { return '@confluentinc/kafka-javascript' }
10
+ static get plugins () {
11
+ return {
12
+ producer: ProducerPlugin,
13
+ consumer: ConsumerPlugin,
14
+ batchConsumer: BatchConsumerPlugin
15
+ }
16
+ }
17
+ }
18
+
19
+ module.exports = ConfluentKafkaJsPlugin
@@ -0,0 +1,11 @@
1
+ 'use strict'
2
+
3
+ const KafkajsProducerPlugin = require('../../datadog-plugin-kafkajs/src/producer')
4
+
5
+ class ConfluentKafkaJsProducerPlugin extends KafkajsProducerPlugin {
6
+ static get id () {
7
+ return '@confluentinc/kafka-javascript'
8
+ }
9
+ }
10
+
11
+ module.exports = ConfluentKafkaJsProducerPlugin
@@ -221,13 +221,8 @@ class CucumberPlugin extends CiPlugin {
221
221
  this.telemetry.ciVisEvent(TELEMETRY_CODE_COVERAGE_FINISHED, 'suite', { library: 'istanbul' })
222
222
  })
223
223
 
224
- this.addSub('ci:cucumber:test:start', ({
225
- testName,
226
- testFileAbsolutePath,
227
- testSourceLine,
228
- isParallel,
229
- promises
230
- }) => {
224
+ this.addBind('ci:cucumber:test:start', (ctx) => {
225
+ const { testName, testFileAbsolutePath, testSourceLine, isParallel, promises } = ctx
231
226
  const store = storage('legacy').getStore()
232
227
  const testSuite = getTestSuitePath(testFileAbsolutePath, this.sourceRoot)
233
228
  const testSourceFile = getTestSuitePath(testFileAbsolutePath, this.repositoryRoot)
@@ -240,22 +235,23 @@ class CucumberPlugin extends CiPlugin {
240
235
  extraTags[CUCUMBER_IS_PARALLEL] = 'true'
241
236
  }
242
237
 
243
- const testSpan = this.startTestSpan(testName, testSuite, extraTags)
238
+ const span = this.startTestSpan(testName, testSuite, extraTags)
244
239
 
245
- this.enter(testSpan, store)
240
+ ctx.parentStore = store
241
+ ctx.currentStore = { ...store, span }
246
242
 
247
- this.activeTestSpan = testSpan
243
+ this.activeTestSpan = span
248
244
  // Time we give the breakpoint to be hit
249
245
  if (promises && this.runningTestProbe) {
250
246
  promises.hitBreakpointPromise = new Promise((resolve) => {
251
247
  setTimeout(resolve, BREAKPOINT_HIT_GRACE_PERIOD_MS)
252
248
  })
253
249
  }
250
+
251
+ return ctx.currentStore
254
252
  })
255
253
 
256
- this.addSub('ci:cucumber:test:retry', ({ isFirstAttempt, error, isAtrRetry }) => {
257
- const store = storage('legacy').getStore()
258
- const span = store.span
254
+ this.addSub('ci:cucumber:test:retry', ({ span, isFirstAttempt, error, isAtrRetry }) => {
259
255
  if (!isFirstAttempt) {
260
256
  span.setTag(TEST_IS_RETRY, 'true')
261
257
  if (isAtrRetry) {
@@ -284,7 +280,9 @@ class CucumberPlugin extends CiPlugin {
284
280
  finishAllTraceSpans(span)
285
281
  })
286
282
 
287
- this.addSub('ci:cucumber:test-step:start', ({ resource }) => {
283
+ this.addBind('ci:cucumber:test-step:start', (ctx) => {
284
+ const { resource } = ctx
285
+
288
286
  const store = storage('legacy').getStore()
289
287
  const childOf = store ? store.span : store
290
288
  const span = this.tracer.startSpan('cucumber.step', {
@@ -295,7 +293,10 @@ class CucumberPlugin extends CiPlugin {
295
293
  [RESOURCE_NAME]: resource
296
294
  }
297
295
  })
298
- this.enter(span, store)
296
+ ctx.parentStore = store
297
+ ctx.currentStore = { ...store, span }
298
+
299
+ return ctx.currentStore
299
300
  })
300
301
 
301
302
  this.addSub('ci:cucumber:worker-report:trace', (traces) => {
@@ -329,6 +330,7 @@ class CucumberPlugin extends CiPlugin {
329
330
  })
330
331
 
331
332
  this.addSub('ci:cucumber:test:finish', ({
333
+ span,
332
334
  isStep,
333
335
  status,
334
336
  skipReason,
@@ -341,10 +343,10 @@ class CucumberPlugin extends CiPlugin {
341
343
  isAttemptToFixRetry,
342
344
  hasFailedAllRetries,
343
345
  hasPassedAllRetries,
346
+ hasFailedAttemptToFix,
344
347
  isDisabled,
345
348
  isQuarantined
346
349
  }) => {
347
- const span = storage('legacy').getStore().span
348
350
  const statusTag = isStep ? 'step.status' : TEST_STATUS
349
351
 
350
352
  span.setTag(statusTag, status)
@@ -385,6 +387,8 @@ class CucumberPlugin extends CiPlugin {
385
387
  span.setTag(TEST_RETRY_REASON, TEST_RETRY_REASON_TYPES.atf)
386
388
  if (hasPassedAllRetries) {
387
389
  span.setTag(TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED, 'true')
390
+ } else if (hasFailedAttemptToFix) {
391
+ span.setTag(TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED, 'false')
388
392
  }
389
393
  }
390
394
 
@@ -422,11 +426,21 @@ class CucumberPlugin extends CiPlugin {
422
426
  }
423
427
  })
424
428
 
425
- this.addSub('ci:cucumber:error', (err) => {
429
+ this.addBind('ci:cucumber:error', (ctx) => {
430
+ const { err } = ctx
426
431
  if (err) {
427
- const span = storage('legacy').getStore().span
432
+ const span = ctx.currentStore.span
428
433
  span.setTag('error', err)
434
+
435
+ ctx.parentStore = ctx.currentStore
436
+ ctx.currentStore = { ...ctx.currentStore, span }
429
437
  }
438
+
439
+ return ctx.currentStore
440
+ })
441
+
442
+ this.addBind('ci:cucumber:test:fn', (ctx) => {
443
+ return ctx.currentStore
430
444
  })
431
445
  }
432
446
 
@@ -838,6 +838,9 @@ class CypressPlugin {
838
838
  }
839
839
  const isLastAttempt = testStatuses.length === this.testManagementAttemptToFixRetries + 1
840
840
  if (isLastAttempt) {
841
+ if (testStatuses.some(status => status === 'fail')) {
842
+ this.activeTestSpan.setTag(TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED, 'false')
843
+ }
841
844
  if (testStatuses.every(status => status === 'fail')) {
842
845
  this.activeTestSpan.setTag(TEST_HAS_FAILED_ALL_RETRIES, 'true')
843
846
  } else if (testStatuses.every(status => status === 'pass')) {
@@ -6,7 +6,9 @@ class DNSLookupPlugin extends ClientPlugin {
6
6
  static get id () { return 'dns' }
7
7
  static get operation () { return 'lookup' }
8
8
 
9
- start ([hostname]) {
9
+ bindStart (ctx) {
10
+ const [hostname] = ctx.args
11
+
10
12
  this.startSpan('dns.lookup', {
11
13
  service: this.config.service,
12
14
  resource: hostname,
@@ -16,11 +18,14 @@ class DNSLookupPlugin extends ClientPlugin {
16
18
  'dns.address': '',
17
19
  'dns.addresses': ''
18
20
  }
19
- })
21
+ }, ctx)
22
+
23
+ return ctx.currentStore
20
24
  }
21
25
 
22
- finish (result) {
23
- const span = this.activeSpan
26
+ bindFinish (ctx) {
27
+ const span = ctx.currentStore.span
28
+ const result = ctx.result
24
29
 
25
30
  if (Array.isArray(result)) {
26
31
  const addresses = Array.isArray(result)
@@ -33,7 +38,7 @@ class DNSLookupPlugin extends ClientPlugin {
33
38
  span.setTag('dns.address', result)
34
39
  }
35
40
 
36
- super.finish()
41
+ return ctx.parentStore
37
42
  }
38
43
  }
39
44
 
@@ -6,7 +6,9 @@ class DNSLookupServicePlugin extends ClientPlugin {
6
6
  static get id () { return 'dns' }
7
7
  static get operation () { return 'lookup_service' }
8
8
 
9
- start ([address, port]) {
9
+ bindStart (ctx) {
10
+ const [address, port] = ctx.args
11
+
10
12
  this.startSpan('dns.lookup_service', {
11
13
  service: this.config.service,
12
14
  resource: `${address}:${port}`,
@@ -17,7 +19,9 @@ class DNSLookupServicePlugin extends ClientPlugin {
17
19
  metrics: {
18
20
  'dns.port': port
19
21
  }
20
- })
22
+ }, ctx)
23
+
24
+ return ctx.currentStore
21
25
  }
22
26
  }
23
27
 
@@ -6,7 +6,8 @@ class DNSResolvePlugin extends ClientPlugin {
6
6
  static get id () { return 'dns' }
7
7
  static get operation () { return 'resolve' }
8
8
 
9
- start ([hostname, maybeType]) {
9
+ bindStart (ctx) {
10
+ const [hostname, maybeType] = ctx.args
10
11
  const rrtype = typeof maybeType === 'string' ? maybeType : 'A'
11
12
 
12
13
  this.startSpan('dns.resolve', {
@@ -17,7 +18,9 @@ class DNSResolvePlugin extends ClientPlugin {
17
18
  'dns.hostname': hostname,
18
19
  'dns.rrtype': rrtype
19
20
  }
20
- })
21
+ }, ctx)
22
+
23
+ return ctx.currentStore
21
24
  }
22
25
  }
23
26
 
@@ -6,7 +6,9 @@ class DNSReversePlugin extends ClientPlugin {
6
6
  static get id () { return 'dns' }
7
7
  static get operation () { return 'reverse' }
8
8
 
9
- start ([ip]) {
9
+ bindStart (ctx) {
10
+ const [ip] = ctx.args
11
+
10
12
  this.startSpan('dns.reverse', {
11
13
  service: this.config.service,
12
14
  resource: ip,
@@ -14,7 +16,9 @@ class DNSReversePlugin extends ClientPlugin {
14
16
  meta: {
15
17
  'dns.ip': ip
16
18
  }
17
- })
19
+ }, ctx)
20
+
21
+ return ctx.currentStore
18
22
  }
19
23
  }
20
24
 
@@ -10,9 +10,10 @@ class FsPlugin extends TracingPlugin {
10
10
  return super.configure(...args)
11
11
  }
12
12
 
13
- start ({ operation, ...params }) {
13
+ bindStart (ctx) {
14
14
  if (!this.activeSpan) return this.skip()
15
15
 
16
+ const { operation, ...params } = ctx
16
17
  const lowerOp = operation.toLowerCase()
17
18
  const flag = params.flag || params.flags || (params.options && (params.options.flag || params.options.flags))
18
19
  const defaultFlag = ((lowerOp.includes('open') || lowerOp.includes('read')) && 'r') ||
@@ -38,7 +39,13 @@ class FsPlugin extends TracingPlugin {
38
39
  'file.src': params.src || params.oldPath || params.existingPath || params.target,
39
40
  'file.uid': uid || ''
40
41
  }
41
- })
42
+ }, ctx)
43
+
44
+ return ctx.currentStore
45
+ }
46
+
47
+ bindFinish (ctx) {
48
+ return ctx.parentStore
42
49
  }
43
50
  }
44
51
 
@@ -0,0 +1,18 @@
1
+ 'use strict'
2
+
3
+ const RedisPlugin = require('../../datadog-plugin-redis/src')
4
+
5
+ class IOValkeyPlugin extends RedisPlugin {
6
+ static get id () {
7
+ return 'iovalkey'
8
+ }
9
+
10
+ static get system () { return 'valkey' }
11
+
12
+ constructor (...args) {
13
+ super(...args)
14
+ this._spanType = 'valkey'
15
+ }
16
+ }
17
+
18
+ module.exports = IOValkeyPlugin
@@ -333,28 +333,39 @@ class JestPlugin extends CiPlugin {
333
333
  this.telemetry.distribution(TELEMETRY_CODE_COVERAGE_NUM_FILES, {}, files.length)
334
334
  })
335
335
 
336
- this.addSub('ci:jest:test:start', (test) => {
336
+ this.addBind('ci:jest:test:start', (ctx) => {
337
337
  const store = storage('legacy').getStore()
338
- const span = this.startTestSpan(test)
338
+ const span = this.startTestSpan(ctx)
339
+
340
+ ctx.parentStore = store
341
+ ctx.currentStore = { ...store, span }
339
342
 
340
- this.enter(span, store)
341
343
  this.activeTestSpan = span
344
+
345
+ return ctx.currentStore
346
+ })
347
+
348
+ this.addBind('ci:jest:test:fn', (ctx) => {
349
+ return ctx.currentStore
342
350
  })
343
351
 
344
352
  this.addSub('ci:jest:test:finish', ({
353
+ span,
345
354
  status,
346
355
  testStartLine,
347
356
  attemptToFixPassed,
348
357
  failedAllTests,
358
+ attemptToFixFailed,
349
359
  isAtrRetry
350
360
  }) => {
351
- const span = storage('legacy').getStore().span
352
361
  span.setTag(TEST_STATUS, status)
353
362
  if (testStartLine) {
354
363
  span.setTag(TEST_SOURCE_START, testStartLine)
355
364
  }
356
365
  if (attemptToFixPassed) {
357
366
  span.setTag(TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED, 'true')
367
+ } else if (attemptToFixFailed) {
368
+ span.setTag(TEST_MANAGEMENT_ATTEMPT_TO_FIX_PASSED, 'false')
358
369
  }
359
370
  if (failedAllTests) {
360
371
  span.setTag(TEST_HAS_FAILED_ALL_RETRIES, 'true')
@@ -381,11 +392,9 @@ class JestPlugin extends CiPlugin {
381
392
  this.activeTestSpan = null
382
393
  })
383
394
 
384
- this.addSub('ci:jest:test:err', ({ error, shouldSetProbe, promises }) => {
395
+ this.addSub('ci:jest:test:err', ({ span, error, shouldSetProbe, promises }) => {
385
396
  if (error) {
386
- const store = storage('legacy').getStore()
387
- if (store && store.span) {
388
- const span = store.span
397
+ if (span) {
389
398
  span.setTag(TEST_STATUS, 'fail')
390
399
  span.setTag('error', getFormattedError(error, this.repositoryRoot))
391
400
  if (shouldSetProbe) {
@@ -1,5 +1,6 @@
1
1
  const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
2
2
  const { getMessageSize } = require('../../dd-trace/src/datastreams')
3
+ const { convertToTextMap } = require('./utils')
3
4
 
4
5
  class KafkajsBatchConsumerPlugin extends ConsumerPlugin {
5
6
  static get id () { return 'kafkajs' }
@@ -10,7 +11,7 @@ class KafkajsBatchConsumerPlugin extends ConsumerPlugin {
10
11
  for (const message of messages) {
11
12
  if (!message || !message.headers) continue
12
13
  const payloadSize = getMessageSize(message)
13
- this.tracer.decodeDataStreamsContext(message.headers)
14
+ this.tracer.decodeDataStreamsContext(convertToTextMap(message.headers))
14
15
  const edgeTags = ['direction:in', `group:${groupId}`, `topic:${topic}`, 'type:kafka']
15
16
  if (clusterId) {
16
17
  edgeTags.push(`kafka_cluster_id:${clusterId}`)
@@ -3,7 +3,7 @@
3
3
  const dc = require('dc-polyfill')
4
4
  const { getMessageSize } = require('../../dd-trace/src/datastreams')
5
5
  const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
6
-
6
+ const { convertToTextMap } = require('./utils')
7
7
  const afterStartCh = dc.channel('dd-trace:kafkajs:consumer:afterStart')
8
8
  const beforeFinishCh = dc.channel('dd-trace:kafkajs:consumer:beforeFinish')
9
9
 
@@ -15,7 +15,7 @@ class KafkajsConsumerPlugin extends ConsumerPlugin {
15
15
 
16
16
  constructor () {
17
17
  super(...arguments)
18
- this.addSub('apm:kafkajs:consume:commit', message => this.commit(message))
18
+ this.addSub(`apm:${this.constructor.id}:consume:commit`, message => this.commit(message))
19
19
  }
20
20
 
21
21
  /**
@@ -65,15 +65,18 @@ class KafkajsConsumerPlugin extends ConsumerPlugin {
65
65
  }
66
66
 
67
67
  start ({ topic, partition, message, groupId, clusterId }) {
68
- const childOf = extract(this.tracer, message.headers)
68
+ let childOf
69
+ const headers = convertToTextMap(message?.headers)
70
+ if (headers) {
71
+ childOf = this.tracer.extract('text_map', headers)
72
+ }
69
73
  const span = this.startSpan({
70
74
  childOf,
71
75
  resource: topic,
72
76
  type: 'worker',
73
77
  meta: {
74
- component: 'kafkajs',
78
+ component: this.constructor.id,
75
79
  'kafka.topic': topic,
76
- 'kafka.message.offset': message.offset,
77
80
  'kafka.cluster_id': clusterId,
78
81
  [MESSAGING_DESTINATION_KEY]: topic
79
82
  },
@@ -81,9 +84,11 @@ class KafkajsConsumerPlugin extends ConsumerPlugin {
81
84
  'kafka.partition': partition
82
85
  }
83
86
  })
84
- if (this.config.dsmEnabled && message?.headers) {
87
+ if (message?.offset) span.setTag('kafka.message.offset', message?.offset)
88
+
89
+ if (this.config.dsmEnabled && headers) {
85
90
  const payloadSize = getMessageSize(message)
86
- this.tracer.decodeDataStreamsContext(message.headers)
91
+ this.tracer.decodeDataStreamsContext(headers)
87
92
  const edgeTags = ['direction:in', `group:${groupId}`, `topic:${topic}`, 'type:kafka']
88
93
  if (clusterId) {
89
94
  edgeTags.push(`kafka_cluster_id:${clusterId}`)
@@ -105,18 +110,4 @@ class KafkajsConsumerPlugin extends ConsumerPlugin {
105
110
  }
106
111
  }
107
112
 
108
- function extract (tracer, bufferMap) {
109
- if (!bufferMap) return null
110
-
111
- const textMap = {}
112
-
113
- for (const key of Object.keys(bufferMap)) {
114
- if (bufferMap[key] === null || bufferMap[key] === undefined) continue
115
-
116
- textMap[key] = bufferMap[key].toString()
117
- }
118
-
119
- return tracer.extract('text_map', textMap)
120
- }
121
-
122
113
  module.exports = KafkajsConsumerPlugin
@@ -13,7 +13,7 @@ class KafkajsProducerPlugin extends ProducerPlugin {
13
13
 
14
14
  constructor () {
15
15
  super(...arguments)
16
- this.addSub('apm:kafkajs:produce:commit', message => this.commit(message))
16
+ this.addSub(`apm:${this.constructor.id}:produce:commit`, message => this.commit(message))
17
17
  }
18
18
 
19
19
  /**
@@ -54,6 +54,7 @@ class KafkajsProducerPlugin extends ProducerPlugin {
54
54
  */
55
55
  commit (commitList) {
56
56
  if (!this.config.dsmEnabled) return
57
+ if (!commitList || !Array.isArray(commitList)) return
57
58
  const keys = [
58
59
  'type',
59
60
  'partition',
@@ -66,11 +67,11 @@ class KafkajsProducerPlugin extends ProducerPlugin {
66
67
  }
67
68
  }
68
69
 
69
- start ({ topic, messages, bootstrapServers, clusterId }) {
70
+ start ({ topic, messages, bootstrapServers, clusterId, disableHeaderInjection }) {
70
71
  const span = this.startSpan({
71
72
  resource: topic,
72
73
  meta: {
73
- component: 'kafkajs',
74
+ component: this.constructor.id,
74
75
  'kafka.topic': topic,
75
76
  'kafka.cluster_id': clusterId,
76
77
  [MESSAGING_DESTINATION_KEY]: topic
@@ -84,7 +85,11 @@ class KafkajsProducerPlugin extends ProducerPlugin {
84
85
  }
85
86
  for (const message of messages) {
86
87
  if (message !== null && typeof message === 'object') {
87
- this.tracer.inject(span, 'text_map', message.headers)
88
+ // message headers are not supported for kafka broker versions <0.11
89
+ if (!disableHeaderInjection) {
90
+ message.headers ??= {}
91
+ this.tracer.inject(span, 'text_map', message.headers)
92
+ }
88
93
  if (this.config.dsmEnabled) {
89
94
  const payloadSize = getMessageSize(message)
90
95
  const edgeTags = ['direction:out', `topic:${topic}`, 'type:kafka']
@@ -94,7 +99,9 @@ class KafkajsProducerPlugin extends ProducerPlugin {
94
99
  }
95
100
 
96
101
  const dataStreamsContext = this.tracer.setCheckpoint(edgeTags, span, payloadSize)
97
- DsmPathwayCodec.encode(dataStreamsContext, message.headers)
102
+ if (!disableHeaderInjection) {
103
+ DsmPathwayCodec.encode(dataStreamsContext, message.headers)
104
+ }
98
105
  }
99
106
  }
100
107
  }
@@ -0,0 +1,27 @@
1
+ 'use strict'
2
+
3
+ function convertToTextMap (bufferMap) {
4
+ if (!bufferMap) return null
5
+
6
+ // rdKafka returns an array of header maps
7
+ if (bufferMap instanceof Array) {
8
+ const headers = {}
9
+ for (const headerMap of bufferMap) {
10
+ for (const key of Object.keys(headerMap)) {
11
+ headers[key] = headerMap[key].toString()
12
+ }
13
+ }
14
+ return headers
15
+ }
16
+
17
+ const textMap = {}
18
+ for (const key of Object.keys(bufferMap)) {
19
+ if (bufferMap[key] === null || bufferMap[key] === undefined) continue
20
+ textMap[key] = bufferMap[key].toString()
21
+ }
22
+ return textMap
23
+ }
24
+
25
+ module.exports = {
26
+ convertToTextMap
27
+ }
@@ -2,7 +2,6 @@
2
2
 
3
3
  const langChainTracingPlugins = require('./tracing')
4
4
  const langChainLLMObsPlugins = require('../../dd-trace/src/llmobs/plugins/langchain')
5
- // const LangChainLLMObsPlugin = require('../../dd-trace/src/llmobs/plugins/langchain')
6
5
  const CompositePlugin = require('../../dd-trace/src/plugins/composite')
7
6
 
8
7
  const plugins = {}