dd-trace 5.132.0 → 5.134.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 (231) hide show
  1. package/ci/diagnose.js +9 -14
  2. package/ci/init.js +1 -2
  3. package/ci/test-optimization-validation/ci-discovery.js +9 -4
  4. package/ci/test-optimization-validation/executable.js +1 -5
  5. package/ci/test-optimization-validation/framework-adapters/cypress.js +1 -4
  6. package/ci/test-optimization-validation/framework-adapters/vitest.js +1 -1
  7. package/ci/test-optimization-validation/generated-files.js +6 -4
  8. package/ci/test-optimization-validation/generated-test-contract.js +7 -3
  9. package/ci/test-optimization-validation/manifest-scaffold.js +7 -2
  10. package/ci/test-optimization-validation/manifest-schema.js +6 -7
  11. package/ci/test-optimization-validation/report-writer.js +6 -2
  12. package/ci/test-optimization-validation/runner-command.js +2 -4
  13. package/ci/test-optimization-validation/runner-contract.js +1 -2
  14. package/ci/test-optimization-validation/scenarios/auto-test-retries.js +1 -15
  15. package/ci/vitest-no-worker-init-runner-setup.mjs +27 -0
  16. package/ci/vitest-no-worker-init-setup.mjs +10 -7
  17. package/index.d.ts +41 -19
  18. package/initialize.mjs +1 -3
  19. package/openfeature/rules-based.d.ts +11 -0
  20. package/openfeature/rules-based.js +7 -0
  21. package/package.json +25 -22
  22. package/packages/datadog-core/src/storage.js +16 -0
  23. package/packages/datadog-esbuild/index.js +18 -12
  24. package/packages/datadog-instrumentations/index.js +2 -1
  25. package/packages/datadog-instrumentations/src/aerospike.js +3 -3
  26. package/packages/datadog-instrumentations/src/ai.js +3 -3
  27. package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +0 -6
  28. package/packages/datadog-instrumentations/src/aws-sdk.js +21 -13
  29. package/packages/datadog-instrumentations/src/cassandra-driver.js +25 -20
  30. package/packages/datadog-instrumentations/src/claude-agent-sdk.js +9 -23
  31. package/packages/datadog-instrumentations/src/cucumber.js +65 -41
  32. package/packages/datadog-instrumentations/src/elasticsearch.js +1 -5
  33. package/packages/datadog-instrumentations/src/electron.js +6 -6
  34. package/packages/datadog-instrumentations/src/fastify.js +13 -4
  35. package/packages/datadog-instrumentations/src/fs.js +2 -2
  36. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +9 -5
  37. package/packages/datadog-instrumentations/src/grpc/client.js +2 -0
  38. package/packages/datadog-instrumentations/src/helpers/bundler-register.js +28 -9
  39. package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +1 -2
  40. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  41. package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -1
  42. package/packages/datadog-instrumentations/src/helpers/register.js +45 -1
  43. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -0
  44. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +89 -6
  45. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql-jit.js +5 -6
  46. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/jest.js +12 -0
  47. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/postgres.js +48 -31
  48. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/vitest.js +8 -0
  49. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +7 -7
  50. package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +5 -0
  51. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms/postgres.js +42 -4
  52. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +7 -10
  53. package/packages/datadog-instrumentations/src/ioredis.js +7 -5
  54. package/packages/datadog-instrumentations/src/iovalkey.js +7 -5
  55. package/packages/datadog-instrumentations/src/jest.js +72 -67
  56. package/packages/datadog-instrumentations/src/knex.js +9 -5
  57. package/packages/datadog-instrumentations/src/mariadb-bundle.js +3 -3
  58. package/packages/datadog-instrumentations/src/mocha/common.js +20 -8
  59. package/packages/datadog-instrumentations/src/mocha/main.js +140 -43
  60. package/packages/datadog-instrumentations/src/mocha/utils.js +38 -4
  61. package/packages/datadog-instrumentations/src/mocha/worker.js +1 -2
  62. package/packages/datadog-instrumentations/src/mongodb-core.js +3 -3
  63. package/packages/datadog-instrumentations/src/mongoose.js +3 -3
  64. package/packages/datadog-instrumentations/src/nova-sonic/audio.js +173 -0
  65. package/packages/datadog-instrumentations/src/nova-sonic/index.js +209 -0
  66. package/packages/datadog-instrumentations/src/nova-sonic/session.js +492 -0
  67. package/packages/datadog-instrumentations/src/openai-realtime/index.js +18 -6
  68. package/packages/datadog-instrumentations/src/openai-realtime/session.js +1 -1
  69. package/packages/datadog-instrumentations/src/openai.js +7 -0
  70. package/packages/datadog-instrumentations/src/pino.js +5 -6
  71. package/packages/datadog-instrumentations/src/playwright.js +2 -0
  72. package/packages/datadog-instrumentations/src/redis.js +27 -13
  73. package/packages/datadog-instrumentations/src/router.js +30 -0
  74. package/packages/datadog-instrumentations/src/rum-browser-scripts.js +2 -6
  75. package/packages/datadog-instrumentations/src/stripe.js +23 -12
  76. package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +8 -5
  77. package/packages/datadog-instrumentations/src/vitest-main.js +16 -18
  78. package/packages/datadog-instrumentations/src/vitest-util.js +7 -4
  79. package/packages/datadog-instrumentations/src/vitest-worker.js +1 -2
  80. package/packages/datadog-instrumentations/src/vitest.js +9 -1
  81. package/packages/datadog-instrumentations/src/webdriverio.js +5 -8
  82. package/packages/datadog-instrumentations/src/ws.js +1 -4
  83. package/packages/datadog-plugin-amqplib/src/client.js +1 -2
  84. package/packages/datadog-plugin-avsc/src/schema_iterator.js +1 -5
  85. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/handler.js +1 -2
  86. package/packages/datadog-plugin-aws-sdk/src/base.js +5 -8
  87. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/index.js +18 -0
  88. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/sonic.js +45 -0
  89. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +9 -3
  90. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +2 -5
  91. package/packages/datadog-plugin-azure-durable-functions/src/index.js +5 -4
  92. package/packages/datadog-plugin-azure-functions/src/index.js +5 -3
  93. package/packages/datadog-plugin-claude-agent-sdk/src/index.js +0 -2
  94. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +4 -5
  95. package/packages/datadog-plugin-cypress/src/index.js +6 -6
  96. package/packages/datadog-plugin-cypress/src/source-map-utils.js +1 -2
  97. package/packages/datadog-plugin-cypress/src/support.js +3 -4
  98. package/packages/datadog-plugin-express/src/code_origin.js +1 -2
  99. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -2
  100. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +1 -2
  101. package/packages/datadog-plugin-graphql/src/execute.js +5 -5
  102. package/packages/datadog-plugin-grpc/src/util.js +1 -2
  103. package/packages/datadog-plugin-kafkajs/src/producer.js +1 -2
  104. package/packages/datadog-plugin-mocha/src/index.js +7 -10
  105. package/packages/datadog-plugin-mocha/src/webdriverio-video.js +8 -4
  106. package/packages/datadog-plugin-mongodb-core/src/query.js +8 -5
  107. package/packages/datadog-plugin-next/src/index.js +1 -2
  108. package/packages/datadog-plugin-openai/src/tracing.js +5 -2
  109. package/packages/datadog-plugin-openai-agents/src/integration.js +6 -2
  110. package/packages/datadog-plugin-openai-agents/src/processor.js +2 -4
  111. package/packages/datadog-plugin-postgres/src/index.js +24 -0
  112. package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +1 -5
  113. package/packages/datadog-plugin-rhea/src/consumer.js +1 -4
  114. package/packages/datadog-plugin-vitest/src/index.js +5 -2
  115. package/packages/datadog-shimmer/src/shimmer.js +5 -4
  116. package/packages/datadog-webpack/index.js +55 -43
  117. package/packages/datadog-webpack/src/loader.js +56 -8
  118. package/packages/dd-trace/src/aiguard/evaluation.js +143 -1
  119. package/packages/dd-trace/src/aiguard/integrations/vercel-ai.js +2 -4
  120. package/packages/dd-trace/src/aiguard/messages/utils.js +1 -2
  121. package/packages/dd-trace/src/aiguard/redaction.js +8 -2
  122. package/packages/dd-trace/src/appsec/api_security/normalized-route.js +3 -2
  123. package/packages/dd-trace/src/appsec/api_security/sampler.js +2 -6
  124. package/packages/dd-trace/src/appsec/downstream_requests.js +1 -9
  125. package/packages/dd-trace/src/appsec/handlers/http-request.js +3 -9
  126. package/packages/dd-trace/src/appsec/handlers/http-response.js +7 -2
  127. package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +4 -3
  128. package/packages/dd-trace/src/appsec/iast/analyzers/set-cookies-header-interceptor.js +1 -4
  129. package/packages/dd-trace/src/appsec/iast/path-line.js +2 -1
  130. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +7 -1
  131. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -3
  132. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -3
  133. package/packages/dd-trace/src/appsec/iast/telemetry/iast-metric.js +1 -6
  134. package/packages/dd-trace/src/appsec/lambda.js +1 -3
  135. package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +37 -27
  136. package/packages/dd-trace/src/appsec/rasp/lfi.js +9 -5
  137. package/packages/dd-trace/src/appsec/reporter.js +21 -1
  138. package/packages/dd-trace/src/appsec/stack_trace.js +4 -4
  139. package/packages/dd-trace/src/ci-visibility/dynamic-atr-retries.js +3 -6
  140. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +3 -2
  141. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +1 -1
  142. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +13 -7
  143. package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +1 -2
  144. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +2 -8
  145. package/packages/dd-trace/src/ci-visibility/resolve-runfile-path.js +54 -0
  146. package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +5 -8
  147. package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +2 -53
  148. package/packages/dd-trace/src/config/config-types.d.ts +2 -2
  149. package/packages/dd-trace/src/config/defaults.js +5 -5
  150. package/packages/dd-trace/src/config/generated-config-types.d.ts +10 -0
  151. package/packages/dd-trace/src/config/helper.js +34 -3
  152. package/packages/dd-trace/src/config/index.js +55 -9
  153. package/packages/dd-trace/src/config/normalize-service.js +1 -1
  154. package/packages/dd-trace/src/config/parsers.js +2 -2
  155. package/packages/dd-trace/src/config/supported-configurations.json +44 -0
  156. package/packages/dd-trace/src/datastreams/processor.js +3 -2
  157. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -4
  158. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +6 -5
  159. package/packages/dd-trace/src/debugger/devtools_client/condition.js +5 -5
  160. package/packages/dd-trace/src/debugger/devtools_client/send.js +1 -0
  161. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +4 -6
  162. package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -0
  163. package/packages/dd-trace/src/debugger/guardrail-metrics.js +2 -2
  164. package/packages/dd-trace/src/debugger/unsupported-runtime.js +16 -0
  165. package/packages/dd-trace/src/dogstatsd.js +1 -1
  166. package/packages/dd-trace/src/encode/tags-processors.js +2 -2
  167. package/packages/dd-trace/src/exporters/common/request.js +1 -5
  168. package/packages/dd-trace/src/id.js +14 -1
  169. package/packages/dd-trace/src/lambda/handler.js +179 -19
  170. package/packages/dd-trace/src/lambda/index.js +15 -1
  171. package/packages/dd-trace/src/lambda/runtime/patch.js +34 -7
  172. package/packages/dd-trace/src/llmobs/agent-manifest.js +19 -2
  173. package/packages/dd-trace/src/llmobs/audio-utils.js +3 -2
  174. package/packages/dd-trace/src/llmobs/constants/tags.js +15 -0
  175. package/packages/dd-trace/src/llmobs/experiments/experiment.js +1 -1
  176. package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +15 -0
  177. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +1 -2
  178. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +1 -3
  179. package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
  180. package/packages/dd-trace/src/llmobs/plugins/nova-sonic.js +92 -0
  181. package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +5 -0
  182. package/packages/dd-trace/src/llmobs/plugins/openai/index.js +64 -2
  183. package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +38 -0
  184. package/packages/dd-trace/src/llmobs/prompts/manager.js +5 -7
  185. package/packages/dd-trace/src/llmobs/prompts/prompt.js +1 -1
  186. package/packages/dd-trace/src/llmobs/sdk.js +15 -4
  187. package/packages/dd-trace/src/llmobs/span_processor.js +13 -2
  188. package/packages/dd-trace/src/llmobs/tagger.js +20 -10
  189. package/packages/dd-trace/src/llmobs/util.js +11 -6
  190. package/packages/dd-trace/src/llmobs/writers/base.js +4 -5
  191. package/packages/dd-trace/src/log/log.js +1 -5
  192. package/packages/dd-trace/src/openfeature/evaluation-telemetry-opt-out-hook.js +51 -0
  193. package/packages/dd-trace/src/openfeature/flagging_provider.js +48 -21
  194. package/packages/dd-trace/src/openfeature/index.js +6 -0
  195. package/packages/dd-trace/src/openfeature/writers/util.js +4 -4
  196. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +1 -1
  197. package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +1 -1
  198. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -2
  199. package/packages/dd-trace/src/opentelemetry/otlp/common.proto +1 -1
  200. package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +24 -24
  201. package/packages/dd-trace/src/opentracing/propagation/text_map.js +53 -13
  202. package/packages/dd-trace/src/otel-sampling.js +4 -5
  203. package/packages/dd-trace/src/otel-thread-ctx.js +79 -13
  204. package/packages/dd-trace/src/plugin_manager.js +1 -2
  205. package/packages/dd-trace/src/plugins/database.js +7 -16
  206. package/packages/dd-trace/src/plugins/tracing.js +0 -1
  207. package/packages/dd-trace/src/plugins/util/git.js +99 -59
  208. package/packages/dd-trace/src/plugins/util/inferred_proxy.js +1 -5
  209. package/packages/dd-trace/src/plugins/util/stacktrace.js +2 -1
  210. package/packages/dd-trace/src/plugins/util/test.js +50 -4
  211. package/packages/dd-trace/src/plugins/util/web.js +90 -20
  212. package/packages/dd-trace/src/priority_sampler.js +1 -2
  213. package/packages/dd-trace/src/profiling/profiler.js +4 -6
  214. package/packages/dd-trace/src/proxy.js +1 -2
  215. package/packages/dd-trace/src/ritm.js +4 -2
  216. package/packages/dd-trace/src/serverless.js +5 -0
  217. package/packages/dd-trace/src/span_processor.js +13 -17
  218. package/packages/dd-trace/src/span_stats.js +4 -1
  219. package/packages/dd-trace/src/telemetry/endpoints.js +1 -3
  220. package/packages/dd-trace/src/telemetry/logs/log-collector.js +1 -1
  221. package/packages/dd-trace/src/util.js +37 -4
  222. package/packages/dd-trace/src/web-tags-cache.js +6 -2
  223. package/vendor/dist/@apm-js-collab/code-transformer/index.js +8 -8
  224. package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
  225. package/vendor/dist/@datadog/openfeature-node-server/rules-based/LICENSE +201 -0
  226. package/vendor/dist/@datadog/openfeature-node-server/rules-based/index.d.ts +925 -0
  227. package/vendor/dist/@datadog/openfeature-node-server/rules-based/index.js +1 -0
  228. package/vendor/dist/@datadog/sketches-js/index.js +1 -1
  229. package/vendor/dist/protobufjs/index.js +1 -1
  230. package/vendor/dist/protobufjs/minimal/index.js +1 -1
  231. package/vendor/dist/shell-quote/index.js +1 -1
