dd-trace 6.15.0 → 6.17.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 (378) hide show
  1. package/README.md +15 -0
  2. package/ci/diagnose.js +0 -23
  3. package/ci/test-optimization-validation/approval-artifacts.js +0 -3
  4. package/ci/test-optimization-validation/approval.js +0 -6
  5. package/ci/test-optimization-validation/artifact-id.js +0 -1
  6. package/ci/test-optimization-validation/bounded-json.js +0 -1
  7. package/ci/test-optimization-validation/cli.js +0 -12
  8. package/ci/test-optimization-validation/command-output-policy.js +0 -1
  9. package/ci/test-optimization-validation/command-runner.js +0 -3
  10. package/ci/test-optimization-validation/environment.js +0 -4
  11. package/ci/test-optimization-validation/executable-approval.js +0 -1
  12. package/ci/test-optimization-validation/executable.js +0 -5
  13. package/ci/test-optimization-validation/framework-adapters/cucumber.js +4 -8
  14. package/ci/test-optimization-validation/framework-adapters/cypress.js +0 -3
  15. package/ci/test-optimization-validation/framework-adapters/playwright.js +0 -6
  16. package/ci/test-optimization-validation/framework-adapters/vitest.js +0 -4
  17. package/ci/test-optimization-validation/generated-test-contract.js +0 -5
  18. package/ci/test-optimization-validation/generated-verifier.js +0 -1
  19. package/ci/test-optimization-validation/literal-environment.js +0 -1
  20. package/ci/test-optimization-validation/manifest-scaffold.js +0 -17
  21. package/ci/test-optimization-validation/manifest-schema.js +0 -21
  22. package/ci/test-optimization-validation/offline-fixtures.js +0 -4
  23. package/ci/test-optimization-validation/package-check.js +4 -1
  24. package/ci/test-optimization-validation/plan-writer.js +0 -11
  25. package/ci/test-optimization-validation/preflight-runner.js +0 -1
  26. package/ci/test-optimization-validation/redaction.js +0 -4
  27. package/ci/test-optimization-validation/report-writer.js +0 -16
  28. package/ci/test-optimization-validation/runner-command.js +0 -3
  29. package/ci/test-optimization-validation/runner-contract.js +0 -4
  30. package/ci/test-optimization-validation/safe-files.js +0 -1
  31. package/ci/test-optimization-validation/scenarios/basic-reporting.js +0 -1
  32. package/ci/test-optimization-validation/scenarios/ci-wiring.js +1 -2
  33. package/ci/test-optimization-validation/source-text.js +0 -3
  34. package/ci/vitest-no-worker-init-setup.mjs +41 -16
  35. package/index.d.ts +169 -0
  36. package/next.d.ts +27 -0
  37. package/next.js +3 -0
  38. package/package.json +28 -23
  39. package/packages/datadog-esbuild/index.js +14 -1
  40. package/packages/datadog-esbuild/src/resolver.js +284 -0
  41. package/packages/datadog-esbuild/src/utils.js +162 -120
  42. package/packages/datadog-instrumentations/src/aerospike.js +28 -6
  43. package/packages/datadog-instrumentations/src/ai.js +39 -97
  44. package/packages/datadog-instrumentations/src/anthropic.js +76 -134
  45. package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +1 -3
  46. package/packages/datadog-instrumentations/src/aws-sdk.js +0 -2
  47. package/packages/datadog-instrumentations/src/azure-cosmos.js +1 -1
  48. package/packages/datadog-instrumentations/src/azure-durable-functions.js +23 -9
  49. package/packages/datadog-instrumentations/src/azure-functions.js +48 -0
  50. package/packages/datadog-instrumentations/src/bullmq.js +1 -1
  51. package/packages/datadog-instrumentations/src/claude-agent-sdk.js +1 -3
  52. package/packages/datadog-instrumentations/src/console.js +97 -0
  53. package/packages/datadog-instrumentations/src/cucumber.js +72 -12
  54. package/packages/datadog-instrumentations/src/cypress-config.js +0 -23
  55. package/packages/datadog-instrumentations/src/dd-trace-api.js +2 -2
  56. package/packages/datadog-instrumentations/src/graphql.js +1 -1
  57. package/packages/datadog-instrumentations/src/helpers/bundler-register.js +39 -14
  58. package/packages/datadog-instrumentations/src/helpers/channel.js +0 -2
  59. package/packages/datadog-instrumentations/src/helpers/graphql-jit-runtime.js +0 -5
  60. package/packages/datadog-instrumentations/src/helpers/hooks.js +8 -0
  61. package/packages/datadog-instrumentations/src/helpers/instrument.js +25 -8
  62. package/packages/datadog-instrumentations/src/helpers/instrumentation-utils.js +69 -0
  63. package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +0 -6
  64. package/packages/datadog-instrumentations/src/helpers/register.js +13 -64
  65. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +109 -29
  66. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +39 -0
  67. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/azure-durable-functions.js +17 -0
  68. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +3 -16
  69. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +12 -0
  70. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/postgres.js +36 -0
  71. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/supabase.js +128 -0
  72. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +6 -7
  73. package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +17 -0
  74. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms/postgres.js +388 -0
  75. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +99 -75
  76. package/packages/datadog-instrumentations/src/helpers/router-helper.js +0 -1
  77. package/packages/datadog-instrumentations/src/jest.js +141 -51
  78. package/packages/datadog-instrumentations/src/knex.js +0 -1
  79. package/packages/datadog-instrumentations/src/langchain.js +1 -1
  80. package/packages/datadog-instrumentations/src/langgraph.js +1 -1
  81. package/packages/datadog-instrumentations/src/mariadb-bundle.js +0 -24
  82. package/packages/datadog-instrumentations/src/mariadb.js +0 -2
  83. package/packages/datadog-instrumentations/src/mercurius.js +1 -1
  84. package/packages/datadog-instrumentations/src/mocha/common.js +0 -1
  85. package/packages/datadog-instrumentations/src/mocha/main.js +22 -25
  86. package/packages/datadog-instrumentations/src/mocha/utils.js +119 -49
  87. package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +0 -6
  88. package/packages/datadog-instrumentations/src/mocha/worker.js +14 -17
  89. package/packages/datadog-instrumentations/src/modelcontextprotocol-sdk.js +1 -1
  90. package/packages/datadog-instrumentations/src/mysql2.js +0 -2
  91. package/packages/datadog-instrumentations/src/openai-agents.js +1 -1
  92. package/packages/datadog-instrumentations/src/openai-realtime/audio-accumulator.js +241 -0
  93. package/packages/datadog-instrumentations/src/openai-realtime/events.js +76 -0
  94. package/packages/datadog-instrumentations/src/openai-realtime/index.js +301 -0
  95. package/packages/datadog-instrumentations/src/openai-realtime/session.js +998 -0
  96. package/packages/datadog-instrumentations/src/openai-realtime/turns.js +211 -0
  97. package/packages/datadog-instrumentations/src/openai.js +97 -80
  98. package/packages/datadog-instrumentations/src/oracledb.js +9 -3
  99. package/packages/datadog-instrumentations/src/playwright-reporter.js +3 -16
  100. package/packages/datadog-instrumentations/src/playwright.js +238 -55
  101. package/packages/datadog-instrumentations/src/postgres.js +7 -0
  102. package/packages/datadog-instrumentations/src/router.js +0 -2
  103. package/packages/datadog-instrumentations/src/rum-browser-scripts.js +0 -2
  104. package/packages/datadog-instrumentations/src/sequelize.js +0 -1
  105. package/packages/datadog-instrumentations/src/supabase.js +15 -0
  106. package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +18 -18
  107. package/packages/datadog-instrumentations/src/vitest-main.js +37 -17
  108. package/packages/datadog-instrumentations/src/vitest-util.js +7 -1
  109. package/packages/datadog-instrumentations/src/vitest-worker.js +56 -23
  110. package/packages/datadog-instrumentations/src/webdriverio.js +23 -42
  111. package/packages/datadog-instrumentations/src/ws.js +0 -1
  112. package/packages/datadog-plugin-ai/src/utils.js +0 -2
  113. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +0 -1
  114. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +0 -2
  115. package/packages/datadog-plugin-aws-sdk/src/base.js +0 -1
  116. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +7 -2
  117. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +0 -1
  118. package/packages/datadog-plugin-aws-sdk/src/util.js +0 -1
  119. package/packages/datadog-plugin-azure-cosmos/src/index.js +1 -1
  120. package/packages/datadog-plugin-azure-durable-functions/src/index.js +95 -1
  121. package/packages/datadog-plugin-cucumber/src/index.js +10 -0
  122. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +171 -75
  123. package/packages/datadog-plugin-cypress/src/finalization.js +0 -3
  124. package/packages/datadog-plugin-cypress/src/source-map-utils.js +0 -4
  125. package/packages/datadog-plugin-cypress/src/support.js +52 -7
  126. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -24
  127. package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +2 -36
  128. package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-request-context.js +31 -0
  129. package/packages/datadog-plugin-graphql/src/resolve-error.js +32 -11
  130. package/packages/datadog-plugin-graphql/src/utils.js +0 -5
  131. package/packages/datadog-plugin-jest/src/index.js +13 -0
  132. package/packages/datadog-plugin-kafkajs/src/producer.js +0 -1
  133. package/packages/datadog-plugin-mocha/src/index.js +39 -11
  134. package/packages/datadog-plugin-mongodb-core/src/query.js +0 -1
  135. package/packages/datadog-plugin-openai/src/index.js +16 -1
  136. package/packages/datadog-plugin-openai/src/realtime.js +144 -0
  137. package/packages/datadog-plugin-openai-agents/src/integration.js +0 -4
  138. package/packages/datadog-plugin-openai-agents/src/util.js +0 -1
  139. package/packages/datadog-plugin-playwright/src/index.js +76 -9
  140. package/packages/datadog-plugin-postgres/src/index.js +167 -0
  141. package/packages/datadog-plugin-prisma/src/datadog-tracing-helper.js +0 -1
  142. package/packages/datadog-plugin-redis/src/index.js +15 -1
  143. package/packages/datadog-plugin-supabase/src/error.js +18 -0
  144. package/packages/datadog-plugin-supabase/src/index.js +21 -0
  145. package/packages/datadog-plugin-supabase/src/supabase-auth-js-gotrueclient-getuser.js +69 -0
  146. package/packages/datadog-plugin-supabase/src/supabase-functions-js-functionsclient-invoke.js +70 -0
  147. package/packages/datadog-plugin-supabase/src/supabase-postgrest-js-postgrestbuilder-then.js +122 -0
  148. package/packages/datadog-plugin-supabase/src/supabase-realtime-js-realtimechannel-send.js +66 -0
  149. package/packages/datadog-plugin-supabase/src/supabase-storage-js-handle-request.js +93 -0
  150. package/packages/datadog-plugin-supabase/src/url.js +17 -0
  151. package/packages/datadog-plugin-vitest/src/index.js +10 -0
  152. package/packages/datadog-plugin-ws/src/util.js +0 -4
  153. package/packages/datadog-turbopack/index.js +206 -0
  154. package/packages/datadog-turbopack/src/constants.js +5 -0
  155. package/packages/datadog-turbopack/src/loader.js +484 -0
  156. package/packages/datadog-webpack/src/loader.js +0 -1
  157. package/packages/dd-trace/src/aiguard/client.js +2 -3
  158. package/packages/dd-trace/src/aiguard/evaluation.js +6 -12
  159. package/packages/dd-trace/src/aiguard/index.js +3 -2
  160. package/packages/dd-trace/src/aiguard/integrations/anthropic.js +53 -25
  161. package/packages/dd-trace/src/aiguard/integrations/evaluate.js +49 -25
  162. package/packages/dd-trace/src/aiguard/integrations/index.js +4 -3
  163. package/packages/dd-trace/src/aiguard/integrations/openai.js +132 -29
  164. package/packages/dd-trace/src/aiguard/integrations/vercel-ai.js +116 -42
  165. package/packages/dd-trace/src/aiguard/messages/anthropic.js +0 -2
  166. package/packages/dd-trace/src/aiguard/messages/openai.js +64 -1
  167. package/packages/dd-trace/src/aiguard/messages/utils.js +29 -2
  168. package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +25 -0
  169. package/packages/dd-trace/src/aiguard/redaction.js +0 -1
  170. package/packages/dd-trace/src/aiguard/sdk.js +1 -1
  171. package/packages/dd-trace/src/appsec/activation.js +1 -1
  172. package/packages/dd-trace/src/appsec/api_security/normalized-route.js +0 -5
  173. package/packages/dd-trace/src/appsec/api_security/sampler.js +0 -4
  174. package/packages/dd-trace/src/appsec/blocking/index.js +3 -3
  175. package/packages/dd-trace/src/appsec/downstream_requests.js +1 -4
  176. package/packages/dd-trace/src/appsec/iast/index.js +1 -1
  177. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +5 -5
  178. package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +1 -1
  179. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -1
  180. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +3 -3
  181. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +8 -10
  182. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +2 -2
  183. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -2
  184. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +4 -1
  185. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +7 -7
  186. package/packages/dd-trace/src/appsec/index.js +2 -2
  187. package/packages/dd-trace/src/appsec/lambda.js +71 -2
  188. package/packages/dd-trace/src/appsec/rasp/utils.js +5 -1
  189. package/packages/dd-trace/src/appsec/remote_config.js +8 -6
  190. package/packages/dd-trace/src/appsec/reporter.js +10 -6
  191. package/packages/dd-trace/src/appsec/rule_manager.js +3 -3
  192. package/packages/dd-trace/src/appsec/sdk/track_event.js +0 -2
  193. package/packages/dd-trace/src/appsec/telemetry/api_security.js +1 -3
  194. package/packages/dd-trace/src/appsec/telemetry/common.js +4 -0
  195. package/packages/dd-trace/src/appsec/telemetry/index.js +23 -5
  196. package/packages/dd-trace/src/appsec/telemetry/rasp.js +1 -20
  197. package/packages/dd-trace/src/appsec/telemetry/user.js +1 -3
  198. package/packages/dd-trace/src/appsec/telemetry/waf.js +1 -20
  199. package/packages/dd-trace/src/appsec/waf/index.js +2 -2
  200. package/packages/dd-trace/src/appsec/waf/waf_manager.js +8 -5
  201. package/packages/dd-trace/src/carrier.js +0 -5
  202. package/packages/dd-trace/src/ci-visibility/dynamic-atr-retries.js +104 -0
  203. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +0 -2
  204. package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +34 -3
  205. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +0 -1
  206. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +0 -1
  207. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +0 -1
  208. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/index.js +0 -4
  209. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +0 -1
  210. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +0 -2
  211. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +37 -15
  212. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +0 -3
  213. package/packages/dd-trace/src/ci-visibility/exporters/request.js +0 -11
  214. package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +0 -1
  215. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +0 -1
  216. package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +0 -6
  217. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -2
  218. package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +0 -1
  219. package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +0 -5
  220. package/packages/dd-trace/src/ci-visibility/requests/video-request.js +0 -1
  221. package/packages/dd-trace/src/ci-visibility/telemetry.js +13 -0
  222. package/packages/dd-trace/src/ci-visibility/test-optimization-cache.js +0 -1
  223. package/packages/dd-trace/src/ci-visibility/test-screenshot.js +0 -2
  224. package/packages/dd-trace/src/ci-visibility/test-video.js +0 -1
  225. package/packages/dd-trace/src/config/defaults.js +3 -2
  226. package/packages/dd-trace/src/config/generated-config-types.d.ts +74 -66
  227. package/packages/dd-trace/src/config/helper.js +9 -2
  228. package/packages/dd-trace/src/config/index.js +44 -29
  229. package/packages/dd-trace/src/config/parsers.js +34 -6
  230. package/packages/dd-trace/src/config/remote_config.js +25 -109
  231. package/packages/dd-trace/src/config/supported-configurations.json +146 -9
  232. package/packages/dd-trace/src/datastreams/encoding.js +0 -1
  233. package/packages/dd-trace/src/datastreams/pathway.js +0 -1
  234. package/packages/dd-trace/src/debugger/constants.js +10 -0
  235. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +76 -17
  236. package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -0
  237. package/packages/dd-trace/src/debugger/devtools_client/guardrail-metrics.js +15 -0
  238. package/packages/dd-trace/src/debugger/devtools_client/index.js +103 -27
  239. package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +50 -7
  240. package/packages/dd-trace/src/debugger/devtools_client/log.js +3 -1
  241. package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +34 -8
  242. package/packages/dd-trace/src/debugger/devtools_client/send.js +40 -14
  243. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +53 -13
  244. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +118 -71
  245. package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +0 -3
  246. package/packages/dd-trace/src/debugger/devtools_client/status.js +20 -6
  247. package/packages/dd-trace/src/debugger/guardrail-metrics.js +167 -0
  248. package/packages/dd-trace/src/debugger/index.js +50 -2
  249. package/packages/dd-trace/src/debugger/inspect-segment.js +0 -3
  250. package/packages/dd-trace/src/debugger/probe_sampler.js +133 -9
  251. package/packages/dd-trace/src/debugger/probe_sampler_constants.js +31 -1
  252. package/packages/dd-trace/src/dogstatsd.js +0 -23
  253. package/packages/dd-trace/src/encode/0.4-cross-payload.js +0 -3
  254. package/packages/dd-trace/src/encode/0.4.js +0 -7
  255. package/packages/dd-trace/src/encode/0.5.js +0 -2
  256. package/packages/dd-trace/src/encode/tags-processors.js +0 -1
  257. package/packages/dd-trace/src/evp_proxy/discovery.js +3 -5
  258. package/packages/dd-trace/src/evp_proxy/path.js +11 -4
  259. package/packages/dd-trace/src/exporters/agent/writer.js +0 -1
  260. package/packages/dd-trace/src/exporters/agentless/index.js +0 -1
  261. package/packages/dd-trace/src/exporters/agentless/intake.js +0 -1
  262. package/packages/dd-trace/src/exporters/agentless/writer.js +0 -3
  263. package/packages/dd-trace/src/exporters/common/docker.js +4 -1
  264. package/packages/dd-trace/src/exporters/common/final-flush-request-tracker.js +0 -6
  265. package/packages/dd-trace/src/exporters/common/proxy.js +3 -0
  266. package/packages/dd-trace/src/exporters/common/request.js +1 -0
  267. package/packages/dd-trace/src/exporters/common/url.js +0 -2
  268. package/packages/dd-trace/src/exporters/common/writer.js +0 -2
  269. package/packages/dd-trace/src/id.js +0 -11
  270. package/packages/dd-trace/src/llmobs/audio-codec.js +192 -0
  271. package/packages/dd-trace/src/llmobs/audio-utils.js +121 -0
  272. package/packages/dd-trace/src/llmobs/constants/audio.js +35 -0
  273. package/packages/dd-trace/src/llmobs/constants/prompts.js +14 -0
  274. package/packages/dd-trace/src/llmobs/constants/tags.js +17 -0
  275. package/packages/dd-trace/src/llmobs/eval-metric.js +0 -6
  276. package/packages/dd-trace/src/llmobs/experiments/dataset.js +0 -4
  277. package/packages/dd-trace/src/llmobs/experiments/experiment.js +0 -3
  278. package/packages/dd-trace/src/llmobs/experiments/index.js +7 -6
  279. package/packages/dd-trace/src/llmobs/experiments/util.js +1 -11
  280. package/packages/dd-trace/src/llmobs/index.js +1 -3
  281. package/packages/dd-trace/src/llmobs/noop.js +10 -0
  282. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +0 -4
  283. package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +0 -1
  284. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +0 -4
  285. package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/utils.js +0 -2
  286. package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +0 -2
  287. package/packages/dd-trace/src/llmobs/plugins/openai/index.js +4 -6
  288. package/packages/dd-trace/src/llmobs/plugins/openai/realtime.js +285 -0
  289. package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +16 -3
  290. package/packages/dd-trace/src/llmobs/prompts/cache.js +272 -0
  291. package/packages/dd-trace/src/llmobs/prompts/manager.js +639 -0
  292. package/packages/dd-trace/src/llmobs/prompts/noop.js +29 -0
  293. package/packages/dd-trace/src/llmobs/prompts/prompt.js +92 -0
  294. package/packages/dd-trace/src/llmobs/sdk.js +21 -6
  295. package/packages/dd-trace/src/llmobs/span_processor.js +81 -2
  296. package/packages/dd-trace/src/llmobs/tagger.js +30 -7
  297. package/packages/dd-trace/src/llmobs/telemetry.js +36 -4
  298. package/packages/dd-trace/src/llmobs/util.js +0 -34
  299. package/packages/dd-trace/src/llmobs/writers/base.js +0 -1
  300. package/packages/dd-trace/src/llmobs/writers/util.js +1 -2
  301. package/packages/dd-trace/src/log/channels.js +3 -0
  302. package/packages/dd-trace/src/log/index.js +23 -5
  303. package/packages/dd-trace/src/log-submission/log-submission-plugin.js +74 -6
  304. package/packages/dd-trace/src/msgpack/chunk.js +0 -1
  305. package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +0 -12
  306. package/packages/dd-trace/src/openfeature/encoding.js +0 -2
  307. package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +0 -1
  308. package/packages/dd-trace/src/openfeature/index.js +0 -4
  309. package/packages/dd-trace/src/openfeature/span-enrichment-hook.js +0 -1
  310. package/packages/dd-trace/src/openfeature/span-enrichment.js +0 -4
  311. package/packages/dd-trace/src/openfeature/writers/base.js +0 -6
  312. package/packages/dd-trace/src/openfeature/writers/exposures.js +0 -5
  313. package/packages/dd-trace/src/openfeature/writers/util.js +0 -4
  314. package/packages/dd-trace/src/opentelemetry/logs/logger.js +0 -1
  315. package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +0 -1
  316. package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +0 -1
  317. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +0 -2
  318. package/packages/dd-trace/src/opentelemetry/metrics/index.js +1 -1
  319. package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +4 -4
  320. package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +0 -1
  321. package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +0 -1
  322. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +103 -35
  323. package/packages/dd-trace/src/opentelemetry/metrics/time.js +0 -1
  324. package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +36 -13
  325. package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +0 -1
  326. package/packages/dd-trace/src/opentelemetry/span-helpers.js +0 -1
  327. package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +0 -1
  328. package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +0 -3
  329. package/packages/dd-trace/src/opentracing/propagation/text_map.js +0 -6
  330. package/packages/dd-trace/src/opentracing/span_context.js +0 -1
  331. package/packages/dd-trace/src/otel-thread-ctx.js +38 -11
  332. package/packages/dd-trace/src/payload-tagging/tagging.js +15 -3
  333. package/packages/dd-trace/src/plugin_manager.js +9 -3
  334. package/packages/dd-trace/src/plugins/ci_plugin.js +0 -1
  335. package/packages/dd-trace/src/plugins/database.js +2 -6
  336. package/packages/dd-trace/src/plugins/index.js +8 -0
  337. package/packages/dd-trace/src/plugins/plugin.js +0 -4
  338. package/packages/dd-trace/src/plugins/tracing.js +1 -1
  339. package/packages/dd-trace/src/plugins/util/git.js +1 -3
  340. package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +0 -1
  341. package/packages/dd-trace/src/plugins/util/llm.js +0 -2
  342. package/packages/dd-trace/src/plugins/util/status-validator.js +0 -1
  343. package/packages/dd-trace/src/plugins/util/test.js +25 -21
  344. package/packages/dd-trace/src/plugins/util/url.js +0 -5
  345. package/packages/dd-trace/src/priority_sampler.js +0 -6
  346. package/packages/dd-trace/src/process-tags/index.js +0 -1
  347. package/packages/dd-trace/src/profiler.js +132 -35
  348. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +0 -1
  349. package/packages/dd-trace/src/profiling/profiler.js +101 -41
  350. package/packages/dd-trace/src/profiling/ssi-heuristics.js +29 -15
  351. package/packages/dd-trace/src/propagation-hash/index.js +0 -1
  352. package/packages/dd-trace/src/proxy.js +21 -45
  353. package/packages/dd-trace/src/random_sampler.js +0 -4
  354. package/packages/dd-trace/src/rate_limiter.js +0 -4
  355. package/packages/dd-trace/src/remote_config/capabilities.js +1 -9
  356. package/packages/dd-trace/src/remote_config/index.js +0 -1
  357. package/packages/dd-trace/src/runtime_metrics/otlp_runtime_metrics.js +0 -3
  358. package/packages/dd-trace/src/sampler.js +0 -4
  359. package/packages/dd-trace/src/sampling_rule.js +0 -7
  360. package/packages/dd-trace/src/serverless/vercel.js +0 -1
  361. package/packages/dd-trace/src/serverless.js +0 -1
  362. package/packages/dd-trace/src/service-naming/index.js +0 -1
  363. package/packages/dd-trace/src/service-naming/schemas/util.js +0 -1
  364. package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +7 -0
  365. package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +5 -0
  366. package/packages/dd-trace/src/span_processor.js +2 -2
  367. package/packages/dd-trace/src/span_sampler.js +0 -1
  368. package/packages/dd-trace/src/standalone/product.js +2 -2
  369. package/packages/dd-trace/src/standalone/tracesource.js +0 -1
  370. package/packages/dd-trace/src/startup-log.js +1 -1
  371. package/packages/dd-trace/src/telemetry/endpoints.js +0 -8
  372. package/packages/dd-trace/src/telemetry/logs/index.js +16 -5
  373. package/packages/dd-trace/src/telemetry/logs/log-collector.js +16 -6
  374. package/packages/dd-trace/src/telemetry/metrics.js +0 -2
  375. package/packages/dd-trace/src/telemetry/telemetry.js +4 -1
  376. package/packages/dd-trace/src/util.js +13 -1
  377. package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
  378. package/packages/dd-trace/src/llmobs/plugins/claude-agent-sdk/utils.js +0 -10
