dd-trace 5.108.0 → 5.110.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 (174) hide show
  1. package/ci/init.js +4 -3
  2. package/index.d.ts +88 -25
  3. package/loader-hook.mjs +88 -2
  4. package/package.json +19 -14
  5. package/packages/datadog-esbuild/index.js +26 -0
  6. package/packages/datadog-esbuild/src/utils.js +46 -3
  7. package/packages/datadog-instrumentations/src/ai.js +43 -48
  8. package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js-context-methods.js +18 -0
  9. package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +111 -0
  10. package/packages/datadog-instrumentations/src/aws-sdk.js +3 -1
  11. package/packages/datadog-instrumentations/src/connect.js +4 -3
  12. package/packages/datadog-instrumentations/src/electron.js +1 -1
  13. package/packages/datadog-instrumentations/src/fastify.js +4 -12
  14. package/packages/datadog-instrumentations/src/graphql.js +17 -6
  15. package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +81 -8
  16. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  17. package/packages/datadog-instrumentations/src/helpers/instrument.js +27 -2
  18. package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +65 -0
  19. package/packages/datadog-instrumentations/src/helpers/register.js +6 -4
  20. package/packages/datadog-instrumentations/src/helpers/require-optional-peer.js +17 -0
  21. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/aws-durable-execution-sdk-js.js +31 -0
  22. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
  23. package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +18 -2
  24. package/packages/datadog-instrumentations/src/http/client.js +12 -2
  25. package/packages/datadog-instrumentations/src/ioredis.js +0 -1
  26. package/packages/datadog-instrumentations/src/iovalkey.js +1 -2
  27. package/packages/datadog-instrumentations/src/koa.js +3 -2
  28. package/packages/datadog-instrumentations/src/mariadb.js +4 -2
  29. package/packages/datadog-instrumentations/src/mocha/main.js +3 -3
  30. package/packages/datadog-instrumentations/src/next.js +44 -10
  31. package/packages/datadog-instrumentations/src/openai.js +77 -18
  32. package/packages/datadog-instrumentations/src/otel-sdk-trace.js +7 -6
  33. package/packages/datadog-instrumentations/src/playwright.js +1 -1
  34. package/packages/datadog-instrumentations/src/redis.js +0 -1
  35. package/packages/datadog-instrumentations/src/restify.js +4 -3
  36. package/packages/datadog-instrumentations/src/router.js +18 -5
  37. package/packages/datadog-instrumentations/src/selenium.js +1 -2
  38. package/packages/datadog-instrumentations/src/tedious.js +28 -0
  39. package/packages/datadog-instrumentations/src/vitest.js +323 -7
  40. package/packages/datadog-plugin-avsc/src/schema_iterator.js +2 -2
  41. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/checkpoint.js +31 -0
  42. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/client.js +55 -0
  43. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/context.js +114 -0
  44. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/handler.js +128 -0
  45. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/index.js +19 -0
  46. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +224 -0
  47. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +43 -0
  48. package/packages/datadog-plugin-aws-sdk/src/base.js +14 -16
  49. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +43 -6
  50. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +100 -37
  51. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +108 -99
  52. package/packages/datadog-plugin-bullmq/src/filter.js +35 -0
  53. package/packages/datadog-plugin-bullmq/src/producer.js +84 -4
  54. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +9 -1
  55. package/packages/datadog-plugin-fs/src/index.js +1 -0
  56. package/packages/datadog-plugin-http/src/client.js +8 -3
  57. package/packages/datadog-plugin-http2/src/client.js +5 -2
  58. package/packages/datadog-plugin-mysql/src/index.js +7 -2
  59. package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +2 -2
  60. package/packages/datadog-plugin-redis/src/index.js +1 -2
  61. package/packages/datadog-plugin-undici/src/index.js +5 -2
  62. package/packages/datadog-plugin-vitest/src/index.js +11 -2
  63. package/packages/datadog-webpack/index.js +17 -1
  64. package/packages/datadog-webpack/src/optional-peer-loader.js +17 -0
  65. package/packages/dd-trace/src/aiguard/channels.js +0 -1
  66. package/packages/dd-trace/src/aiguard/index.js +11 -49
  67. package/packages/dd-trace/src/aiguard/integrations/evaluate.js +46 -0
  68. package/packages/dd-trace/src/aiguard/integrations/openai.js +66 -0
  69. package/packages/dd-trace/src/aiguard/integrations/vercel-ai.js +78 -0
  70. package/packages/{datadog-instrumentations/src/helpers/ai-messages.js → dd-trace/src/aiguard/messages/openai.js} +85 -193
  71. package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +185 -0
  72. package/packages/dd-trace/src/aiguard/sdk.js +13 -1
  73. package/packages/dd-trace/src/appsec/api_security/index.js +55 -0
  74. package/packages/dd-trace/src/appsec/api_security/sampler.js +147 -0
  75. package/packages/dd-trace/src/appsec/channels.js +1 -0
  76. package/packages/dd-trace/src/appsec/downstream_requests.js +111 -58
  77. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +54 -12
  78. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +5 -1
  79. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +29 -4
  80. package/packages/dd-trace/src/appsec/index.js +10 -6
  81. package/packages/dd-trace/src/appsec/rasp/ssrf.js +19 -11
  82. package/packages/dd-trace/src/appsec/reporter.js +1 -0
  83. package/packages/dd-trace/src/appsec/telemetry/api_security.js +34 -0
  84. package/packages/dd-trace/src/appsec/telemetry/index.js +26 -0
  85. package/packages/dd-trace/src/ci-visibility/requests/request.js +1 -17
  86. package/packages/dd-trace/src/config/defaults.js +22 -3
  87. package/packages/dd-trace/src/config/generated-config-types.d.ts +538 -1
  88. package/packages/dd-trace/src/config/helper.js +133 -33
  89. package/packages/dd-trace/src/config/index.js +4 -1
  90. package/packages/dd-trace/src/config/parsers.js +19 -1
  91. package/packages/dd-trace/src/config/supported-configurations.json +45 -5
  92. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +49 -35
  93. package/packages/dd-trace/src/debugger/devtools_client/index.js +31 -66
  94. package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +83 -0
  95. package/packages/dd-trace/src/debugger/devtools_client/state.js +1 -0
  96. package/packages/dd-trace/src/debugger/index.js +5 -0
  97. package/packages/dd-trace/src/debugger/probe_sampler.js +112 -0
  98. package/packages/dd-trace/src/debugger/probe_sampler_constants.js +19 -0
  99. package/packages/dd-trace/src/dogstatsd.js +15 -8
  100. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +77 -26
  101. package/packages/dd-trace/src/exporters/agentless/index.js +7 -5
  102. package/packages/dd-trace/src/exporters/agentless/intake.js +43 -0
  103. package/packages/dd-trace/src/exporters/agentless/writer.js +5 -4
  104. package/packages/dd-trace/src/exporters/common/request.js +1 -20
  105. package/packages/dd-trace/src/exporters/common/url.js +34 -0
  106. package/packages/dd-trace/src/exporters/span-stats/writer.js +1 -3
  107. package/packages/dd-trace/src/guardrails/index.js +8 -5
  108. package/packages/dd-trace/src/index.js +6 -4
  109. package/packages/dd-trace/src/llmobs/constants/tags.js +6 -0
  110. package/packages/dd-trace/src/llmobs/index.js +16 -5
  111. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +3 -3
  112. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +5 -1
  113. package/packages/dd-trace/src/llmobs/sdk.js +5 -3
  114. package/packages/dd-trace/src/llmobs/span_processor.js +4 -0
  115. package/packages/dd-trace/src/llmobs/tagger.js +55 -0
  116. package/packages/dd-trace/src/llmobs/telemetry.js +1 -0
  117. package/packages/dd-trace/src/log/index.js +18 -20
  118. package/packages/dd-trace/src/openfeature/flagging_provider.js +3 -1
  119. package/packages/dd-trace/src/opentelemetry/bridge-span-base.js +5 -4
  120. package/packages/dd-trace/src/opentelemetry/metrics/instruments.js +2 -1
  121. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +4 -3
  122. package/packages/dd-trace/src/opentelemetry/metrics/time.js +19 -0
  123. package/packages/dd-trace/src/opentelemetry/otlp/common.proto +2 -2
  124. package/packages/dd-trace/src/opentelemetry/otlp/logs.proto +1 -1
  125. package/packages/dd-trace/src/opentelemetry/otlp/logs_service.proto +1 -1
  126. package/packages/dd-trace/src/opentelemetry/otlp/metrics.proto +1 -1
  127. package/packages/dd-trace/src/opentelemetry/otlp/metrics_service.proto +1 -1
  128. package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +11 -4
  129. package/packages/dd-trace/src/opentelemetry/span-helpers.js +29 -13
  130. package/packages/dd-trace/src/opentelemetry/span.js +14 -3
  131. package/packages/dd-trace/src/opentelemetry/span_context.js +1 -0
  132. package/packages/dd-trace/src/opentelemetry/trace/index.js +2 -1
  133. package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +3 -2
  134. package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +26 -13
  135. package/packages/dd-trace/src/opentracing/propagation/text_map.js +3 -3
  136. package/packages/dd-trace/src/opentracing/span_context.js +17 -0
  137. package/packages/dd-trace/src/plugin_manager.js +7 -1
  138. package/packages/dd-trace/src/plugins/ci_plugin.js +36 -3
  139. package/packages/dd-trace/src/plugins/index.js +3 -0
  140. package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +276 -0
  141. package/packages/dd-trace/src/plugins/util/test.js +80 -0
  142. package/packages/dd-trace/src/plugins/util/url.js +68 -1
  143. package/packages/dd-trace/src/plugins/util/web.js +19 -36
  144. package/packages/dd-trace/src/priority_sampler.js +1 -13
  145. package/packages/dd-trace/src/profiling/config.js +129 -198
  146. package/packages/dd-trace/src/profiling/constants.js +4 -7
  147. package/packages/dd-trace/src/profiling/exporter_cli.js +10 -10
  148. package/packages/dd-trace/src/profiling/exporters/agent.js +23 -16
  149. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +45 -14
  150. package/packages/dd-trace/src/profiling/exporters/file.js +16 -5
  151. package/packages/dd-trace/src/profiling/oom.js +71 -0
  152. package/packages/dd-trace/src/profiling/profiler.js +35 -23
  153. package/packages/dd-trace/src/profiling/profilers/events.js +14 -7
  154. package/packages/dd-trace/src/profiling/profilers/space.js +27 -18
  155. package/packages/dd-trace/src/profiling/profilers/wall.js +35 -25
  156. package/packages/dd-trace/src/ritm.js +4 -2
  157. package/packages/dd-trace/src/serverless.js +1 -2
  158. package/packages/dd-trace/src/service-naming/schemas/util.js +36 -5
  159. package/packages/dd-trace/src/service-naming/schemas/v0/serverless.js +12 -0
  160. package/packages/dd-trace/src/service-naming/schemas/v1/serverless.js +12 -0
  161. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +5 -3
  162. package/packages/dd-trace/src/span_format.js +2 -1
  163. package/packages/dd-trace/src/span_processor.js +6 -0
  164. package/packages/dd-trace/src/telemetry/send-data.js +12 -10
  165. package/packages/dd-trace/src/tracer.js +15 -1
  166. package/packages/dd-trace/src/util.js +14 -0
  167. package/register.js +58 -1
  168. package/vendor/dist/@apm-js-collab/code-transformer/index.js +1 -1
  169. package/vendor/dist/@datadog/sketches-js/index.js +1 -1
  170. package/vendor/dist/pprof-format/index.js +1 -1
  171. package/vendor/dist/protobufjs/index.js +1 -1
  172. package/vendor/dist/protobufjs/minimal/index.js +1 -1
  173. package/packages/datadog-instrumentations/src/helpers/openai-ai-guard.js +0 -284
  174. package/packages/dd-trace/src/appsec/api_security_sampler.js +0 -117