@@ -5,6 +5,7 @@ const path = require('node:path')
5
5
 
6
6
  const log = require('../log')
7
7
  const { getNumFromKnownTests } = require('../plugins/util/test')
8
+ const resolveRunfilePath = require('./resolve-runfile-path')
8
9
  const { parseKnownTestsResponse } = require('./early-flake-detection/get-known-tests')
9
10
  const {
10
11
  logSkippableSuitesResponse,
@@ -38,16 +39,12 @@ const HTTP_CACHE_FOLDER_NAME = 'http'
38
39
 
39
40
  const ENV_MANIFEST_FILE = 'TEST_OPTIMIZATION_MANIFEST_FILE'
40
41
  const ENV_MANIFEST_FILE_ALIAS = 'DD_TEST_OPTIMIZATION_MANIFEST_FILE'
41
- const ENV_RUNFILES_DIR = 'RUNFILES_DIR'
42
- const ENV_RUNFILES_MANIFEST_FILE = 'RUNFILES_MANIFEST_FILE'
43
- const ENV_TEST_SRCDIR = 'TEST_SRCDIR'
44
42
 
45
43
  const SETTINGS_FILE_NAME = 'settings.json'
46
44
  const KNOWN_TESTS_FILE_NAME = 'known_tests.json'
47
45
  const SKIPPABLE_TESTS_FILE_NAME = 'skippable_tests.json'
48
46
  const TEST_MANAGEMENT_FILE_NAME = 'test_management.json'
49
47
 
50
- const RUNFILES_MANIFEST_SEPARATOR = ' '
51
48
  const DEFAULT_VALIDATION_MAX_FILE_BYTES = 1024 * 1024
52
49
  const DEFAULT_VALIDATION_MAX_ENTRIES = 100_000
53
50
  const DEFAULT_VALIDATION_MAX_NESTING_DEPTH = 32
@@ -250,7 +247,7 @@ class TestOptimizationHttpCache {
250
247
  const manifestFile = this._env[ENV_MANIFEST_FILE] || this._env[ENV_MANIFEST_FILE_ALIAS]
251
248
  if (!manifestFile) return
252
249
 
253
- const resolvedManifestPath = this._resolveRunfilePath(manifestFile)
250
+ const resolvedManifestPath = resolveRunfilePath(manifestFile, this._env)
254
251
  if (fs.existsSync(resolvedManifestPath)) {
255
252
  return resolvedManifestPath
256
253
  }
@@ -280,54 +277,6 @@ class TestOptimizationHttpCache {
280
277
  }
281
278
  }
282
279
 
283
- _resolveRunfilePath (manifestFile) {
284
- if (fs.existsSync(manifestFile)) {
285
- return manifestFile
286
- }
287
-
288
- const runfilesDir = this._env[ENV_RUNFILES_DIR]
289
- if (runfilesDir) {
290
- const candidate = path.join(runfilesDir, manifestFile)
291
- if (fs.existsSync(candidate)) {
292
- return candidate
293
- }
294
- }
295
-
296
- const runfilesManifestCandidate = this._resolveRunfilePathFromManifest(manifestFile)
297
- if (runfilesManifestCandidate) {
298
- return runfilesManifestCandidate
299
- }
300
-
301
- const testSrcdir = this._env[ENV_TEST_SRCDIR]
302
- if (testSrcdir) {
303
- const candidate = path.join(testSrcdir, manifestFile)
304
- if (fs.existsSync(candidate)) {
305
- return candidate
306
- }
307
- }
308
-
309
- return manifestFile
310
- }
311
-
312
- _resolveRunfilePathFromManifest (manifestFile) {
313
- const runfilesManifest = this._env[ENV_RUNFILES_MANIFEST_FILE]
314
- if (!runfilesManifest || !fs.existsSync(runfilesManifest)) return
315
-
316
- try {
317
- const lines = fs.readFileSync(runfilesManifest, 'utf8').split('\n')
318
- for (const line of lines) {
319
- const separatorIndex = line.indexOf(RUNFILES_MANIFEST_SEPARATOR)
320
- if (separatorIndex <= 0) continue
321
- if (line.slice(0, separatorIndex) !== manifestFile) continue
322
-
323
- const resolvedPath = line.slice(separatorIndex + 1).trim()
324
- if (resolvedPath) return resolvedPath
325
- }
326
- } catch (err) {
327
- log.debug('Failed to resolve Test Optimization HTTP cache manifest from %s: %s', runfilesManifest, err.message)
328
- }
329
- }
330
-
331
280
  _readManifestVersion (manifestPath) {
332
281
  try {
333
282
  this._assertValidationFixtureFile(manifestPath)
@@ -72,9 +72,9 @@ export type ConfigPathValue<TPath extends ConfigPath> = ConfigPathValueFor<Confi
72
72
  export type ConfigDefaults = Partial<{ [TPath in ConfigPath]: ConfigPathValue<TPath> }>
73
73
  export type ConfigurationOption = {
74
74
  property?: string
75
- parser?: (value: unknown, optionName: string, source: string) => unknown
75
+ parser?: (value: unknown, optionName: string, source: string, reportInvalid?: boolean) => unknown
76
76
  type: string
77
77
  canonicalName?: string
78
- transformer?: (value: unknown, optionName: string, source: string) => unknown
78
+ transformer?: (value: unknown, optionName: string, source: string, reportInvalid?: boolean) => unknown
79
79
  telemetryTransformer?: (value: unknown) => unknown
80
80
  }
@@ -191,10 +191,10 @@ const optionsTable = {
191
191
  },
192
192
  }
193
193
 
194
- const parser = (value, optionName, source) => {
194
+ const parser = (value, optionName, source, reportInvalid = true) => {
195
195
  const { type, canonicalName = optionName } = configurationsTable[optionName]
196
196
  const parsed = parsers[type](value, canonicalName)
197
- if (parsed === undefined) {
197
+ if (parsed === undefined && reportInvalid) {
198
198
  warnInvalidValue(value, optionName, source, `Invalid ${type} input`)
199
199
  }
200
200
  return parsed
@@ -249,13 +249,13 @@ for (const [canonicalName, entries] of Object.entries(supportedConfigurations))
249
249
  regExps[entry.allowed] ??= new RegExp(`^(${entry.allowed})$`, 'i')
250
250
  const allowed = regExps[entry.allowed]
251
251
  const originalTransform = transformer
252
- transformer = (value, optionName, source) => {
252
+ transformer = (value, optionName, source, reportInvalid = true) => {
253
253
  if (!allowed.test(value)) {
254
- warnInvalidValue(value, optionName, source, 'Invalid value')
254
+ if (reportInvalid) warnInvalidValue(value, optionName, source, 'Invalid value')
255
255
  return
256
256
  }
257
257
  if (originalTransform) {
258
- value = originalTransform(value)
258
+ value = originalTransform(value, optionName, source, reportInvalid)
259
259
  }
260
260
  return value
261
261
  }
@@ -3,6 +3,8 @@
3
3
 
4
4
  export interface GeneratedConfig {
5
5
  _DD_APM_TRACING_AGENTLESS_ENABLED: boolean;
6
+ _DD_TEST_PARALLELIZATION_ENABLED: boolean | undefined;
7
+ _DD_TEST_PARALLELIZATION_METADATA_FILE: string | undefined;
6
8
  _DD_TRACE_METRICS_OTEL_FLUSH_INTERVAL: number;
7
9
  aiguard: {
8
10
  DD_AI_GUARD_ANALYZE_STREAM_RESPONSES_ENABLED: boolean;
@@ -75,6 +77,7 @@ export interface GeneratedConfig {
75
77
  DD_APM_FLUSH_DEADLINE_MILLISECONDS: number;
76
78
  DD_APP_KEY: string | undefined;
77
79
  DD_AZURE_RESOURCE_GROUP: string | undefined;
80
+ DD_BUNDLER_INJECT_GIT_METADATA: boolean;
78
81
  DD_CRASHTRACKING_ENABLED: boolean;
79
82
  DD_CUSTOM_PARENT_ID: string | undefined;
80
83
  DD_CUSTOM_TRACE_ID: string | undefined;
@@ -435,6 +438,8 @@ export interface GeneratedConfig {
435
438
  DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_POLL_INTERVAL_SECONDS: number;
436
439
  DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_REQUEST_TIMEOUT_SECONDS: number;
437
440
  DD_FEATURE_FLAGS_ENABLED: boolean;
441
+ DD_FEATURE_FLAGS_EVALUATION_TELEMETRY_PER_SUBJECT_OPT_OUT_ENABLED: boolean;
442
+ DD_FEATURE_FLAGS_EXPOSURES_DATADOG_LOGGING_ENABLED: boolean;
438
443
  DD_FLAGGING_EVALUATION_COUNTS_ENABLED: boolean;
439
444
  };
440
445
  flushInterval: number;
@@ -606,6 +611,8 @@ export interface GeneratedConfig {
606
611
 
607
612
  export interface GeneratedEnvVarConfig {
608
613
  _DD_APM_TRACING_AGENTLESS_ENABLED: boolean;
614
+ _DD_TEST_PARALLELIZATION_ENABLED: boolean | undefined;
615
+ _DD_TEST_PARALLELIZATION_METADATA_FILE: string | undefined;
609
616
  _DD_TRACE_METRICS_OTEL_FLUSH_INTERVAL: number;
610
617
  DATADOG_API_KEY: string | undefined;
611
618
  DD_ACTION_EXECUTION_ID: string | undefined;
@@ -656,6 +663,7 @@ export interface GeneratedEnvVarConfig {
656
663
  DD_APPSEC_TRACE_RATE_LIMIT: number;
657
664
  DD_APPSEC_WAF_TIMEOUT: number;
658
665
  DD_AZURE_RESOURCE_GROUP: string | undefined;
666
+ DD_BUNDLER_INJECT_GIT_METADATA: boolean;
659
667
  DD_CIVISIBILITY_AGENTLESS_ENABLED: boolean;
660
668
  DD_CIVISIBILITY_AGENTLESS_URL: URL | undefined;
661
669
  DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER: string | undefined;
@@ -718,6 +726,8 @@ export interface GeneratedEnvVarConfig {
718
726
  DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_POLL_INTERVAL_SECONDS: number;
719
727
  DD_FEATURE_FLAGS_CONFIGURATION_SOURCE_AGENTLESS_REQUEST_TIMEOUT_SECONDS: number;
720
728
  DD_FEATURE_FLAGS_ENABLED: boolean;
729
+ DD_FEATURE_FLAGS_EVALUATION_TELEMETRY_PER_SUBJECT_OPT_OUT_ENABLED: boolean;
730
+ DD_FEATURE_FLAGS_EXPOSURES_DATADOG_LOGGING_ENABLED: boolean;
721
731
  DD_FLAGGING_EVALUATION_COUNTS_ENABLED: boolean;
722
732
  DD_GIT_BRANCH: string | undefined;
723
733
  DD_GIT_COMMIT_AUTHOR_DATE: string | undefined;
@@ -180,14 +180,17 @@ function loadConfigurationsTable () {
180
180
  * @param {string} name Canonical or alias environment variable name.
181
181
  * @param {string} value Raw value read from an environment source.
182
182
  * @param {'env_var'|'fleet_stable_config'|'local_stable_config'} source Source the value was read from.
183
+ * @param {boolean} [reportInvalid] Whether invalid values should produce configuration diagnostics.
183
184
  * @returns {string | number | boolean | object | undefined}
184
185
  */
185
- function parseConfigurationValue (name, value, source) {
186
+ function parseConfigurationValue (name, value, source, reportInvalid = true) {
186
187
  loadConfigurationsTable()
187
188
  const canonical = aliasToCanonical[name] ?? name
188
189
  const entry = configurationsTable[canonical]
189
- const parsed = entry.parser(value, canonical, source)
190
- return parsed !== undefined && entry.transformer ? entry.transformer(parsed, canonical, source) : parsed
190
+ const parsed = entry.parser(value, canonical, source, reportInvalid)
191
+ return parsed !== undefined && entry.transformer
192
+ ? entry.transformer(parsed, canonical, source, reportInvalid)
193
+ : parsed
191
194
  }
192
195
 
193
196
  /**
@@ -376,4 +379,32 @@ module.exports = {
376
379
  }
377
380
  }
378
381
  },
382
+
383
+ /**
384
+ * Returns the environment variable name from the highest-priority source whose value is valid.
385
+ *
386
+ * @param {string} name Environment variable name
387
+ */
388
+ getValidatedConfiguredEnvName (name) {
389
+ validateAccess(name)
390
+
391
+ if (!stableConfigLoaded) {
392
+ loadStableConfig()
393
+ }
394
+
395
+ const sources = [
396
+ [fleetStableConfig, 'fleet_stable_config'],
397
+ [process.env, 'env_var'],
398
+ [localStableConfig, 'local_stable_config'],
399
+ ]
400
+ for (const [source, sourceName] of sources) {
401
+ if (source !== undefined) {
402
+ const fromSource = getEnvNameFromSource(name, source)
403
+ if (fromSource !== undefined &&
404
+ parseConfigurationValue(fromSource, source[fromSource], sourceName, false) !== undefined) {
405
+ return fromSource
406
+ }
407
+ }
408
+ }
409
+ },
379
410
  }
@@ -12,6 +12,7 @@ const uuid = require('../../../../vendor/dist/crypto-randomuuid') // we need to
12
12
  const set = require('../../../datadog-core/src/utils/src/set')
13
13
  const { DD_MAJOR, NODE_MAJOR } = require('../../../../version')
14
14
  const log = require('../log')
15
+ const { warn } = require('../log/writer')
15
16
  const pkg = require('../pkg')
16
17
  const { isTrue } = require('../util')
17
18
  const telemetry = require('../telemetry')
@@ -25,6 +26,7 @@ const {
25
26
  const { ORIGIN_KEY, DATADOG_MINI_AGENT_PATH } = require('../constants')
26
27
  const { appendRules } = require('../payload-tagging/config')
27
28
  const { createSiteUrl } = require('../exporters/common/url')
29
+ const { getUnsupportedRuntime } = require('../debugger/unsupported-runtime')
28
30
  const ConfigBase = require('./config-base')
29
31
  const {
30
32
  getEnvironmentVariable,
@@ -124,6 +126,8 @@ const changeTracker = {
124
126
  */
125
127
  function undo (config, source) {
126
128
  for (const name of changeTracker[source]) {
129
+ if (trackedConfigOrigins.get(name) !== source) continue
130
+
127
131
  const entry = changeTracker.baseValuesByPath[name] ?? { source: 'default', value: defaults[name] }
128
132
  setAndTrack(config, name, entry.value, undefined, entry.source)
129
133
  }
@@ -198,6 +202,12 @@ class Config extends ConfigBase {
198
202
  */
199
203
  #parsedDdTags
200
204
 
205
+ /**
206
+ * Options already explained as deactivated, so recalculating the config doesn't repeat the explanation
207
+ * @type {Set<ConfigPath>}
208
+ */
209
+ #explainedDeactivations = new Set()
210
+
201
211
  /**
202
212
  * @type {Record<string, string>}
203
213
  */
@@ -248,9 +258,9 @@ class Config extends ConfigBase {
248
258
  const { experimental, ...rest } = options
249
259
  if (experimental) {
250
260
  // @ts-expect-error - Difficult to type this correctly.
251
- this.#applyOptions(experimental, 'code', 'experimental')
261
+ this.#applyOptions(experimental, 'experimental')
252
262
  }
253
- this.#applyOptions(rest, 'code')
263
+ this.#applyOptions(rest)
254
264
  this.#applyCalculated()
255
265
 
256
266
  warnWrongOtelSettings()
@@ -280,10 +290,9 @@ class Config extends ConfigBase {
280
290
 
281
291
  /**
282
292
  * @param {TracerOptions} options
283
- * @param {'code'} source
284
293
  * @param {string} [root]
285
294
  */
286
- #applyOptions (options, source, root = '') {
295
+ #applyOptions (options, root = '') {
287
296
  for (const [name, value] of Object.entries(options)) {
288
297
  const fullName = root ? `${root}.${name}` : name
289
298
  let entry = optionsTable[fullName]
@@ -300,7 +309,7 @@ class Config extends ConfigBase {
300
309
  // Defining an option that receives an object as value may not contain a property that is also
301
310
  // potentially a nested property!
302
311
  if (Object.hasOwn(value, nestedProperty)) {
303
- this.#applyOptions(value, source, fullName)
312
+ this.#applyOptions(value, fullName)
304
313
  matched = true
305
314
  break
306
315
  }
@@ -316,7 +325,7 @@ class Config extends ConfigBase {
316
325
  // TracePropagationStyle is special. It is a single option that is used to set both inject and extract.
317
326
  // TODO: Consider what to do with this later
318
327
  // @ts-expect-error - Difficult to type this correctly.
319
- this.#applyOptions({ inject: value, extract: value }, source, 'tracePropagationStyle')
328
+ this.#applyOptions({ inject: value, extract: value }, 'tracePropagationStyle')
320
329
  } else {
321
330
  log.warn('Unknown option %s with value %o', fullName, value)
322
331
  }
@@ -325,12 +334,12 @@ class Config extends ConfigBase {
325
334
  }
326
335
  const coerced = programmaticTypeCoercions[entry.type](value)
327
336
  if (coerced === undefined && value !== undefined) {
328
- warnInvalidValue(value, fullName, source, `Invalid ${entry.type} input`)
337
+ warnInvalidValue(value, fullName, 'code', `Invalid ${entry.type} input`)
329
338
  }
330
339
  const transformed = coerced !== undefined && entry.transformer
331
- ? entry.transformer(coerced, fullName, source)
340
+ ? entry.transformer(coerced, fullName, 'code')
332
341
  : coerced
333
- setAndTrack(this, entry.property ?? name, transformed, value, source)
342
+ setAndTrack(this, entry.property ?? name, transformed, value, 'code')
334
343
  }
335
344
  }
336
345
 
@@ -638,6 +647,12 @@ class Config extends ConfigBase {
638
647
  setAndTrack(this, 'remoteConfig.DD_REMOTE_CONFIGURATION_ENABLED', false)
639
648
  }
640
649
 
650
+ if (this.isCiVisibility) {
651
+ // Test Optimization reports its metrics through instrumentation telemetry, not DogStatsD.
652
+ set(this, 'dogstatsd', undefined)
653
+ setAndTrack(this, 'runtimeMetrics.enabled', false)
654
+ }
655
+
641
656
  const isTestOptimizationWorker = this.isCiVisibility &&
642
657
  TEST_OPTIMIZATION_WORKER_EXPORTERS.has(this.tracing.DD_TRACE_EXPERIMENTAL_EXPORTER)
643
658
  if (isTestOptimizationWorker) {
@@ -749,11 +764,42 @@ class Config extends ConfigBase {
749
764
  deactivateIfEnabledAndWarnOnWindows(this, 'DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED')
750
765
  }
751
766
 
767
+ const unsupportedRuntime = getUnsupportedRuntime()
768
+ if (unsupportedRuntime !== undefined) {
769
+ this.#deactivateOnUnsupportedRuntime(
770
+ 'dynamicInstrumentation.DD_DYNAMIC_INSTRUMENTATION_ENABLED',
771
+ `Live Debugger/Dynamic Instrumentation is disabled, because it is not supported on ${unsupportedRuntime}.`
772
+ )
773
+ this.#deactivateOnUnsupportedRuntime(
774
+ 'testOptimization.DD_TEST_FAILED_TEST_REPLAY_ENABLED',
775
+ 'Failed Test Replay is disabled, ' +
776
+ `because Live Debugger/Dynamic Instrumentation is not supported on ${unsupportedRuntime}.`
777
+ )
778
+ }
779
+
752
780
  // Single tags update is tracked as a calculated value.
753
781
  setAndTrack(this, 'tags', this.tags)
754
782
 
755
783
  telemetry.updateConfig([...configWithOrigin.values()], this)
756
784
  }
785
+
786
+ /**
787
+ * Only explains the deactivation of an option that was explicitly set, since Failed Test Replay is enabled by
788
+ * default.
789
+ *
790
+ * @param {ConfigPath} name
791
+ * @param {string} reason
792
+ */
793
+ #deactivateOnUnsupportedRuntime (name, reason) {
794
+ if (!get(this, name)) return
795
+
796
+ if (this.startupLogs && trackedConfigOrigins.has(name) && !this.#explainedDeactivations.has(name)) {
797
+ this.#explainedDeactivations.add(name)
798
+ // `log.warn` only prints with debug logging enabled, so write the diagnostic like the startup logs do
799
+ warn(`DATADOG TRACER DIAGNOSTIC - ${reason}`)
800
+ }
801
+ setAndTrack(this, name, false)
802
+ }
757
803
  }
758
804
 
759
805
  /**
@@ -11,7 +11,7 @@ const MAX_SERVICE_LENGTH = 100
11
11
  * `_scope/name` in runtime metrics. Pre-normalizing pins both consumers
12
12
  * (and telemetry / process tags) to the same value.
13
13
  *
14
- * @see https://github.com/DataDog/datadog-agent/blob/main/pkg/trace/traceutil/normalize.go
14
+ * @see https://github.com/DataDog/datadog-agent/blob/main/pkg/trace/traceutil/normalize/normalize.go
15
15
  * @param {string | undefined} name
16
16
  */
17
17
  function normalizeService (name) {
@@ -227,12 +227,12 @@ const transformers = {
227
227
  if (url?.protocol === 'http:' || url?.protocol === 'https:') return value
228
228
  warnInvalidValue(value, optionName, source, 'Invalid HTTP URL')
229
229
  },
230
- validatePropagationStyles (value, optionName) {
230
+ validatePropagationStyles (value, optionName, _source, reportInvalid = true) {
231
231
  value = transformers.toLowerCase(value)
232
232
  for (let index = 0; index < value.length; index++) {
233
233
  const propagator = value[index]
234
234
  if (!VALID_PROPAGATION_STYLES.has(propagator)) {
235
- warnInvalidValue(propagator, optionName, optionName, 'Invalid propagator')
235
+ if (reportInvalid) warnInvalidValue(propagator, optionName, optionName, 'Invalid propagator')
236
236
  return
237
237
  }
238
238
  if (DD_MAJOR >= 6 && propagator === 'b3 single header') {
@@ -508,6 +508,14 @@
508
508
  "default": null
509
509
  }
510
510
  ],
511
+ "DD_BUNDLER_INJECT_GIT_METADATA": [
512
+ {
513
+ "implementation": "A",
514
+ "type": "boolean",
515
+ "default": "true",
516
+ "description": "When using the Datadog esbuild or webpack plugin, inject DD_GIT_COMMIT_SHA and DD_GIT_REPOSITORY_URL into the bundle. Set to false for stable artifact hashes across commits."
517
+ }
518
+ ],
511
519
  "DD_CIVISIBILITY_AGENTLESS_ENABLED": [
512
520
  {
513
521
  "implementation": "A",
@@ -937,6 +945,17 @@
937
945
  "default": "false"
938
946
  }
939
947
  ],
948
+ "DD_FEATURE_FLAGS_EVALUATION_TELEMETRY_PER_SUBJECT_OPT_OUT_ENABLED": [
949
+ {
950
+ "implementation": "A",
951
+ "type": "boolean",
952
+ "namespace": "featureFlags",
953
+ "configurationNames": [
954
+ "featureFlags.enableEvaluationTelemetryOptOutParameter"
955
+ ],
956
+ "default": "false"
957
+ }
958
+ ],
940
959
  "DD_FEATURE_FLAGS_CONFIGURATION_SOURCE": [
941
960
  {
942
961
  "implementation": "A",
@@ -985,6 +1004,15 @@
985
1004
  "namespace": "featureFlags"
986
1005
  }
987
1006
  ],
1007
+ "DD_FEATURE_FLAGS_EXPOSURES_DATADOG_LOGGING_ENABLED": [
1008
+ {
1009
+ "implementation": "A",
1010
+ "type": "boolean",
1011
+ "default": "true",
1012
+ "description": "Enable Feature Flagging exposure delivery to Datadog independently of flag evaluation and evaluation telemetry.",
1013
+ "namespace": "featureFlags"
1014
+ }
1015
+ ],
988
1016
  "DD_FLAGGING_EVALUATION_COUNTS_ENABLED": [
989
1017
  {
990
1018
  "implementation": "A",
@@ -2130,6 +2158,22 @@
2130
2158
  "namespace": "testOptimization"
2131
2159
  }
2132
2160
  ],
2161
+ "_DD_TEST_PARALLELIZATION_ENABLED": [
2162
+ {
2163
+ "implementation": "A",
2164
+ "type": "boolean",
2165
+ "default": null,
2166
+ "description": "Internal: Identifies test processes started by ddtest run."
2167
+ }
2168
+ ],
2169
+ "_DD_TEST_PARALLELIZATION_METADATA_FILE": [
2170
+ {
2171
+ "implementation": "A",
2172
+ "type": "string",
2173
+ "default": null,
2174
+ "description": "Internal: Absolute path to planning metadata supplied by ddtest run."
2175
+ }
2176
+ ],
2133
2177
  "DD_TEST_SESSION_NAME": [
2134
2178
  {
2135
2179
  "implementation": "A",
@@ -28,8 +28,9 @@ class StatsPoint {
28
28
  }
29
29
 
30
30
  addLatencies (checkpoint) {
31
- const edgeLatencySec = checkpoint.edgeLatencyNs / 1e9
32
- const pathwayLatencySec = checkpoint.pathwayLatencyNs / 1e9
31
+ // Start times can come from another host's clock, so skew can make these negative.
32
+ const edgeLatencySec = Math.max(0, checkpoint.edgeLatencyNs / 1e9)
33
+ const pathwayLatencySec = Math.max(0, checkpoint.pathwayLatencyNs / 1e9)
33
34
  this.edgeLatency.accept(edgeLatencySec)
34
35
  this.pathwayLatency.accept(pathwayLatencySec)
35
36
  this.payloadSize.accept(checkpoint.payloadSize)
@@ -54,10 +54,7 @@ class SchemaBuilder {
54
54
  }
55
55
 
56
56
  shouldExtractSchema (schemaName, depth) {
57
- if (depth > maxDepth) {
58
- return false
59
- }
60
- if (schemaName in this.schema.components.schemas) {
57
+ if (depth > maxDepth || schemaName in this.schema.components.schemas) {
61
58
  return false
62
59
  }
63
60
  this.schema.components.schemas[schemaName] = new OpenApiSchema.SCHEMA()
@@ -103,14 +103,14 @@ async function addBreakpoint (probe) {
103
103
  file, lineNumber, columnNumber, probe.id, probe.version
104
104
  )
105
105
  const position = await getGeneratedPosition(url, source, lineNumber, sourceMapURL)
106
- if (position.line !== null && position.column !== null) {
107
- lineNumber = position.line
108
- columnNumber = position.column
109
- } else {
106
+ if (position.line === null || position.column === null) {
110
107
  throw new Error(
111
108
  // eslint-disable-next-line @stylistic/max-len
112
109
  `Could not find generated position for ${url}:${lineNumber}:${columnNumber} (probe: ${probe.id}, version: ${probe.version})`
113
110
  )
111
+ } else {
112
+ lineNumber = position.line
113
+ columnNumber = position.column
114
114
  }
115
115
  }
116
116
 
@@ -357,9 +357,10 @@ async function reEvaluateProbe (probe) {
357
357
  }
358
358
 
359
359
  async function start () {
360
- sessionStarted = true
361
360
  log.debug('[debugger:devtools_client] Starting debugger')
362
361
  await session.post('Debugger.enable')
362
+ // Only flag the session as started once enabled, so the next probe retries a failed start and reports its cause
363
+ sessionStarted = true
363
364
 
364
365
  // Wait until there's a pause in script-loading to avoid accidentally adding probes to incorrect scripts. This is not
365
366
  // a guarantee, but best effort.
@@ -312,9 +312,9 @@ function isInstanceOfCoreType (type, variable, fallback = `${variable} instanceo
312
312
  function getSize (variable) {
313
313
  return `((val) => {
314
314
  if (${isString('val')} || ${isArrayOrTypedArray('val')}) {
315
- return ${guardAgainstPropertyAccessSideEffects('val', '"length"')}
315
+ return ${guardAgainstPropertyAccessSideEffects('"length"')}
316
316
  } else if (${isInstanceOfCoreType('Set', 'val')} || ${isInstanceOfCoreType('Map', 'val')}) {
317
- return ${guardAgainstPropertyAccessSideEffects('val', '"size"')}
317
+ return ${guardAgainstPropertyAccessSideEffects('"size"')}
318
318
  } else if (${isInstanceOfCoreType('WeakSet', 'val')} || ${isInstanceOfCoreType('WeakMap', 'val')}) {
319
319
  throw new TypeError('Cannot get size of WeakSet or WeakMap')
320
320
  } else if (typeof val === 'object' && val !== null) {
@@ -338,12 +338,12 @@ function accessProperty (variable, keyOrIndex, allowMapAccess) {
338
338
  } else if (${isInstanceOfCoreType('Set', 'val')} || ${isInstanceOfCoreType('WeakSet', 'val')}) {
339
339
  throw new Error('Accessing a Set or WeakSet is not allowed')
340
340
  } else {
341
- return ${guardAgainstPropertyAccessSideEffects('val', 'key')}
341
+ return ${guardAgainstPropertyAccessSideEffects('key')}
342
342
  }
343
343
  })(${variable}, ${keyOrIndex})`
344
344
  }
345
345
 
346
- function guardAgainstPropertyAccessSideEffects (variable, propertyName) {
346
+ function guardAgainstPropertyAccessSideEffects (propertyName) {
347
347
  return `((val, key) => {
348
348
  if (
349
349
  ${isInstanceOfCoreType('Proxy', 'val', 'true')} ||
@@ -353,7 +353,7 @@ function guardAgainstPropertyAccessSideEffects (variable, propertyName) {
353
353
  } else {
354
354
  return val[key]
355
355
  }
356
- })(${variable}, ${propertyName})`
356
+ })(val, ${propertyName})`
357
357
  }
358
358
 
359
359
  function guardAgainstCoercionSideEffects (variable) {
@@ -61,6 +61,7 @@ function send (message, logger, dd, snapshot, processTags, eventType, incomplete
61
61
  ddsource,
62
62
  hostname,
63
63
  service,
64
+ timestamp: snapshot.timestamp,
64
65
  message,
65
66
  logger,
66
67
  dd,
@@ -126,8 +126,8 @@ async function traverseGetPropertiesResult (props, opts, depth) {
126
126
  if (prop.value === undefined) continue
127
127
  const { value: { type, objectId, subtype, description } } = prop
128
128
  if (type === 'object') {
129
- if (objectId === undefined) continue // if `subtype` is "null"
130
- if (LEAF_SUBTYPES.has(subtype)) continue // don't waste time with these subtypes
129
+ // if `subtype` is "null"
130
+ if (objectId === undefined || LEAF_SUBTYPES.has(subtype)) continue // don't waste time with these subtypes
131
131
  const size = parseLengthFromDescription(description, subtype)
132
132
  if (size !== null && size >= LARGE_OBJECT_SKIP_THRESHOLD) {
133
133
  const empty = []
@@ -310,8 +310,7 @@ function removeNonEnumerableProperties (props) {
310
310
  }
311
311
 
312
312
  function parseLengthFromDescription (description, subtype) {
313
- if (typeof description !== 'string') return null
314
- if (!SIZE_IN_DESCRIPTION_SUBTYPES.has(subtype)) return null
313
+ if (typeof description !== 'string' || !SIZE_IN_DESCRIPTION_SUBTYPES.has(subtype)) return null
315
314
 
316
315
  const open = description.lastIndexOf('(')
317
316
  if (open === -1) return null
@@ -323,8 +322,7 @@ function parseLengthFromDescription (description, subtype) {
323
322
  if (s === '') return null
324
323
 
325
324
  const n = Number(s)
326
- if (!Number.isSafeInteger(n) || n < 0) return null
327
- if (String(n) !== s) return null
325
+ if (!Number.isSafeInteger(n) || n < 0 || String(n) !== s) return null
328
326
 
329
327
  return n
330
328
  }
@@ -129,6 +129,7 @@ function statusPayload (probeId, probeVersion, status) {
129
129
  return {
130
130
  ddsource,
131
131
  service,
132
+ timestamp: Date.now(),
132
133
  debugger: {
133
134
  diagnostics: { probeId, runtimeId, probeVersion, status },
134
135
  },
@@ -9,10 +9,10 @@
9
9
  * atomics, and the main thread periodically drains the counters into instrumentation telemetry metrics.
10
10
  *
11
11
  * The metric names, tags and reason codes are defined by the "Debugger Observability for GA" specification and are
12
- * shared with the other tracers. All metrics are counts in the `live_debugger` telemetry namespace.
12
+ * shared with the other tracers. All metrics are counts in the `debugger` telemetry namespace.
13
13
  */
14
14
 
15
- const TELEMETRY_NAMESPACE = 'live_debugger'
15
+ const TELEMETRY_NAMESPACE = 'debugger'
16
16
 
17
17
  const EVENT_TYPE = Object.freeze({
18
18
  SNAPSHOT: 0,
@@ -0,0 +1,16 @@
1
+ 'use strict'
2
+
3
+ /**
4
+ * Get the name of the runtime if it can't run Live Debugger/Dynamic Instrumentation, or `undefined` if it can.
5
+ *
6
+ * Live Debugger/Dynamic Instrumentation needs the Debugger domain of the `node:inspector` module. Bun only implements a
7
+ * few of its methods, never returns their results, and never emits its events. Deno doesn't let worker threads
8
+ * connect to the main thread inspector. Deno reports a Node.js `process.version`, so both runtimes are detected by
9
+ * their own `process.versions` entry instead.
10
+ */
11
+ function getUnsupportedRuntime () {
12
+ if (process.versions.bun !== undefined) return 'Bun'
13
+ if (process.versions.deno !== undefined) return 'Deno'
14
+ }
15
+
16
+ module.exports = { getUnsupportedRuntime }