@@ -3,6 +3,7 @@
3
3
  const { LRUCache } = require('../../../../vendor/dist/lru-cache')
4
4
  const { PEER_SERVICE_KEY, PEER_SERVICE_SOURCE_KEY } = require('../constants')
5
5
  const propagationHash = require('../propagation-hash')
6
+ const { truncateString } = require('../util')
6
7
  const StoragePlugin = require('./storage')
7
8
 
8
9
  // Unreserved RFC 3986 set that `encodeURIComponent` leaves untouched (a conservative subset:
@@ -46,7 +47,6 @@ class DatabasePlugin extends StoragePlugin {
46
47
  * @param {string} serviceName
47
48
  * @param {import('../../../..').Span} span
48
49
  * @param {object} peerData
49
- * @returns {string}
50
50
  */
51
51
  #createDBMPropagationCommentService (serviceName, span, peerData) {
52
52
  const spanTags = span.context().getTags()
@@ -70,7 +70,6 @@ class DatabasePlugin extends StoragePlugin {
70
70
  /**
71
71
  * @param {string} tracerService
72
72
  * @param {object} peerData
73
- * @returns {string}
74
73
  */
75
74
  #getDbmServiceName (tracerService, peerData) {
76
75
  if (this._tracerConfig.spanComputePeerService) {
@@ -123,7 +122,6 @@ class DatabasePlugin extends StoragePlugin {
123
122
  * @param {string} query
124
123
  * @param {string} serviceName
125
124
  * @param {boolean} disableFullMode
126
- * @returns {string}
127
125
  */
128
126
  injectDbmQuery (span, query, serviceName, disableFullMode = false) {
129
127
  const dbmTraceComment = this.createDbmComment(span, serviceName, disableFullMode)
@@ -139,7 +137,6 @@ class DatabasePlugin extends StoragePlugin {
139
137
 
140
138
  /**
141
139
  * @param {string} query
142
- * @returns {string}
143
140
  */
144
141
  maybeTruncate (query) {
145
142
  const maxLength = typeof this.config.truncate === 'number'
@@ -147,7 +144,7 @@ class DatabasePlugin extends StoragePlugin {
147
144
  : 5000 // same as what the agent does
148
145
 
149
146
  if (this.config.truncate && query && query.length > maxLength) {
150
- query = `${query.slice(0, maxLength - 3)}...`
147
+ query = truncateString(query, maxLength, '...')
151
148
  }
152
149
 
153
150
  return query
@@ -156,7 +153,6 @@ class DatabasePlugin extends StoragePlugin {
156
153
 
157
154
  /**
158
155
  * @param {string | number | undefined | null} value
159
- * @returns {string}
160
156
  */
161
157
  function encode (value) {
162
158
  if (!value) return ''
@@ -10,6 +10,12 @@ const plugins = {
10
10
  get '@azure/functions' () { return require('../../../datadog-plugin-azure-functions/src') },
11
11
  get '@modelcontextprotocol/sdk' () { return require('../../../datadog-plugin-modelcontextprotocol-sdk/src') },
12
12
  get '@aws/durable-execution-sdk-js' () { return require('../../../datadog-plugin-aws-durable-execution-sdk-js/src') },
13
+ get '@supabase/auth-js' () { return require('../../../datadog-plugin-supabase/src') },
14
+ get '@supabase/functions-js' () { return require('../../../datadog-plugin-supabase/src') },
15
+ get '@supabase/postgrest-js' () { return require('../../../datadog-plugin-supabase/src') },
16
+ get '@supabase/realtime-js' () { return require('../../../datadog-plugin-supabase/src') },
17
+ get '@supabase/storage-js' () { return require('../../../datadog-plugin-supabase/src') },
18
+ get '@supabase/supabase-js' () { return require('../../../datadog-plugin-supabase/src') },
13
19
  get 'durable-functions' () { return require('../../../datadog-plugin-azure-durable-functions/src') },
14
20
  get '@azure/service-bus' () { return require('../../../datadog-plugin-azure-service-bus/src') },
15
21
  get '@cucumber/cucumber' () { return require('../../../datadog-plugin-cucumber/src') },
@@ -19,6 +25,7 @@ const plugins = {
19
25
  get '@google-cloud/pubsub' () { return require('../../../datadog-plugin-google-cloud-pubsub/src') },
20
26
  get '@google-cloud/vertexai' () { return require('../../../datadog-plugin-google-cloud-vertexai/src') },
21
27
  get '@google/genai' () { return require('../../../datadog-plugin-google-genai/src') },
28
+ get '@graphql-tools/executor' () { return require('../../../datadog-plugin-graphql/src') },
22
29
  get '@grpc/grpc-js' () { return require('../../../datadog-plugin-grpc/src') },
23
30
  get '@hapi/hapi' () { return require('../../../datadog-plugin-hapi/src') },
24
31
  get '@happy-dom/jest-environment' () { return require('../../../datadog-plugin-jest/src') },
@@ -120,6 +127,7 @@ const plugins = {
120
127
  get pino () { return require('../../../datadog-plugin-pino/src') },
121
128
  get 'pino-pretty' () { return require('../../../datadog-plugin-pino/src') },
122
129
  get playwright () { return require('../../../datadog-plugin-playwright/src') },
130
+ get postgres () { return require('../../../datadog-plugin-postgres/src') },
123
131
  get protobufjs () { return require('../../../datadog-plugin-protobufjs/src') },
124
132
  get redis () { return require('../../../datadog-plugin-redis/src') },
125
133
  get restify () { return require('../../../datadog-plugin-restify/src') },
@@ -100,7 +100,6 @@ module.exports = class Plugin {
100
100
  *
101
101
  * @param {object} span The span to bind as current.
102
102
  * @param {object=} store Optional existing store to extend; if omitted, uses current store.
103
- * @returns {void}
104
103
  */
105
104
  enter (span, store) {
106
105
  store ||= legacyStorage.getStore()
@@ -112,7 +111,6 @@ module.exports = class Plugin {
112
111
  *
113
112
  * @param {string} channelName Diagnostic channel name.
114
113
  * @param {(message: unknown, name: string) => unknown} handler Handler invoked on messages.
115
- * @returns {void}
116
114
  */
117
115
  addSub (channelName, handler) {
118
116
  const wrappedHandler = (message, name) => {
@@ -132,7 +130,6 @@ module.exports = class Plugin {
132
130
  *
133
131
  * @param {string} channelName Diagnostic channel name.
134
132
  * @param {(data: unknown) => object} transform Transform to compute the bound store.
135
- * @returns {void}
136
133
  */
137
134
  addBind (channelName, transform) {
138
135
  this._bindings.push(new StoreBinding(channelName, transform))
@@ -142,7 +139,6 @@ module.exports = class Plugin {
142
139
  * Attach an error to the current active span (if any).
143
140
  *
144
141
  * @param {unknown} error Error object or sentinel value.
145
- * @returns {void}
146
142
  */
147
143
  addError (error) {
148
144
  const store = legacyStorage.getStore()
@@ -29,6 +29,7 @@ class TracingPlugin extends Plugin {
29
29
  * @param {string} [opts.type]
30
30
  * @param {string} [opts.id]
31
31
  * @param {string} [opts.kind]
32
+ * @param {object} [opts.pluginConfig]
32
33
  * @returns {{ name: string, source: string | undefined }}
33
34
  */
34
35
  serviceName (opts = {}) {
@@ -46,7 +47,6 @@ class TracingPlugin extends Plugin {
46
47
  * @param {string} [opts.type]
47
48
  * @param {string} [opts.id]
48
49
  * @param {string} [opts.kind]
49
- * @returns {string}
50
50
  */
51
51
  operationName (opts = {}) {
52
52
  const {
@@ -95,10 +95,8 @@ function isDirectory (path) {
95
95
  }
96
96
 
97
97
  function isGitAvailable () {
98
- const isWindows = os.platform() === 'win32'
99
- const command = isWindows ? 'where' : 'which'
100
98
  try {
101
- cachedExec(command, ['git'])
99
+ cachedExec('git', ['--version'])
102
100
  return true
103
101
  } catch {
104
102
  incrementCountMetric(TELEMETRY_GIT_COMMAND_ERRORS, { command: 'check_git', exitCode: 'missing' })
@@ -104,7 +104,6 @@ function toHttpScheme (scheme) {
104
104
  * `REDACTED@host`. Returns the URL unchanged when no userinfo is present.
105
105
  *
106
106
  * @param {string} url
107
- * @returns {string}
108
107
  */
109
108
  function redactUrlCredentials (url) {
110
109
  const schemeEnd = url.indexOf('://')
@@ -29,7 +29,6 @@ function normalize (text, limit = 128) {
29
29
  *
30
30
  * @param {Sampler} sampler
31
31
  * @param {import('../../../../..').Span|import('../../../../..').SpanContext} span
32
- * @returns {boolean} `true` if the prompt completion should be sampled, otherwise `false`.
33
32
  */
34
33
  function isPromptCompletionSampled (sampler, span) {
35
34
  return sampler.isSampled(span)
@@ -52,7 +51,6 @@ module.exports = function makeUtilities (integrationName, tracerConfig) {
52
51
  * Determines whether a prompt completion should be sampled based on the configured sampling rate.
53
52
  *
54
53
  * @param {import('../../../../..').Span|import('../../../../..').SpanContext} span
55
- * @returns {boolean} `true` if the prompt completion should be sampled, otherwise `false`.
56
54
  */
57
55
  isPromptCompletionSampled: (span) => isPromptCompletionSampled(sampler, span),
58
56
  }
@@ -83,7 +83,6 @@ function getStatusValidator (config, optionName, defaultRanges, defaultValidator
83
83
 
84
84
  /**
85
85
  * @param {number} code
86
- * @returns {boolean}
87
86
  */
88
87
  function isValidStatusCode (code) {
89
88
  return errorStatusCodes[code] !== 1
@@ -102,6 +102,7 @@ const TEST_STATUS = 'test.status'
102
102
  const TEST_FINAL_STATUS = 'test.final_status'
103
103
  const TEST_PARAMETERS = 'test.parameters'
104
104
  const TEST_SKIP_REASON = 'test.skip_reason'
105
+ const TEST_SESSION_EMPTY_REASON = 'test.session.empty_reason'
105
106
  const TEST_IS_RUM_ACTIVE = 'test.is_rum_active'
106
107
  const TEST_CODE_OWNERS = 'test.codeowners'
107
108
  const TEST_SOURCE_FILE = 'test.source.file'
@@ -445,7 +446,6 @@ function addTestOptimizationRequest (requestPromises, responseNames, responseNam
445
446
  *
446
447
  * @param {string} testSuite
447
448
  * @param {string|undefined} testSuiteExecutionId
448
- * @returns {string}
449
449
  */
450
450
  function getTestSuiteExecutionKey (testSuite, testSuiteExecutionId) {
451
451
  return testSuiteExecutionId ? `${testSuite}\0${testSuiteExecutionId}` : testSuite
@@ -471,9 +471,11 @@ module.exports = {
471
471
  TEST_FINAL_STATUS,
472
472
  TEST_PARAMETERS,
473
473
  TEST_SKIP_REASON,
474
+ TEST_SESSION_EMPTY_REASON,
474
475
  TEST_IS_RUM_ACTIVE,
475
476
  setRumTestCorrelation,
476
477
  setRumTestTags,
478
+ setExpectedEmptyTestSessionTags,
477
479
  TEST_SOURCE_FILE,
478
480
  TEST_FAILURE_SCREENSHOT_UPLOADED,
479
481
  TEST_FAILURE_SCREENSHOT_UPLOAD_ERROR,
@@ -868,7 +870,6 @@ function finishAllTraceSpans (span) {
868
870
  * @param {import('../../opentracing/span')} testSpan
869
871
  * @param {boolean|undefined} isRumActive
870
872
  * @param {string} [browserVersion]
871
- * @returns {void}
872
873
  */
873
874
  function setRumTestTags (testSpan, isRumActive, browserVersion) {
874
875
  if (isRumActive) {
@@ -879,6 +880,24 @@ function setRumTestTags (testSpan, isRumActive, browserVersion) {
879
880
  }
880
881
  }
881
882
 
883
+ /**
884
+ * Marks a successful test session that intentionally executed no tests.
885
+ *
886
+ * @param {import('../../opentracing/span')} testSessionSpan
887
+ * @param {import('../../opentracing/span')|undefined} testModuleSpan
888
+ * @param {string} skipReason
889
+ * @param {string} emptyReason
890
+ */
891
+ function setExpectedEmptyTestSessionTags (testSessionSpan, testModuleSpan, skipReason, emptyReason) {
892
+ for (const span of [testSessionSpan, testModuleSpan]) {
893
+ if (!span) continue
894
+
895
+ span.setTag(TEST_STATUS, 'skip')
896
+ span.setTag(TEST_SKIP_REASON, skipReason)
897
+ span.setTag(TEST_SESSION_EMPTY_REASON, emptyReason)
898
+ }
899
+ }
900
+
882
901
  /**
883
902
  * @param {RumTestCorrelationContext} context
884
903
  * @param {import('../../opentracing/span')|undefined} activeSpan
@@ -942,7 +961,6 @@ function getTestCommonTags (name, suite, version, testFramework) {
942
961
  *
943
962
  * @param {string | undefined} testSuiteAbsolutePath
944
963
  * @param {string} sourceRoot
945
- * @returns {string}
946
964
  */
947
965
  function getTestSuitePath (testSuiteAbsolutePath, sourceRoot) {
948
966
  if (!testSuiteAbsolutePath) {
@@ -1069,7 +1087,6 @@ const codeOwnersPerEntries = new WeakMap()
1069
1087
 
1070
1088
  /**
1071
1089
  * @param {string} character
1072
- * @returns {string}
1073
1090
  */
1074
1091
  function escapeRegexCharacter (character) {
1075
1092
  return character.replaceAll(/[|\\{}()[\]^$+*?.]/g, String.raw`\$&`)
@@ -1077,7 +1094,6 @@ function escapeRegexCharacter (character) {
1077
1094
 
1078
1095
  /**
1079
1096
  * @param {string} pattern
1080
- * @returns {boolean}
1081
1097
  */
1082
1098
  function hasUnescapedWildcard (pattern) {
1083
1099
  for (let i = 0; i < pattern.length; i++) {
@@ -1093,7 +1109,6 @@ function hasUnescapedWildcard (pattern) {
1093
1109
 
1094
1110
  /**
1095
1111
  * @param {string} pattern
1096
- * @returns {string}
1097
1112
  */
1098
1113
  function codeOwnersPatternToRegexSource (pattern) {
1099
1114
  let source = ''
@@ -1135,7 +1150,10 @@ function getCodeOwnersPatternRegex (pattern) {
1135
1150
  }
1136
1151
 
1137
1152
  const directoryOnly = pattern.endsWith('/')
1138
- const normalizedPattern = pattern.replace(/^\/+/, '').replace(/\/+$/, '')
1153
+ let normalizedPattern = pattern.replace(/^\/+/, '')
1154
+ let normalizedPatternEnd = normalizedPattern.length
1155
+ while (normalizedPatternEnd > 0 && normalizedPattern[normalizedPatternEnd - 1] === '/') normalizedPatternEnd--
1156
+ normalizedPattern = normalizedPattern.slice(0, normalizedPatternEnd)
1139
1157
  const anchored = pattern.startsWith('/') || normalizedPattern.includes('/')
1140
1158
 
1141
1159
  if (!normalizedPattern) {
@@ -1169,7 +1187,6 @@ function setCodeOwnersPatternRegex (entry) {
1169
1187
  *
1170
1188
  * @param {RegExp|null} regex
1171
1189
  * @param {string} filename
1172
- * @returns {boolean}
1173
1190
  */
1174
1191
  function isCodeOwnersPatternMatch (regex, filename) {
1175
1192
  if (!regex || !filename) {
@@ -1548,7 +1565,6 @@ function applySkippedCoverageToFileCoverage (fileCoverage, skippedBitmap) {
1548
1565
  * @param {object} coverage
1549
1566
  * @param {object} skippedCoverage
1550
1567
  * @param {string} [rootDir]
1551
- * @returns {boolean}
1552
1568
  */
1553
1569
  function applySkippedCoverageToCoverage (coverage, skippedCoverage, rootDir) {
1554
1570
  const skippedCoverageByFilename = getSkippedCoverageByFilename(skippedCoverage)
@@ -1613,7 +1629,6 @@ function fromCoverageMapToCoverage (coverageMap) {
1613
1629
 
1614
1630
  /**
1615
1631
  * @param {number} code
1616
- * @returns {boolean}
1617
1632
  */
1618
1633
  function isAsciiDigit (code) {
1619
1634
  return code >= 0x30 && code <= 0x39
@@ -2039,7 +2054,6 @@ function getModifiedFilesFromDiff (diff) {
2039
2054
  *
2040
2055
  * @param {string | undefined} testSuite
2041
2056
  * @param {string} testName
2042
- * @returns {string}
2043
2057
  */
2044
2058
  function getTestOptimizationIdentity (testSuite, testName) {
2045
2059
  return JSON.stringify([testSuite, testName])
@@ -2050,7 +2064,6 @@ function getTestOptimizationIdentity (testSuite, testName) {
2050
2064
  *
2051
2065
  * @param {string | undefined} testSuite
2052
2066
  * @param {string} testName
2053
- * @returns {string}
2054
2067
  */
2055
2068
  function formatTestOptimizationName (testSuite, testName) {
2056
2069
  return testSuite ? `${testSuite} › ${testName}` : testName
@@ -2060,7 +2073,6 @@ function formatTestOptimizationName (testSuite, testName) {
2060
2073
  * Replaces characters that could make one test occupy multiple CI log lines.
2061
2074
  *
2062
2075
  * @param {string} value
2063
- * @returns {string}
2064
2076
  */
2065
2077
  function sanitizeTestOptimizationName (value) {
2066
2078
  return stripVTControlCharacters(value)
@@ -2074,7 +2086,6 @@ function sanitizeTestOptimizationName (value) {
2074
2086
  *
2075
2087
  * @param {string} value
2076
2088
  * @param {number} maxLength
2077
- * @returns {string}
2078
2089
  */
2079
2090
  function truncateTestOptimizationNameStart (value, maxLength) {
2080
2091
  if (value.length <= maxLength) return value
@@ -2090,7 +2101,6 @@ function truncateTestOptimizationNameStart (value, maxLength) {
2090
2101
  *
2091
2102
  * @param {string} value
2092
2103
  * @param {number} maxLength
2093
- * @returns {string}
2094
2104
  */
2095
2105
  function truncateTestOptimizationNameMiddle (value, maxLength) {
2096
2106
  if (value.length <= maxLength) return value
@@ -2109,7 +2119,6 @@ function truncateTestOptimizationNameMiddle (value, maxLength) {
2109
2119
  *
2110
2120
  * @param {string | undefined} testSuite
2111
2121
  * @param {string} testName
2112
- * @returns {string}
2113
2122
  */
2114
2123
  function formatTestOptimizationDisplayName (testSuite, testName) {
2115
2124
  const sanitizedSuite = testSuite ? sanitizeTestOptimizationName(testSuite) : ''
@@ -2133,7 +2142,6 @@ function formatTestOptimizationDisplayName (testSuite, testName) {
2133
2142
  * Renders a bounded bullet list for Test Optimization summaries.
2134
2143
  *
2135
2144
  * @param {Array<{ text: string, suffix?: string }>} items
2136
- * @returns {string}
2137
2145
  */
2138
2146
  function formatTestOptimizationList (items) {
2139
2147
  const shown = items.slice(0, MAX_TEST_OPTIMIZATION_SUMMARY_ITEMS)
@@ -2296,7 +2304,6 @@ function collectAttemptToFixExecutionFromTraceSpan (span, attemptToFixExecutions
2296
2304
  *
2297
2305
  * @param {{ meta?: Record<string, string> }} span
2298
2306
  * @param {TestManagementExecutions} executions
2299
- * @returns {void}
2300
2307
  */
2301
2308
  function collectTestManagementExecutionFromTraceSpan (span, executions) {
2302
2309
  const meta = span.meta
@@ -2402,7 +2409,6 @@ function addAttemptToFixResultLine (lines, result) {
2402
2409
  *
2403
2410
  * @param {AttemptToFixExecutions} attemptToFixExecutions
2404
2411
  * @param {boolean} [includeTestNames]
2405
- * @returns {string}
2406
2412
  */
2407
2413
  function formatAttemptToFixSummary (attemptToFixExecutions, includeTestNames = true) {
2408
2414
  if (attemptToFixExecutions.size === 0) return ''
@@ -2455,7 +2461,6 @@ function formatAttemptToFixSummary (attemptToFixExecutions, includeTestNames = t
2455
2461
  *
2456
2462
  * @param {TestManagementExecutions} executions
2457
2463
  * @param {boolean} [includeTestNames]
2458
- * @returns {string}
2459
2464
  */
2460
2465
  function formatTestManagementSummary (executions, includeTestNames = true) {
2461
2466
  if (executions.size === 0) return ''
@@ -2506,7 +2511,6 @@ function formatTestManagementSummary (executions, includeTestNames = true) {
2506
2511
  * Formats the dynamic-name warning section of the Test Optimization summary.
2507
2512
  *
2508
2513
  * @param {Set<string>} newTestsWithDynamicNames
2509
- * @returns {string}
2510
2514
  */
2511
2515
  function formatDynamicNamesSummary (newTestsWithDynamicNames) {
2512
2516
  if (newTestsWithDynamicNames.size === 0) return ''
@@ -19,7 +19,6 @@ const SPECIAL_CHARACTER_SEGMENT = /[%&'()*+,:=@]/
19
19
  /**
20
20
  * Extract full URL from HTTP request
21
21
  * @param {import('http').IncomingMessage} req
22
- * @returns {string} Full URL
23
22
  */
24
23
  function extractURL (req) {
25
24
  const headers = req.headers
@@ -42,7 +41,6 @@ function getProtocol (req) {
42
41
  *
43
42
  * @param {object} config
44
43
  * @param {string} url
45
- * @returns {string} obfuscated URL
46
44
  */
47
45
  function obfuscateQs (config, url) {
48
46
  const { queryStringObfuscation } = config
@@ -114,7 +112,6 @@ function getQsObfuscator (config) {
114
112
  * @param {string} base `scheme://host[:port]`
115
113
  * @param {string} [pathname] raw request path, may include `?query`
116
114
  * @param {string} strippedUrl `base` + query-stripped path (used when there is no query)
117
- * @returns {string}
118
115
  */
119
116
  function buildClientHttpUrl (config, base, pathname, strippedUrl) {
120
117
  if (pathname?.includes('?')) {
@@ -133,7 +130,6 @@ function buildClientHttpUrl (config, base, pathname, strippedUrl) {
133
130
  * - Cross tracers compatibility
134
131
  *
135
132
  * @param {string} url
136
- * @returns {string} Url path
137
133
  */
138
134
  function extractPathFromUrl (url) {
139
135
  if (!url) return '/'
@@ -146,7 +142,6 @@ function extractPathFromUrl (url) {
146
142
  * Calculate http.endpoint from URL path
147
143
  *
148
144
  * @param {string} url
149
- * @returns {string} The normalized endpoint
150
145
  */
151
146
  function calculateHttpEndpoint (url) {
152
147
  const path = extractPathFromUrl(url)
@@ -86,7 +86,6 @@ class PrioritySampler {
86
86
 
87
87
  /**
88
88
  * @param {DatadogSpan} span
89
- * @returns {boolean} True if the trace should be sampled based on priority.
90
89
  */
91
90
  isSampled (span) {
92
91
  const priority = this._getPriorityFromAuto(span)
@@ -99,7 +98,6 @@ class PrioritySampler {
99
98
  *
100
99
  * @param {DatadogSpan} span
101
100
  * @param {boolean} [auto] - Whether to use automatic sampling if no manual tags are present.
102
- * @returns {void}
103
101
  */
104
102
  sample (span, auto = true) {
105
103
  if (!span) return
@@ -131,7 +129,6 @@ class PrioritySampler {
131
129
  * Updates agent-provided sampling rates keyed by `service:,env:`.
132
130
  *
133
131
  * @param {Record<string, number>} rates
134
- * @returns {void}
135
132
  */
136
133
  update (rates) {
137
134
  const samplers = {}
@@ -151,7 +148,6 @@ class PrioritySampler {
151
148
  * Validates that a sampling priority value is one of the allowed constants.
152
149
  *
153
150
  * @param {SamplingPriority|undefined} samplingPriority
154
- * @returns {boolean}
155
151
  */
156
152
  validate (samplingPriority) {
157
153
  switch (samplingPriority) {
@@ -277,7 +273,6 @@ class PrioritySampler {
277
273
  * records the effective rate on the trace.
278
274
  *
279
275
  * @param {DatadogSpanContext} context
280
- * @returns {boolean}
281
276
  */
282
277
  _isSampledByRateLimit (context) {
283
278
  // TODO: Change underscored properties to private ones.
@@ -316,7 +311,6 @@ class PrioritySampler {
316
311
  * Tags the trace with a decision maker when priority is keep, or removes it otherwise.
317
312
  *
318
313
  * @param {DatadogSpan} span
319
- * @returns {void}
320
314
  */
321
315
  #addDecisionMaker (span) {
322
316
  const context = span.context()
@@ -16,7 +16,6 @@ const ENTRYPOINT_PATH = require.main?.filename || ''
16
16
  * Sanitize a process tag value
17
17
  *
18
18
  * @param {string} value
19
- * @returns {string}
20
19
  */
21
20
  function sanitize (value) {
22
21
  return String(value)
@@ -1,42 +1,139 @@
1
1
  'use strict'
2
2
 
3
- const { profiler } = require('./profiling')
3
+ const dc = require('dc-polyfill')
4
4
 
5
- globalThis[Symbol.for('dd-trace')].beforeExitHandlers.add(() => { profiler.stop() })
5
+ const log = require('./log')
6
6
 
7
- module.exports = {
8
- /**
9
- * @param {import('./config/config-base')} config - Tracer configuration
10
- */
11
- start (config) {
7
+ const configUpdateChannel = dc.channel('datadog:config:update')
8
+
9
+ /** @type {import('./profiling/ssi-heuristics').SSIHeuristics | undefined} */
10
+ let activeSSIHeuristics
11
+
12
+ /** @type {import('./profiling') | undefined} */
13
+ let profilingModule
14
+
15
+ function getProfilingModule () {
16
+ profilingModule ??= require('./profiling')
17
+ return profilingModule
18
+ }
19
+
20
+ // The profiling engine can stop itself (e.g. a collection error) without going through stop(), so
21
+ // read its state directly rather than caching a flag that could drift out of sync. Checking
22
+ // `profilingModule` first avoids forcing the profiling engine (and its native crashtracker binding)
23
+ // to load just to read this.
24
+ function isStarted () {
25
+ return profilingModule !== undefined && profilingModule.profiler.enabled
26
+ }
27
+
28
+ /** @type {typeof import('./profiling/ssi-heuristics') | undefined} */
29
+ let ssiHeuristicsModule
30
+
31
+ function getSSIHeuristicsModule () {
32
+ ssiHeuristicsModule ??= require('./profiling/ssi-heuristics')
33
+ return ssiHeuristicsModule
34
+ }
35
+
36
+ function disableSSIHeuristics () {
37
+ if (!activeSSIHeuristics) return
38
+ activeSSIHeuristics.disable()
39
+ activeSSIHeuristics = undefined
40
+ }
41
+
42
+ /**
43
+ * @param {import('./config/config-base')} config - Tracer configuration
44
+ */
45
+ function start (config) {
46
+ try {
12
47
  // Forward the full tracer config to the profiling layer.
13
48
  // Profiling code is responsible for deriving the specific options it needs.
14
- return profiler.start(config)
15
- },
16
-
17
- stop () {
18
- profiler.stop()
19
- },
20
-
21
- /**
22
- * Declares the set of custom label keys that will be used with
23
- * `runWithLabels`.
24
- *
25
- * @param {Iterable<string>} keys - Custom label key names
26
- */
27
- setCustomLabelKeys: (keys) => {
28
- profiler.setCustomLabelKeys(keys)
29
- },
30
-
31
- /**
32
- * Runs a function with custom profiling labels attached to wall profiler samples.
33
- *
34
- * @param {Record<string, string | number>} labels - Custom labels to attach
35
- * @param {function(): T} fn - Function to execute with the labels
36
- * @returns {T} The return value of fn
37
- * @template T
38
- */
39
- runWithLabels: (labels, fn) => {
40
- return profiler.runWithLabels(labels, fn)
41
- },
49
+ return getProfilingModule().profiler.start(config)
50
+ } catch (error) {
51
+ log.error(
52
+ 'Error starting profiler. For troubleshooting tips, see <https://dtdg.co/nodejs-profiler-troubleshooting>',
53
+ error
54
+ )
55
+ return false
56
+ }
57
+ }
58
+
59
+ function stop () {
60
+ // A stop command for a profiler that has never been loaded is already satisfied. Once loaded,
61
+ // always forward it so the profiling layer can also cancel a restart queued during shutdown.
62
+ if (profilingModule === undefined) return
63
+
64
+ try {
65
+ profilingModule.profiler.stop()
66
+ } catch (error) {
67
+ log.error(
68
+ 'Error stopping profiler. For troubleshooting tips, see <https://dtdg.co/nodejs-profiler-troubleshooting>',
69
+ error
70
+ )
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Declares the set of custom label keys that will be used with
76
+ * `runWithLabels`.
77
+ *
78
+ * @param {Iterable<string>} keys - Custom label key names
79
+ */
80
+ function setCustomLabelKeys (keys) {
81
+ getProfilingModule().profiler.setCustomLabelKeys(keys)
42
82
  }
83
+
84
+ /**
85
+ * Runs a function with custom profiling labels attached to wall profiler samples.
86
+ *
87
+ * @param {Record<string, string | number>} labels - Custom labels to attach
88
+ * @param {function(): T} fn - Function to execute with the labels
89
+ * @returns {T} The return value of fn
90
+ * @template T
91
+ */
92
+ function runWithLabels (labels, fn) {
93
+ return getProfilingModule().profiler.runWithLabels(labels, fn)
94
+ }
95
+
96
+ configUpdateChannel.subscribe((config) => {
97
+ const enabled = config.profiling.DD_PROFILING_ENABLED
98
+ if (enabled === 'true') {
99
+ // A non-auto value means the SSI heuristics no longer get a say; disable them so a trigger that
100
+ // fires after this publish can't start the profiler behind this decision's back.
101
+ disableSSIHeuristics()
102
+ // Leave an already-running profiler alone; otherwise an unrelated remote-config publish
103
+ // (e.g. an unrelated sampling-rate change) would restart it on every update.
104
+ if (!isStarted()) start(config)
105
+ } else if (enabled === 'false') {
106
+ disableSSIHeuristics()
107
+ stop()
108
+ } else if (enabled === 'auto') {
109
+ if (!isStarted() && !activeSSIHeuristics) {
110
+ // 'auto' defers the start decision to SSI heuristics. A running profiler already reflects a
111
+ // decision that was made (by SSI or a prior unconditional enablement), so leave it alone
112
+ // rather than stopping and re-enabling it on every subsequent config publication. Also guard
113
+ // against creating another active instance; each SSIHeuristics instance owns listeners and a
114
+ // timer until the heuristic makes its decision or is explicitly disabled.
115
+ const { SSIHeuristics } = getSSIHeuristicsModule()
116
+ const heuristics = new SSIHeuristics(config)
117
+ activeSSIHeuristics = heuristics
118
+ heuristics.start()
119
+ heuristics.onTriggered(() => {
120
+ // Explicit true/false publishes disable the heuristics, so reaching this callback guarantees
121
+ // the latest valid published value is still 'auto'.
122
+ if (!isStarted()) start(config)
123
+ // The heuristic has made its decision, so release all of its listeners and timer before
124
+ // dropping the module-level reference. This does not stop the profiler that was just
125
+ // started; it only tears down the completed heuristic.
126
+ heuristics.disable()
127
+ if (activeSSIHeuristics === heuristics) activeSSIHeuristics = undefined
128
+ })
129
+ }
130
+ } else {
131
+ // Invalid config should preserve the last valid profiling decision, not accidentally behave
132
+ // like 'auto' or crash the customer application.
133
+ log.warn('Unexpected DD_PROFILING_ENABLED value: %o', enabled)
134
+ }
135
+ })
136
+
137
+ globalThis[Symbol.for('dd-trace')].beforeExitHandlers.add(stop)
138
+
139
+ module.exports = { isStarted, start, stop, setCustomLabelKeys, runWithLabels }
@@ -15,7 +15,6 @@ const processTags = require('../../process-tags')
15
15
  * profile event.
16
16
  *
17
17
  * @param {string} [enabled] - config.profiling.DD_PROFILING_ENABLED ('true' | 'false' | 'auto')
18
- * @returns {string}
19
18
  */
20
19
  function getActivation (enabled) {
21
20
  if (enabled === 'auto') return 'auto'