@@ -137,14 +137,17 @@ function normalizeLinkContext (context) {
137
137
  * Mirrors `http.response.status_code` onto `http.status_code` (DD's special tag used by APM
138
138
  * trace metrics and client-side stats); both names end up on the span.
139
139
  *
140
+ * When OTel trace semantics are enabled, the behavior is disabled.
141
+ *
140
142
  * @param {import('../opentracing/span')} ddSpan
141
143
  * @param {string} key
142
144
  * @param {unknown} value
145
+ * @param {boolean} [otelTraceSemanticsEnabled]
143
146
  */
144
- function setOtelAttribute (ddSpan, key, value) {
147
+ function setOtelAttribute (ddSpan, key, value, otelTraceSemanticsEnabled) {
145
148
  if (!isWritable(ddSpan)) return
146
149
 
147
- if (key === 'http.response.status_code') {
150
+ if (!otelTraceSemanticsEnabled && key === 'http.response.status_code') {
148
151
  ddSpan.setTag('http.status_code', String(value))
149
152
  }
150
153
 
@@ -155,14 +158,17 @@ function setOtelAttribute (ddSpan, key, value) {
155
158
  * Same `http.status_code` mirror as `setOtelAttribute`; does not mutate the caller's
156
159
  * `attributes` object.
157
160
  *
161
+ * When OTel trace semantics are enabled, the behavior is disabled.
162
+ *
158
163
  * @param {import('../opentracing/span')} ddSpan
159
164
  * @param {Record<string, unknown>} attributes
165
+ * @param {boolean} [otelTraceSemanticsEnabled]
160
166
  */
161
- function setOtelAttributes (ddSpan, attributes) {
167
+ function setOtelAttributes (ddSpan, attributes, otelTraceSemanticsEnabled) {
162
168
  if (!isWritable(ddSpan)) return
163
169
 
164
170
  ddSpan.addTags(attributes)
165
- if ('http.response.status_code' in attributes) {
171
+ if (!otelTraceSemanticsEnabled && 'http.response.status_code' in attributes) {
166
172
  ddSpan.setTag('http.status_code', String(attributes['http.response.status_code']))
167
173
  }
168
174
  }
@@ -223,16 +229,19 @@ function addOtelEvent (ddSpan, name, attributesOrStartTime, startTime) {
223
229
  * @param {import('../opentracing/span')} ddSpan
224
230
  * @param {ExceptionLike} exception
225
231
  * @param {TimeInput} [timeInput]
232
+ * @param {boolean} [otelTraceSemanticsEnabled]
226
233
  */
227
- function recordException (ddSpan, exception, timeInput) {
234
+ function recordException (ddSpan, exception, timeInput, otelTraceSemanticsEnabled) {
228
235
  if (!isWritable(ddSpan)) return
229
236
 
230
- ddSpan.addTags({
231
- [ERROR_TYPE]: exception.name,
232
- [ERROR_MESSAGE]: exception.message,
233
- [ERROR_STACK]: exception.stack,
234
- [IGNORE_OTEL_ERROR]: ddSpan.context().getTag(IGNORE_OTEL_ERROR) ?? true,
235
- })
237
+ if (!otelTraceSemanticsEnabled) {
238
+ ddSpan.addTags({
239
+ [ERROR_TYPE]: exception.name,
240
+ [ERROR_MESSAGE]: exception.message,
241
+ [ERROR_STACK]: exception.stack,
242
+ [IGNORE_OTEL_ERROR]: ddSpan.context().getTag(IGNORE_OTEL_ERROR) ?? true,
243
+ })
244
+ }
236
245
 
237
246
  const attributes = {}
238
247
  if (exception.message) attributes['exception.message'] = exception.message
@@ -251,13 +260,20 @@ function recordException (ddSpan, exception, timeInput) {
251
260
  * @param {import('../opentracing/span')} ddSpan
252
261
  * @param {number} currentCode 0 = UNSET, 1 = OK, 2 = ERROR.
253
262
  * @param {{ code?: number, message?: string }} [status]
263
+ * @param {boolean} [otelTraceSemanticsEnabled]
254
264
  * @returns {number} The new status code to track on the caller.
255
265
  */
256
- function applyOtelStatus (ddSpan, currentCode, status) {
266
+ function applyOtelStatus (ddSpan, currentCode, status, otelTraceSemanticsEnabled) {
257
267
  if (!isWritable(ddSpan)) return currentCode
258
268
 
259
269
  const code = status?.code
260
- if (!code || currentCode === 1) return currentCode
270
+ if (!code || currentCode === 1) {
271
+ if (otelTraceSemanticsEnabled) {
272
+ ddSpan.context().deleteTag(ERROR_MESSAGE)
273
+ ddSpan.context().deleteTag(IGNORE_OTEL_ERROR)
274
+ }
275
+ return currentCode
276
+ }
261
277
 
262
278
  if (code === 2) {
263
279
  ddSpan.addTags({
@@ -15,7 +15,7 @@ const kinds = require('../../../../ext/kinds')
15
15
  const id = require('../id')
16
16
  const BridgeSpanBase = require('./bridge-span-base')
17
17
  const SpanContext = require('./span_context')
18
- const { setOtelOperationName } = require('./span-helpers')
18
+ const { setOtelOperationName, setOtelResource } = require('./span-helpers')
19
19
 
20
20
  const spanKindNames = {
21
21
  [api.SpanKind.INTERNAL]: kinds.INTERNAL,
@@ -118,6 +118,8 @@ function spanNameMapper (spanName, kind, attributes) {
118
118
  * surface; the underlying DD span carries the lifecycle.
119
119
  */
120
120
  class Span extends BridgeSpanBase {
121
+ #otelName
122
+
121
123
  /**
122
124
  * @param {import('./tracer')} parentTracer
123
125
  * @param {import('@opentelemetry/api').Context} context
@@ -159,12 +161,15 @@ class Span extends BridgeSpanBase {
159
161
 
160
162
  super(ddSpan)
161
163
 
164
+ this._otelTraceSemanticsEnabled = _tracer._config.DD_TRACE_OTEL_SEMANTICS_ENABLED
165
+
162
166
  if (attributes) {
163
167
  this.setAttributes(attributes)
164
168
  }
165
169
 
166
170
  this._parentTracer = parentTracer
167
171
  this._context = context
172
+ this.#otelName = spanName || this._ddSpan.context()._name
168
173
 
169
174
  // NOTE: Need to grab the value before setting it on the span because the
170
175
  // math for computing opentracing timestamps is apparently lossy...
@@ -192,7 +197,7 @@ class Span extends BridgeSpanBase {
192
197
  }
193
198
 
194
199
  get name () {
195
- return this._ddSpan.context()._name
200
+ return this.#otelName
196
201
  }
197
202
 
198
203
  spanContext () {
@@ -223,7 +228,13 @@ class Span extends BridgeSpanBase {
223
228
  * @param {string} name
224
229
  */
225
230
  updateName (name) {
226
- setOtelOperationName(this._ddSpan, name)
231
+ if (this.ended) return this
232
+ this.#otelName = name
233
+ if (this._otelTraceSemanticsEnabled) {
234
+ setOtelResource(this._ddSpan, name)
235
+ } else {
236
+ setOtelOperationName(this._ddSpan, name)
237
+ }
227
238
  return this
228
239
  }
229
240
 
@@ -32,6 +32,7 @@ class SpanContext {
32
32
  }
33
33
 
34
34
  get traceFlags () {
35
+ this._ddContext._ensureSamplingPriority()
35
36
  return this._ddContext._sampling.priority >= AUTO_KEEP ? 1 : 0
36
37
  }
37
38
 
@@ -59,7 +59,8 @@ function createOtlpTraceExporter (config) {
59
59
  config.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
60
60
  config.OTEL_EXPORTER_OTLP_TRACES_HEADERS,
61
61
  config.OTEL_EXPORTER_OTLP_TRACES_TIMEOUT,
62
- buildResourceAttributes(config)
62
+ buildResourceAttributes(config),
63
+ config.DD_TRACE_OTEL_SEMANTICS_ENABLED
63
64
  )
64
65
  }
65
66
 
@@ -36,10 +36,11 @@ class OtlpHttpTraceExporter extends OtlpHttpExporterBase {
36
36
  * corresponding `OTEL_EXPORTER_OTLP_*_HEADERS` env by the MAP parser.
37
37
  * @param {number} timeout - Request timeout in milliseconds
38
38
  * @param {import('@opentelemetry/api').Attributes} resourceAttributes - Resource attributes
39
+ * @param {boolean} otelTraceSemanticsEnabled - When true, do not emit Datadog-only attributes as span attributes
39
40
  */
40
- constructor (url, headers, timeout, resourceAttributes) {
41
+ constructor (url, headers, timeout, resourceAttributes, otelTraceSemanticsEnabled) {
41
42
  super(url, headers, timeout, 'http/json', 'traces')
42
- this.#transformer = new OtlpTraceTransformer(resourceAttributes)
43
+ this.#transformer = new OtlpTraceTransformer(resourceAttributes, otelTraceSemanticsEnabled)
43
44
  }
44
45
 
45
46
  /**
@@ -74,6 +74,9 @@ const EXCLUDED_META_KEYS = new Set([
74
74
  TRACE_ID_128,
75
75
  ])
76
76
 
77
+ // DD-only error tags that should not appear as attributes when OTel trace semantics are enabled.
78
+ const DD_ERROR_META_KEYS = new Set(['error.message'])
79
+
77
80
  /**
78
81
  * OtlpTraceTransformer transforms DD-formatted spans to OTLP trace JSON format.
79
82
  *
@@ -87,13 +90,17 @@ const EXCLUDED_META_KEYS = new Set([
87
90
  * @augments OtlpTransformerBase
88
91
  */
89
92
  class OtlpTraceTransformer extends OtlpTransformerBase {
93
+ #otelTraceSemanticsEnabled
94
+
90
95
  /**
91
96
  * Creates a new OtlpTraceTransformer instance.
92
97
  *
93
98
  * @param {import('@opentelemetry/api').Attributes} resourceAttributes - Resource attributes
99
+ * @param {boolean} [otelTraceSemanticsEnabled] - When true, do not emit Datadog-only attributes as span attributes
94
100
  */
95
- constructor (resourceAttributes) {
101
+ constructor (resourceAttributes, otelTraceSemanticsEnabled) {
96
102
  super(resourceAttributes, 'http/json', 'traces')
103
+ this.#otelTraceSemanticsEnabled = otelTraceSemanticsEnabled
97
104
  }
98
105
 
99
106
  /**
@@ -184,24 +191,30 @@ class OtlpTraceTransformer extends OtlpTransformerBase {
184
191
  #buildAttributes (span) {
185
192
  const attributes = []
186
193
 
187
- // Add top-level DD span fields as OTLP attributes
188
- if (span.service) {
189
- attributes.push({ key: 'service.name', value: { stringValue: span.service } })
190
- }
191
- if (span.name) {
192
- attributes.push({ key: 'operation.name', value: { stringValue: span.name } })
193
- }
194
- if (span.resource) {
195
- attributes.push({ key: 'resource.name', value: { stringValue: span.resource } })
196
- }
197
- if (span.type) {
198
- attributes.push({ key: 'span.type', value: { stringValue: span.type } })
194
+ // Add top-level DD span fields as OTLP attributes.
195
+ // When OTel trace semantics are enabled, these Datadog-only concepts
196
+ // are not added to the span attributes so the output conforms to pure
197
+ // OpenTelemetry semantics.
198
+ if (!this.#otelTraceSemanticsEnabled) {
199
+ if (span.service) {
200
+ attributes.push({ key: 'service.name', value: { stringValue: span.service } })
201
+ }
202
+ if (span.name) {
203
+ attributes.push({ key: 'operation.name', value: { stringValue: span.name } })
204
+ }
205
+ if (span.resource) {
206
+ attributes.push({ key: 'resource.name', value: { stringValue: span.resource } })
207
+ }
208
+ if (span.type) {
209
+ attributes.push({ key: 'span.type', value: { stringValue: span.type } })
210
+ }
199
211
  }
200
212
 
201
213
  // Add meta string tags, skipping keys that map to dedicated OTLP fields
202
214
  if (span.meta) {
203
215
  for (const [key, value] of Object.entries(span.meta)) {
204
216
  if (EXCLUDED_META_KEYS.has(key)) continue
217
+ if (this.#otelTraceSemanticsEnabled && DD_ERROR_META_KEYS.has(key)) continue
205
218
  attributes.push({ key, value: { stringValue: value } })
206
219
  }
207
220
  }
@@ -371,8 +371,8 @@ class TextMapPropagator {
371
371
 
372
372
  _hasTraceIdConflict (w3cSpanContext, firstSpanContext) {
373
373
  return w3cSpanContext !== undefined &&
374
- firstSpanContext.toTraceId(true) === w3cSpanContext.toTraceId(true) &&
375
- firstSpanContext.toSpanId() !== w3cSpanContext.toSpanId()
374
+ firstSpanContext.toTraceId(true) === w3cSpanContext.toTraceId(true) &&
375
+ firstSpanContext.toSpanId() !== w3cSpanContext.toSpanId()
376
376
  }
377
377
 
378
378
  _hasParentIdInTags (spanContext) {
@@ -875,7 +875,7 @@ class TextMapPropagator {
875
875
  (!tracestateSamplingPriority || tracestateSamplingPriority >= 0)) {
876
876
  samplingPriority = AUTO_REJECT
877
877
  } else if (traceparentSampled === 1 &&
878
- (!tracestateSamplingPriority || tracestateSamplingPriority < 0)) {
878
+ (!tracestateSamplingPriority || tracestateSamplingPriority < 0)) {
879
879
  samplingPriority = AUTO_KEEP
880
880
  }
881
881
  }
@@ -63,6 +63,7 @@ class DatadogSpanContext {
63
63
  }
64
64
 
65
65
  toTraceparent () {
66
+ this._ensureSamplingPriority()
66
67
  const flags = this._sampling.priority >= AUTO_KEEP ? '01' : '00'
67
68
  const traceId = this.toTraceId(true)
68
69
  const spanId = this.toSpanId(true)
@@ -70,6 +71,22 @@ class DatadogSpanContext {
70
71
  return `${version}-${traceId}-${spanId}-${flags}`
71
72
  }
72
73
 
74
+ /**
75
+ * Materialize the lazy priority-sampling decision for this trace, the same
76
+ * way {@link DatadogTracer#inject} does before propagation. The auto priority
77
+ * is otherwise computed at flush time, so the W3C sampled flag reads "drop"
78
+ * for a freshly started, not-yet-flushed span — see
79
+ * https://github.com/DataDog/dd-trace-js/issues/2547.
80
+ *
81
+ * The root span is only used to reach the priority sampler; `this` is passed
82
+ * to `sample()` so a manual sampling tag set directly on this context is
83
+ * honored, matching what `inject(this)` would decide.
84
+ */
85
+ _ensureSamplingPriority () {
86
+ if (this._sampling.priority !== undefined) return
87
+ this._trace.started[0]?._prioritySampler?.sample(this)
88
+ }
89
+
73
90
  /**
74
91
  * Set a tag value.
75
92
  * @param {string} key - Tag key
@@ -60,7 +60,11 @@ function maybeEnable (Plugin) {
60
60
 
61
61
  function getEnabled (Plugin) {
62
62
  const envName = `DD_TRACE_${Plugin.id.toUpperCase()}_ENABLED`
63
- return getValueFromEnvSources(normalizePluginEnvName(envName))
63
+ // skipDefault: only an explicitly configured value should drive enablement here. A registered
64
+ // default of `false` (e.g. an experimental plugin like `nats`) must not be read as an explicit
65
+ // "disabled via configuration option" — that path both logs a misleading line and nulls the
66
+ // plugin class, bypassing the experimental opt-in handled by `loadPlugin`.
67
+ return getValueFromEnvSources(normalizePluginEnvName(envName), true)
64
68
  }
65
69
 
66
70
  // TODO this must always be a singleton.
@@ -164,6 +168,7 @@ module.exports = class PluginManager {
164
168
  clientIpEnabled,
165
169
  clientIpHeader,
166
170
  DD_TRACE_MEMCACHED_COMMAND_ENABLED,
171
+ DD_TRACE_OTEL_SEMANTICS_ENABLED,
167
172
  DD_TEST_SESSION_NAME,
168
173
  DD_AGENTLESS_LOG_SUBMISSION_ENABLED,
169
174
  isTestDynamicInstrumentationEnabled,
@@ -181,6 +186,7 @@ module.exports = class PluginManager {
181
186
  dbmPropagationMode,
182
187
  dsmEnabled,
183
188
  DD_TRACE_MEMCACHED_COMMAND_ENABLED,
189
+ DD_TRACE_OTEL_SEMANTICS_ENABLED,
184
190
  site,
185
191
  url,
186
192
  headers: headerTags || [],
@@ -31,6 +31,7 @@ const Plugin = require('./plugin')
31
31
  const { getRepositoryRoot } = require('./util/git')
32
32
  const {
33
33
  getTestEnvironmentMetadata,
34
+ getTestLevelsMetadataTags,
34
35
  getTestSessionName,
35
36
  getCodeOwnersFileEntries,
36
37
  getTestParentSpan,
@@ -44,6 +45,7 @@ const {
44
45
  TEST_MODULE_ID,
45
46
  TEST_SESSION_ID,
46
47
  TEST_COMMAND,
48
+ TEST_LEVELS_METADATA,
47
49
  TEST_MODULE,
48
50
  TEST_SESSION_NAME,
49
51
  getTestSuiteCommonTags,
@@ -219,7 +221,13 @@ module.exports = class CiPlugin extends Plugin {
219
221
  this.testEnvironmentMetadata
220
222
  )
221
223
 
222
- const metadataTags = { '*': { [TEST_COMMAND]: command, [TEST_SESSION_NAME]: testSessionName } }
224
+ const metadataTags = {
225
+ [TEST_LEVELS_METADATA]: {
226
+ [TEST_COMMAND]: command,
227
+ [TEST_SESSION_NAME]: testSessionName,
228
+ ...getTestLevelsMetadataTags(this.testEnvironmentMetadata),
229
+ },
230
+ }
223
231
  // tracer might not be initialized correctly
224
232
  if (this.tracer._exporter.addMetadataTags) {
225
233
  this.tracer._exporter.addMetadataTags(metadataTags)
@@ -442,6 +450,28 @@ module.exports = class CiPlugin extends Plugin {
442
450
  }
443
451
  }
444
452
 
453
+ /**
454
+ * Updates repository-root-dependent state when a worker receives the root from
455
+ * the coordinator process after plugin configuration.
456
+ *
457
+ * @param {string|undefined} repositoryRoot - Repository root discovered by the coordinator process.
458
+ * @param {Array<{ pattern: string, owners: string[] }>|null|undefined} codeOwnersEntries
459
+ * Parsed CODEOWNERS entries discovered by the coordinator process.
460
+ * @returns {void}
461
+ */
462
+ _setRepositoryRoot (repositoryRoot, codeOwnersEntries) {
463
+ if (codeOwnersEntries !== undefined) {
464
+ this.codeOwnersEntries = codeOwnersEntries
465
+ }
466
+
467
+ if (!repositoryRoot || repositoryRoot === this.repositoryRoot) return
468
+
469
+ this.repositoryRoot = repositoryRoot
470
+ if (codeOwnersEntries === undefined) {
471
+ this.codeOwnersEntries = getCodeOwnersFileEntries(this.repositoryRoot)
472
+ }
473
+ }
474
+
445
475
  /**
446
476
  * Returns request error tags from the test session span for propagation to module, suite and test spans.
447
477
  * @returns {Record<string, string>}
@@ -610,6 +640,8 @@ module.exports = class CiPlugin extends Plugin {
610
640
  const workerTestFramework = WORKER_EXPORTER_TO_TEST_FRAMEWORK[exporter]
611
641
  this.shouldSkipGitMetadataExtraction = workerTestFramework &&
612
642
  TEST_FRAMEWORKS_TO_SKIP_GIT_METADATA_EXTRACTION.has(workerTestFramework)
643
+ const shouldDeferCodeOwnersEntries = workerTestFramework === 'vitest'
644
+ const shouldDeferRepositoryRoot = workerTestFramework === 'vitest'
613
645
 
614
646
  this.testEnvironmentMetadata = getTestEnvironmentMetadata(
615
647
  this.constructor.id,
@@ -635,9 +667,10 @@ module.exports = class CiPlugin extends Plugin {
635
667
  [GIT_COMMIT_HEAD_MESSAGE]: commitHeadMessage,
636
668
  } = this.testEnvironmentMetadata
637
669
 
638
- this.repositoryRoot = repositoryRoot || getRepositoryRoot() || process.cwd()
670
+ this.repositoryRoot = repositoryRoot ||
671
+ (shouldDeferRepositoryRoot ? process.cwd() : getRepositoryRoot() || process.cwd())
639
672
 
640
- this.codeOwnersEntries = getCodeOwnersFileEntries(this.repositoryRoot)
673
+ this.codeOwnersEntries = shouldDeferCodeOwnersEntries ? null : getCodeOwnersFileEntries(this.repositoryRoot)
641
674
 
642
675
  this.ciProviderName = ciProviderName
643
676
 
@@ -8,6 +8,7 @@ const plugins = {
8
8
  get '@azure/event-hubs' () { return require('../../../datadog-plugin-azure-event-hubs/src') },
9
9
  get '@azure/functions' () { return require('../../../datadog-plugin-azure-functions/src') },
10
10
  get '@modelcontextprotocol/sdk' () { return require('../../../datadog-plugin-modelcontextprotocol-sdk/src') },
11
+ get '@aws/durable-execution-sdk-js' () { return require('../../../datadog-plugin-aws-durable-execution-sdk-js/src') },
11
12
  get 'durable-functions' () { return require('../../../datadog-plugin-azure-durable-functions/src') },
12
13
  get '@azure/service-bus' () { return require('../../../datadog-plugin-azure-service-bus/src') },
13
14
  get '@cucumber/cucumber' () { return require('../../../datadog-plugin-cucumber/src') },
@@ -55,6 +56,7 @@ const plugins = {
55
56
  get express () { return require('../../../datadog-plugin-express/src') },
56
57
  get fastify () { return require('../../../datadog-plugin-fastify/src') },
57
58
  get 'find-my-way' () { return require('../../../datadog-plugin-find-my-way/src') },
59
+ get fs () { return require('../../../datadog-plugin-fs/src') },
58
60
  get 'global:fetch' () { return require('../../../datadog-plugin-fetch/src') },
59
61
  get graphql () { return require('../../../datadog-plugin-graphql/src') },
60
62
  get grpc () { return require('../../../datadog-plugin-grpc/src') },
@@ -97,6 +99,7 @@ const plugins = {
97
99
  get net () { return require('../../../datadog-plugin-net/src') },
98
100
  get next () { return require('../../../datadog-plugin-next/src') },
99
101
  get 'node:dns' () { return require('../../../datadog-plugin-dns/src') },
102
+ get 'node:fs' () { return require('../../../datadog-plugin-fs/src') },
100
103
  get 'node:http' () { return require('../../../datadog-plugin-http/src') },
101
104
  get 'node:http2' () { return require('../../../datadog-plugin-http2/src') },
102
105
  get 'node:https' () { return require('../../../datadog-plugin-http/src') },