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
@@ -35,7 +35,6 @@ const b3FlagsKey = 'x-b3-flags'
35
35
  const b3HeaderKey = 'b3'
36
36
  const sqsdHeaderHey = 'x-aws-sqsd-attr-_datadog'
37
37
  const b3HeaderExpr = /^(([0-9a-f]{16}){1,2}-[0-9a-f]{16}(-[01d](-[0-9a-f]{16})?)?|[01d])$/i
38
- const baggageExpr = new RegExp(`^${baggagePrefix}(.+)$`)
39
38
  // W3C Baggage key grammar: key = token (RFC 7230).
40
39
  // Spec (up-to-date): "Propagation format for distributed context: Baggage" §3.3.1
41
40
  // https://www.w3.org/TR/baggage/#header-content
@@ -56,6 +55,15 @@ const ddKeys = [traceKey, spanKey, samplingKey, originKey]
56
55
  const b3Keys = [b3TraceKey, b3SpanKey, b3ParentKey, b3SampledKey, b3FlagsKey, b3HeaderKey]
57
56
  const w3cKeys = [traceparentKey, tracestateKey]
58
57
  const logKeys = [...ddKeys, ...b3Keys, ...w3cKeys]
58
+ // Dispatch table for `_extractSpanContext`. `'b3'` resolves to the matching
59
+ // single/multi extractor per instance — see `#b3MethodName` — so it is not in
60
+ // this table. `'baggage'` is consumed by `_extractBaggageItems`, not the loop.
61
+ const EXTRACT_STYLE_METHODS = new Map([
62
+ ['datadog', '_extractDatadogContext'],
63
+ ['tracecontext', '_extractTraceparentContext'],
64
+ ['b3 single header', '_extractB3SingleContext'],
65
+ ['b3multi', '_extractB3MultiContext'],
66
+ ])
59
67
  // Origin value in tracestate replaces '~', ',' and ';' with '_"
60
68
  const tracestateOriginFilter = /[^\x20-\x2B\x2D-\x3A\x3C-\x7D]/g
61
69
  // Tag keys in tracestate replace ' ', ',' and '=' with '_'
@@ -68,27 +76,29 @@ const hex16 = /^[0-9A-Fa-f]{16}$/
68
76
  const percentByte = /%([0-9A-Fa-f]{2})/g
69
77
 
70
78
  class TextMapPropagator {
71
- #extractB3Context
72
-
73
79
  /** @type {Set<string> | undefined} Cached `Set` view of `_config.baggageTagKeys`. */
74
80
  #baggageTagKeysSet
75
81
 
76
82
  /** @type {string[] | undefined} Source array that `#baggageTagKeysSet` was built from. */
77
83
  #baggageTagKeysSetSource
78
84
 
85
+ /** @type {'_extractB3SingleContext' | '_extractB3MultiContext'} */
86
+ #b3MethodName
87
+
79
88
  constructor (config) {
80
89
  this._config = config
81
90
 
82
- // v6: `'b3'` is always single-header. v5: env-name decides — OTEL_PROPAGATORS callers expect
83
- // single, the legacy `DD_TRACE_PROPAGATION_STYLE` callers expect multi.
91
+ // v6: `'b3'` is always single-header. v5: `OTEL_PROPAGATORS` callers
92
+ // expect single, legacy `DD_TRACE_PROPAGATION_STYLE` callers expect multi.
93
+ /* istanbul ignore else: v5 fallback, master ships 6.0.0-pre */
84
94
  if (DD_MAJOR >= 6) {
85
- this.#extractB3Context = this._extractB3SingleContext
95
+ this.#b3MethodName = '_extractB3SingleContext'
86
96
  } else {
87
97
  const envName = getConfiguredEnvName('DD_TRACE_PROPAGATION_STYLE')
88
98
  // eslint-disable-next-line eslint-rules/eslint-env-aliases
89
- this.#extractB3Context = envName === 'OTEL_PROPAGATORS'
90
- ? this._extractB3SingleContext
91
- : this._extractB3MultiContext
99
+ this.#b3MethodName = envName === 'OTEL_PROPAGATORS'
100
+ ? '_extractB3SingleContext'
101
+ : '_extractB3MultiContext'
92
102
  }
93
103
  }
94
104
 
@@ -129,8 +139,7 @@ class TextMapPropagator {
129
139
 
130
140
  extract (carrier) {
131
141
  const spanContext = this._extractSpanContext(carrier)
132
-
133
- if (!spanContext) return spanContext
142
+ if (spanContext === undefined) return null
134
143
 
135
144
  if (extractCh.hasSubscribers) {
136
145
  extractCh.publish({ spanContext, carrier })
@@ -292,7 +301,7 @@ class TextMapPropagator {
292
301
  // v6 keeps `'b3 single header'` as a back-compat alias for callers that bypass parser normalisation.
293
302
  const hasB3SingleHeader = this._hasPropagationStyle('inject', 'b3 single header') ||
294
303
  (DD_MAJOR >= 6 && this._hasPropagationStyle('inject', 'b3'))
295
- if (!hasB3SingleHeader) return null
304
+ if (!hasB3SingleHeader) return
296
305
 
297
306
  const traceId = this._getB3TraceId(spanContext)
298
307
  const spanId = spanContext._spanId.toString(16)
@@ -361,7 +370,7 @@ class TextMapPropagator {
361
370
  }
362
371
 
363
372
  _hasTraceIdConflict (w3cSpanContext, firstSpanContext) {
364
- return w3cSpanContext !== null &&
373
+ return w3cSpanContext !== undefined &&
365
374
  firstSpanContext.toTraceId(true) === w3cSpanContext.toTraceId(true) &&
366
375
  firstSpanContext.toSpanId() !== w3cSpanContext.toSpanId()
367
376
  }
@@ -372,7 +381,7 @@ class TextMapPropagator {
372
381
 
373
382
  _updateParentIdFromDdHeaders (carrier, firstSpanContext) {
374
383
  const ddCtx = this._extractDatadogContext(carrier)
375
- if (ddCtx !== null) {
384
+ if (ddCtx !== undefined) {
376
385
  firstSpanContext._trace.tags[tags.DD_PARENT_ID] = ddCtx._spanId.toString().padStart(16, '0')
377
386
  }
378
387
  }
@@ -394,35 +403,20 @@ class TextMapPropagator {
394
403
  }
395
404
 
396
405
  _extractSpanContext (carrier) {
397
- let context = null
406
+ let context
398
407
  let style = ''
399
408
  for (const extractor of this._config.tracePropagationStyle.extract) {
400
- let extractedContext = null
401
- switch (extractor) {
402
- case 'datadog':
403
- extractedContext = this._extractDatadogContext(carrier)
404
- break
405
- case 'tracecontext':
406
- extractedContext = this._extractTraceparentContext(carrier)
407
- break
408
- case 'b3 single header':
409
- extractedContext = this._extractB3SingleContext(carrier)
410
- break
411
- case 'b3':
412
- extractedContext = this.#extractB3Context(carrier)
413
- break
414
- case 'b3multi':
415
- extractedContext = this._extractB3MultiContext(carrier)
416
- break
417
- default:
418
- if (extractor !== 'baggage') log.warn('Unknown propagation style:', extractor)
409
+ const method = extractor === 'b3' ? this.#b3MethodName : EXTRACT_STYLE_METHODS.get(extractor)
410
+ if (method === undefined) {
411
+ if (extractor !== 'baggage') log.warn('Unknown propagation style:', extractor)
412
+ continue
419
413
  }
420
-
421
- if (extractedContext === null) { // If the current extractor was invalid, continue to the next extractor
414
+ const extractedContext = this[method](carrier)
415
+ if (extractedContext === undefined) {
422
416
  continue
423
417
  }
424
418
 
425
- if (context === null) {
419
+ if (context === undefined) {
426
420
  context = extractedContext
427
421
  style = extractor
428
422
  if (this._config.DD_TRACE_PROPAGATION_EXTRACT_FIRST) {
@@ -446,9 +440,7 @@ class TextMapPropagator {
446
440
  }
447
441
 
448
442
  if (this._config.DD_TRACE_PROPAGATION_BEHAVIOR_EXTRACT === 'ignore') {
449
- // `context` is null when no extractor matched; the fallback below picks up
450
- // the SQSD context if present, otherwise the request runs untraced.
451
- if (context) context._links = []
443
+ if (context !== undefined) context._links = []
452
444
  } else {
453
445
  if (this._config.DD_TRACE_PROPAGATION_BEHAVIOR_EXTRACT === 'restart' && context) {
454
446
  context._links = []
@@ -490,14 +482,17 @@ class TextMapPropagator {
490
482
 
491
483
  _extractB3MultiContext (carrier) {
492
484
  const b3 = this._extractB3MultipleHeaders(carrier)
493
- if (!b3) return null
485
+ if (b3 === undefined) return
494
486
  return this._extractB3Context(b3)
495
487
  }
496
488
 
497
489
  _extractB3SingleContext (carrier) {
498
- if (!b3HeaderExpr.test(carrier[b3HeaderKey])) return null
490
+ // `typeof === 'string'` first; otherwise the regex coerces `undefined` to
491
+ // `'undefined'` and runs on every header-less request.
492
+ const header = carrier[b3HeaderKey]
493
+ if (typeof header !== 'string' || !b3HeaderExpr.test(header)) return
499
494
  const b3 = this._extractB3SingleHeader(carrier)
500
- if (!b3) return null
495
+ if (b3 === undefined) return
501
496
  return this._extractB3Context(b3)
502
497
  }
503
498
 
@@ -527,23 +522,19 @@ class TextMapPropagator {
527
522
 
528
523
  _extractSqsdContext (carrier) {
529
524
  const headerValue = carrier[sqsdHeaderHey]
530
- if (!headerValue) {
531
- return null
532
- }
525
+ if (!headerValue) return
533
526
  let parsed
534
527
  try {
535
528
  parsed = JSON.parse(headerValue)
536
529
  } catch {
537
- return null
530
+ return
538
531
  }
539
532
  return this._extractDatadogContext(parsed)
540
533
  }
541
534
 
542
535
  _extractTraceparentContext (carrier) {
543
536
  const headerValue = carrier[traceparentKey]
544
- if (typeof headerValue !== 'string') {
545
- return null
546
- }
537
+ if (typeof headerValue !== 'string') return
547
538
  const matches = headerValue.trim().match(traceparentExpr)
548
539
  if (matches !== null) {
549
540
  const [, version, traceId, spanId, flags, tail] = matches
@@ -554,14 +545,14 @@ class TextMapPropagator {
554
545
  ? carrier.tracestate.filter(item => typeof item === 'string').join(',')
555
546
  : carrier.tracestate
556
547
  const tracestate = TraceState.fromString(rawTracestate)
557
- if (invalidSegment.test(traceId)) return null
558
- if (invalidSegment.test(spanId)) return null
548
+ if (invalidSegment.test(traceId)) return
549
+ if (invalidSegment.test(spanId)) return
559
550
 
560
551
  // Version ff is considered invalid
561
- if (version === 'ff') return null
552
+ if (version === 'ff') return
562
553
 
563
554
  // Version 00 should have no tail, but future versions may
564
- if (tail && version === '00') return null
555
+ if (tail && version === '00') return
565
556
 
566
557
  const spanContext = new DatadogSpanContext({
567
558
  traceId: id(traceId, 16),
@@ -624,12 +615,11 @@ class TextMapPropagator {
624
615
  this._extractLegacyBaggageItems(carrier, spanContext)
625
616
  return spanContext
626
617
  }
627
- return null
628
618
  }
629
619
 
630
620
  _extractGenericContext (carrier, traceKey, spanKey, radix) {
631
621
  if (carrier && carrier[traceKey] && carrier[spanKey]) {
632
- if (invalidSegment.test(carrier[traceKey])) return null
622
+ if (invalidSegment.test(carrier[traceKey])) return
633
623
 
634
624
  return new DatadogSpanContext({
635
625
  traceId: id(carrier[traceKey], radix),
@@ -637,11 +627,17 @@ class TextMapPropagator {
637
627
  isRemote: true,
638
628
  })
639
629
  }
640
-
641
- return null
642
630
  }
643
631
 
644
632
  _extractB3MultipleHeaders (carrier) {
633
+ // `b3ParentKey` is intentionally absent: this method never consults it,
634
+ // so a parent-id-only carrier should bail with the rest.
635
+ if (carrier[b3TraceKey] === undefined &&
636
+ carrier[b3SampledKey] === undefined &&
637
+ carrier[b3FlagsKey] === undefined) {
638
+ return
639
+ }
640
+
645
641
  let empty = true
646
642
  const b3 = {}
647
643
 
@@ -661,12 +657,12 @@ class TextMapPropagator {
661
657
  empty = false
662
658
  }
663
659
 
664
- return empty ? null : b3
660
+ return empty ? undefined : b3
665
661
  }
666
662
 
667
663
  _extractB3SingleHeader (carrier) {
668
664
  const header = carrier[b3HeaderKey]
669
- if (!header) return null
665
+ if (!header) return
670
666
 
671
667
  const parts = header.split('-')
672
668
 
@@ -705,13 +701,12 @@ class TextMapPropagator {
705
701
  }
706
702
 
707
703
  _extractLegacyBaggageItems (carrier, spanContext) {
708
- if (this._config.legacyBaggageEnabled) {
709
- for (const key of Object.keys(carrier)) {
710
- const match = key.match(baggageExpr)
711
-
712
- if (match) {
713
- spanContext._baggageItems[match[1]] = carrier[key]
714
- }
704
+ if (!this._config.legacyBaggageEnabled) return
705
+ for (const key of Object.keys(carrier)) {
706
+ if (!key.startsWith(baggagePrefix)) continue
707
+ const baggageKey = key.slice(baggagePrefix.length)
708
+ if (baggageKey) {
709
+ spanContext._baggageItems[baggageKey] = carrier[key]
715
710
  }
716
711
  }
717
712
  }
@@ -10,7 +10,10 @@ const tagger = require('../tagger')
10
10
  const runtimeMetrics = require('../runtime_metrics')
11
11
  const log = require('../log')
12
12
  const { storage } = require('../../../datadog-core')
13
+ const { resolveServiceSource } = require('../service-naming/source-resolver')
13
14
  const telemetryMetrics = require('../telemetry/metrics')
15
+ const { MANUAL_DROP, MANUAL_KEEP, SAMPLING_PRIORITY } = require('../../../../ext/tags')
16
+ const { DD_MAJOR } = require('../../../../version')
14
17
  const SpanContext = require('./span_context')
15
18
 
16
19
  const dateNow = Date.now
@@ -103,7 +106,7 @@ class DatadogSpan {
103
106
 
104
107
  this._spanContext = this._createContext(parent, fields)
105
108
  this._spanContext._name = operationName
106
- this._spanContext._tags = tags
109
+ Object.assign(this._spanContext.getTags(), tags)
107
110
  this._spanContext._hostname = hostname
108
111
 
109
112
  this._spanContext._trace.started.push(this)
@@ -145,7 +148,7 @@ class DatadogSpan {
145
148
 
146
149
  toString () {
147
150
  const spanContext = this.context()
148
- const resourceName = spanContext._tags['resource.name'] || ''
151
+ const resourceName = spanContext.getTag('resource.name') || ''
149
152
  const resource = resourceName.length > 100
150
153
  ? `${resourceName.slice(0, 97)}...`
151
154
  : resourceName
@@ -153,7 +156,7 @@ class DatadogSpan {
153
156
  traceId: spanContext._traceId,
154
157
  spanId: spanContext._spanId,
155
158
  parentId: spanContext._parentId,
156
- service: spanContext._tags['service.name'],
159
+ service: spanContext.getTag('service.name'),
157
160
  name: spanContext._name,
158
161
  resource,
159
162
  })
@@ -199,12 +202,52 @@ class DatadogSpan {
199
202
  }
200
203
 
201
204
  setTag (key, value) {
202
- this._addTags({ [key]: value })
205
+ this._spanContext.setTag(key, value)
206
+
207
+ if (isSamplingPriorityTag(key) && this._spanContext._sampling.priority === undefined) {
208
+ this._prioritySampler.sample(this, false)
209
+ }
210
+
211
+ if (tagsUpdateCh.hasSubscribers) {
212
+ tagsUpdateCh.publish(this)
213
+ }
214
+
203
215
  return this
204
216
  }
205
217
 
206
218
  addTags (keyValueMap) {
207
- this._addTags(keyValueMap)
219
+ // v6 hot path: `Object.assign` straight onto the live tag map. The
220
+ // string and array shapes never appeared in the public TypeScript
221
+ // surface, and no internal v6 caller passes one (see MIGRATING.md).
222
+ // v5 still accepts both via `tagger.add` for `config.tags` /
223
+ // `options.tags` callers that pass `'key:val,key:val'` strings.
224
+ const tags = this._spanContext.getTags()
225
+ let mayChangeSamplingPriority
226
+
227
+ if (keyValueMap !== null && typeof keyValueMap === 'object' && !Array.isArray(keyValueMap)) {
228
+ Object.assign(tags, keyValueMap)
229
+ mayChangeSamplingPriority =
230
+ MANUAL_KEEP in keyValueMap ||
231
+ MANUAL_DROP in keyValueMap ||
232
+ SAMPLING_PRIORITY in keyValueMap
233
+ } else {
234
+ /* istanbul ignore if: v5 fallback, master ships 6.0.0-pre */
235
+ if (DD_MAJOR < 6 && (typeof keyValueMap === 'string' || Array.isArray(keyValueMap))) {
236
+ tagger.add(tags, keyValueMap)
237
+ mayChangeSamplingPriority = true
238
+ } else {
239
+ return this
240
+ }
241
+ }
242
+
243
+ if (mayChangeSamplingPriority && this._spanContext._sampling.priority === undefined) {
244
+ this._prioritySampler.sample(this, false)
245
+ }
246
+
247
+ if (tagsUpdateCh.hasSubscribers) {
248
+ tagsUpdateCh.publish(this)
249
+ }
250
+
208
251
  return this
209
252
  }
210
253
 
@@ -215,8 +258,9 @@ class DatadogSpan {
215
258
  logEvent () {}
216
259
 
217
260
  addLink (link, attrs) {
218
- // TODO: Remove this once we remove addLink(context, attrs) in v6.0.0
219
- if (link instanceof SpanContext) {
261
+ // v5 still accepts the legacy `addLink(spanContext, attrs)` shape; v6 only takes
262
+ // `addLink({ context, attributes })`.
263
+ if (DD_MAJOR < 6 && link instanceof SpanContext) {
220
264
  link = { context: link, attributes: attrs ?? {} }
221
265
  }
222
266
 
@@ -267,12 +311,14 @@ class DatadogSpan {
267
311
  return
268
312
  }
269
313
 
270
- if (this.#parentTracer._config.DD_TRACE_EXPERIMENTAL_STATE_TRACKING && !this._spanContext._tags['service.name']) {
314
+ if (this.#parentTracer._config.DD_TRACE_EXPERIMENTAL_STATE_TRACKING && !this._spanContext.getTag('service.name')) {
271
315
  log.error('Finishing invalid span: %s', this)
272
316
  }
273
317
 
274
318
  getIntegrationCounter('spans_finished', this._integrationName).inc()
275
- this._spanContext._tags['_dd.integration'] = this._integrationName
319
+ this._spanContext.setTag('_dd.integration', this._integrationName)
320
+
321
+ resolveServiceSource(this, this.#parentTracer._service)
276
322
 
277
323
  if (this.#parentTracer._config.DD_TRACE_EXPERIMENTAL_SPAN_COUNTS && finishedRegistry) {
278
324
  runtimeMetrics.decrement('runtime.node.spans.unfinished')
@@ -404,16 +450,6 @@ class DatadogSpan {
404
450
 
405
451
  return startTime + now() - ticks
406
452
  }
407
-
408
- _addTags (keyValuePairs) {
409
- tagger.add(this._spanContext._tags, keyValuePairs)
410
-
411
- this._prioritySampler.sample(this, false)
412
-
413
- if (tagsUpdateCh.hasSubscribers) {
414
- tagsUpdateCh.publish(this)
415
- }
416
- }
417
453
  }
418
454
 
419
455
  function createRegistry (type) {
@@ -423,4 +459,8 @@ function createRegistry (type) {
423
459
  })
424
460
  }
425
461
 
462
+ function isSamplingPriorityTag (key) {
463
+ return key === MANUAL_KEEP || key === MANUAL_DROP || key === SAMPLING_PRIORITY
464
+ }
465
+
426
466
  module.exports = DatadogSpan
@@ -71,6 +71,55 @@ class DatadogSpanContext {
71
71
  const version = (this._traceparent && this._traceparent.version) || '00'
72
72
  return `${version}-${traceId}-${spanId}-${flags}`
73
73
  }
74
+
75
+ /**
76
+ * Set a tag value.
77
+ * @param {string} key - Tag key
78
+ * @param {unknown} value - Tag value
79
+ */
80
+ setTag (key, value) {
81
+ this._tags[key] = value
82
+ }
83
+
84
+ /**
85
+ * Get a tag value.
86
+ * @param {string} key - Tag key
87
+ * @returns {unknown} Tag value or undefined
88
+ */
89
+ getTag (key) {
90
+ return this._tags[key]
91
+ }
92
+
93
+ /**
94
+ * Check if a tag exists.
95
+ * @param {string} key - Tag key
96
+ * @returns {boolean}
97
+ */
98
+ hasTag (key) { return Object.hasOwn(this._tags, key) }
99
+
100
+ /**
101
+ * Delete a tag.
102
+ * @param {string} key - Tag key
103
+ */
104
+ deleteTag (key) { delete this._tags[key] }
105
+
106
+ /**
107
+ * Get the live internal tags map. The returned reference is mutable;
108
+ * callers may assign or delete keys directly (e.g.
109
+ * `Object.assign(getTags(), tags)` in span.js). Subclasses may have
110
+ * additional sync side effects on the individual `setTag` / `deleteTag`
111
+ * setters; mutating the returned map bypasses those.
112
+ *
113
+ * @returns {object}
114
+ */
115
+ getTags () {
116
+ return this._tags
117
+ }
118
+
119
+ /**
120
+ * Clear all tags.
121
+ */
122
+ clearTags () { this._tags = Object.create(null) }
74
123
  }
75
124
 
76
125
  module.exports = DatadogSpanContext
@@ -3,13 +3,15 @@
3
3
  const { storage } = require('../../../datadog-core')
4
4
  const TracingPlugin = require('./tracing')
5
5
 
6
+ const legacyStorage = storage('legacy')
7
+
6
8
  class ApolloBasePlugin extends TracingPlugin {
7
9
  static id = 'apollo.gateway'
8
10
  static type = 'web'
9
11
  static kind = 'server'
10
12
 
11
13
  bindStart (ctx) {
12
- const store = storage('legacy').getStore()
14
+ const store = legacyStorage.getStore()
13
15
  const childOf = store ? /** @type {import('../opentracing/span') | undefined} */ (store.span) : null
14
16
 
15
17
  const span = this.startSpan(this.getOperationName(), {
@@ -52,7 +52,6 @@ const {
52
52
  TEST_ITR_SKIPPING_ENABLED,
53
53
  ITR_CORRELATION_ID,
54
54
  TEST_SOURCE_FILE,
55
- TEST_LEVEL_EVENT_TYPES,
56
55
  TEST_SUITE,
57
56
  getFileAndLineNumberFromError,
58
57
  DI_ERROR_DEBUG_INFO_CAPTURED,
@@ -82,6 +81,8 @@ const {
82
81
  DD_CAPABILITIES_TEST_IMPACT_ANALYSIS,
83
82
  } = require('./util/test')
84
83
 
84
+ const legacyStorage = storage('legacy')
85
+
85
86
  const FRAMEWORK_TO_TRIMMED_COMMAND = {
86
87
  vitest: 'vitest run',
87
88
  mocha: 'mocha',
@@ -126,7 +127,6 @@ function getTestSuiteLevelVisibilityTags (testSuiteSpan, testFramework) {
126
127
  const suiteTags = {
127
128
  [TEST_SUITE_ID]: testSuiteSpanContext.toSpanId(),
128
129
  [TEST_SESSION_ID]: testSuiteSpanContext.toTraceId(),
129
- [TEST_COMMAND]: testSuiteSpanContext._tags[TEST_COMMAND],
130
130
  [TEST_MODULE]: testFramework,
131
131
  }
132
132
 
@@ -147,7 +147,7 @@ module.exports = class CiPlugin extends Plugin {
147
147
 
148
148
  this.addSub(`ci:${this.constructor.id}:library-configuration`, (ctx) => {
149
149
  const { onDone, frameworkVersion } = ctx
150
- ctx.currentStore = storage('legacy').getStore()
150
+ ctx.currentStore = legacyStorage.getStore()
151
151
 
152
152
  if (!this.tracer._exporter || !this.tracer._exporter.getLibraryConfiguration) {
153
153
  return onDone({ err: new Error('Test optimization was not initialized correctly') })
@@ -172,7 +172,7 @@ module.exports = class CiPlugin extends Plugin {
172
172
  },
173
173
  }
174
174
  this.tracer._exporter.addMetadataTags(metadataTags)
175
- onDone({ err, libraryConfig, requestErrorTags })
175
+ onDone({ err, libraryConfig, repositoryRoot: this.repositoryRoot, requestErrorTags })
176
176
  })
177
177
  })
178
178
 
@@ -184,15 +184,22 @@ module.exports = class CiPlugin extends Plugin {
184
184
  if (!this.tracer._exporter?.getSkippableSuites) {
185
185
  return onDone({ err: new Error('Test optimization was not initialized correctly') })
186
186
  }
187
- this.tracer._exporter.getSkippableSuites(this.testConfiguration, (err, skippableSuites, itrCorrelationId) => {
188
- if (err) {
189
- log.error('Skippable suites could not be fetched. %s', err.message)
190
- this._addRequestErrorTag(DD_CI_LIBRARY_CONFIGURATION_ERROR_SKIPPABLE_TESTS, err)
191
- } else {
192
- this.itrCorrelationId = itrCorrelationId
187
+ this.tracer._exporter.getSkippableSuites(
188
+ {
189
+ ...this.testConfiguration,
190
+ isCoverageReportUploadEnabled: this.libraryConfig?.isCoverageReportUploadEnabled,
191
+ },
192
+ (err, skippableSuites, itrCorrelationId, skippableSuitesCoverage) => {
193
+ if (err) {
194
+ log.error('Skippable suites could not be fetched. %s', err.message)
195
+ this._addRequestErrorTag(DD_CI_LIBRARY_CONFIGURATION_ERROR_SKIPPABLE_TESTS, err)
196
+ } else {
197
+ this.itrCorrelationId = itrCorrelationId
198
+ this.skippableSuitesCoverage = skippableSuitesCoverage
199
+ }
200
+ onDone({ err, skippableSuites, itrCorrelationId, skippableSuitesCoverage })
193
201
  }
194
- onDone({ err, skippableSuites, itrCorrelationId })
195
- })
202
+ )
196
203
  })
197
204
 
198
205
  this.addSub(`ci:${this.constructor.id}:session:start`, ({ command, frameworkVersion, rootDir }) => {
@@ -211,12 +218,7 @@ module.exports = class CiPlugin extends Plugin {
211
218
  this.testEnvironmentMetadata
212
219
  )
213
220
 
214
- const metadataTags = {}
215
- for (const testLevel of TEST_LEVEL_EVENT_TYPES) {
216
- metadataTags[testLevel] = {
217
- [TEST_SESSION_NAME]: testSessionName,
218
- }
219
- }
221
+ const metadataTags = { '*': { [TEST_COMMAND]: command, [TEST_SESSION_NAME]: testSessionName } }
220
222
  // tracer might not be initialized correctly
221
223
  if (this.tracer._exporter.addMetadataTags) {
222
224
  this.tracer._exporter.addMetadataTags(metadataTags)
@@ -249,23 +251,11 @@ module.exports = class CiPlugin extends Plugin {
249
251
  integrationName: this.constructor.id,
250
252
  })
251
253
  setItrSkippingEnabledTagFromLibraryConfig(this, frameworkVersion)
252
- // only for vitest
253
- // These are added for the worker threads to use
254
- if (this.constructor.id === 'vitest') {
255
- // TODO: Figure out alternative ways to pass this information to the worker threads
256
- // eslint-disable-next-line eslint-rules/eslint-process-env
257
- process.env.DD_CIVISIBILITY_TEST_SESSION_ID = this.testSessionSpan.context().toTraceId()
258
- // eslint-disable-next-line eslint-rules/eslint-process-env
259
- process.env.DD_CIVISIBILITY_TEST_MODULE_ID = this.testModuleSpan.context().toSpanId()
260
- // eslint-disable-next-line eslint-rules/eslint-process-env
261
- process.env.DD_CIVISIBILITY_TEST_COMMAND = this.command
262
- }
263
-
264
254
  this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'module')
265
255
  })
266
256
 
267
257
  this.addSub(`ci:${this.constructor.id}:itr:skipped-suites`, ({ skippedSuites, frameworkVersion }) => {
268
- const testCommand = this.testSessionSpan.context()._tags[TEST_COMMAND]
258
+ const testCommand = this.command
269
259
  for (const testSuite of skippedSuites) {
270
260
  const testSuiteMetadata = {
271
261
  ...getTestSuiteCommonTags(testCommand, frameworkVersion, testSuite, this.constructor.id),
@@ -625,7 +615,7 @@ module.exports = class CiPlugin extends Plugin {
625
615
  const suiteTags = {
626
616
  [TEST_SUITE_ID]: testSuiteSpan.context().toSpanId(),
627
617
  [TEST_SESSION_ID]: testSuiteSpan.context().toTraceId(),
628
- [TEST_COMMAND]: testSuiteSpan.context()._tags[TEST_COMMAND],
618
+ [TEST_COMMAND]: testSuiteSpan.context().getTag(TEST_COMMAND),
629
619
  [TEST_MODULE]: this.constructor.id,
630
620
  ...getSessionRequestErrorTags(this.testSessionSpan),
631
621
  }
@@ -818,7 +808,7 @@ module.exports = class CiPlugin extends Plugin {
818
808
  }
819
809
 
820
810
  getTestTelemetryTags (testSpan) {
821
- const activeSpanTags = testSpan.context()._tags
811
+ const activeSpanTags = testSpan.context().getTags()
822
812
  return {
823
813
  hasCodeOwners: !!activeSpanTags[TEST_CODE_OWNERS] || undefined,
824
814
  isNew: activeSpanTags[TEST_IS_NEW] === 'true' || undefined,
@@ -49,7 +49,7 @@ class DatabasePlugin extends StoragePlugin {
49
49
  * @returns {string}
50
50
  */
51
51
  #createDBMPropagationCommentService (serviceName, span, peerData) {
52
- const spanTags = span.context()._tags
52
+ const spanTags = span.context().getTags()
53
53
  const dddb = spanTags['db.name']
54
54
  const ddh = spanTags['out.host']
55
55
  const cacheKey = `${dddb ?? ''}\0${ddh ?? ''}\0${serviceName ?? ''}`
@@ -91,23 +91,24 @@ class DatabasePlugin extends StoragePlugin {
91
91
  return null
92
92
  }
93
93
 
94
- const peerData = this.getPeerService(span.context()._tags)
94
+ const peerData = this.getPeerService(span.context().getTags())
95
95
  const dbmService = this.#getDbmServiceName(serviceName, peerData)
96
96
  const servicePropagation = this.#createDBMPropagationCommentService(dbmService, span, peerData)
97
97
 
98
98
  let dbmComment = servicePropagation
99
99
 
100
- // Add propagation hash if both process tags and SQL base hash injection are enabled
101
- if (propagationHash.isEnabled() && this.config['dbm.injectSqlBaseHash']) {
100
+ // Add propagation hash if process tags are enabled and either SQL base hash injection is enabled
101
+ // or dynamic_service mode implicitly enables it
102
+ if (propagationHash.isEnabled() && (this.config['dbm.injectSqlBaseHash'] || mode === 'dynamic_service')) {
102
103
  const hashBase64 = propagationHash.getHashBase64()
103
104
  if (hashBase64) {
104
105
  dbmComment += `,ddsh='${hashBase64}'`
105
106
  // Add hash to span meta as a tag
106
- span.setTag('_dd.dbm.propagation_hash', hashBase64)
107
+ span.setTag('_dd.propagated_hash', hashBase64)
107
108
  }
108
109
  }
109
110
 
110
- if (disableFullMode || mode === 'service') {
111
+ if (disableFullMode || mode === 'service' || mode === 'dynamic_service') {
111
112
  return dbmComment
112
113
  } else if (mode === 'full') {
113
114
  span.setTag('_dd.dbm_trace_injected', 'true')