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
@@ -4,15 +4,19 @@ const { readFile } = require('fs')
4
4
  const { types } = require('util')
5
5
  const { join } = require('path')
6
6
  const { Worker, MessageChannel, threadId: parentThreadId } = require('worker_threads')
7
+ const dc = require('dc-polyfill')
7
8
  const log = require('../log')
8
9
  const { fetchAgentInfo } = require('../agent/info')
10
+ const telemetryMetrics = require('../telemetry/metrics')
9
11
  const getDebuggerConfig = require('./config')
10
12
  const {
11
13
  DEBUGGER_DIAGNOSTICS_V1,
12
14
  DEBUGGER_INPUT_DIRECT,
13
15
  DEBUGGER_INPUT_V2,
16
+ GUARDRAIL_METRICS_FLUSH_INTERVAL_MS,
14
17
  INSPECT_SEGMENT_GLOBAL_PROPERTY,
15
18
  } = require('./constants')
19
+ const { GuardrailMetrics, TELEMETRY_NAMESPACE } = require('./guardrail-metrics')
16
20
  const { installProbeSampler, uninstallProbeSampler } = require('./probe_sampler')
17
21
 
18
22
  /**
@@ -23,12 +27,20 @@ const { installProbeSampler, uninstallProbeSampler } = require('./probe_sampler'
23
27
  * @typedef {import('../remote_config')} RemoteConfig
24
28
  */
25
29
 
30
+ // Published by telemetry right before it sends its final metrics on process exit. The flush interval timer is unref'ed
31
+ // and the worker does not keep the process alive, so without this hook everything counted since the last tick would
32
+ // be lost when the application exits on its own.
33
+ const TELEMETRY_APP_CLOSING_CHANNEL = 'datadog:telemetry:app-closing'
34
+
26
35
  let worker = null
27
36
  let configChannel = null
28
37
  let ackId = 0
29
38
  let rcAckCallbacks = null
30
39
  let rc = null
31
40
  let inputPath = null
41
+ /** @type {GuardrailMetrics | null} */
42
+ let guardrailMetrics = null
43
+ let guardrailMetricsTimer = null
32
44
 
33
45
  // eslint-disable-next-line eslint-rules/eslint-process-env
34
46
  const { NODE_OPTIONS, ...env } = process.env
@@ -43,7 +55,6 @@ module.exports = {
43
55
  /**
44
56
  * Check if the Debugger worker is currently running
45
57
  *
46
- * @returns {boolean} True if the worker is started, false otherwise
47
58
  */
48
59
  function isStarted () {
49
60
  return worker !== null
@@ -77,7 +88,13 @@ function start (config, rcInstance) {
77
88
  debuggerGlobals.utilTypes = types
78
89
  debuggerGlobals[INSPECT_SEGMENT_GLOBAL_PROPERTY] = require('./inspect-segment')
79
90
 
80
- const probeSamplerBuffer = installProbeSampler()
91
+ const guardrailMetricsBuffer = GuardrailMetrics.createBuffer()
92
+ guardrailMetrics = new GuardrailMetrics(guardrailMetricsBuffer)
93
+ guardrailMetricsTimer = setInterval(flushGuardrailMetrics, GUARDRAIL_METRICS_FLUSH_INTERVAL_MS)
94
+ guardrailMetricsTimer.unref?.()
95
+ dc.subscribe(TELEMETRY_APP_CLOSING_CHANNEL, flushGuardrailMetrics)
96
+
97
+ const probeSamplerBuffer = installProbeSampler(guardrailMetrics)
81
98
 
82
99
  readProbeFile(config.dynamicInstrumentation.probeFile, (probes) => {
83
100
  const action = 'apply'
@@ -125,6 +142,7 @@ function start (config, rcInstance) {
125
142
  logPort: logChannel.port1,
126
143
  configPort: configChannel.port1,
127
144
  probeSamplerBuffer,
145
+ guardrailMetricsBuffer,
128
146
  },
129
147
  transferList: [probeChannel.port1, logChannel.port1, configChannel.port1],
130
148
  }
@@ -137,6 +155,11 @@ function start (config, rcInstance) {
137
155
  )
138
156
  })
139
157
 
158
+ const threadPausedMetric = telemetryMetrics.manager.namespace(TELEMETRY_NAMESPACE)
159
+ .distribution('execution.pause.duration')
160
+ worker.on('message', (/** @type {{ type: string, durationMs: number }} */ { type, durationMs }) => {
161
+ if (type === 'thread-paused') threadPausedMetric.track(durationMs)
162
+ })
140
163
  worker.on('error', (err) => log.error('[debugger] worker thread error', err))
141
164
  worker.on('messageerror', (err) => log.error('[debugger] received "messageerror" from worker', err))
142
165
 
@@ -211,6 +234,20 @@ function cleanup (error) {
211
234
  configChannel = null
212
235
  inputPath = null
213
236
 
237
+ if (guardrailMetricsTimer !== null) {
238
+ clearInterval(guardrailMetricsTimer)
239
+ guardrailMetricsTimer = null
240
+ }
241
+ if (guardrailMetrics !== null) {
242
+ dc.unsubscribe(TELEMETRY_APP_CLOSING_CHANNEL, flushGuardrailMetrics)
243
+ // Report what the worker counted up until it was stopped. Known limitation: `Worker#terminate()` interrupts the
244
+ // worker asynchronously, so anything it counts between this drain and its actual termination is lost. That only
245
+ // concerns events still sitting in the worker's upload buffer, which die with the worker anyway, so it isn't worth
246
+ // deferring the drain until the worker has exited.
247
+ flushGuardrailMetrics()
248
+ guardrailMetrics = null
249
+ }
250
+
214
251
  // Call any pending ack callbacks
215
252
  // Pass error for unexpected exits, or undefined for graceful shutdown
216
253
  if (rcAckCallbacks) {
@@ -223,6 +260,17 @@ function cleanup (error) {
223
260
  }
224
261
  }
225
262
 
263
+ /**
264
+ * Convert the guardrail counters accumulated by the probe sampler and the worker into telemetry metrics.
265
+ */
266
+ function flushGuardrailMetrics () {
267
+ if (guardrailMetrics === null) return
268
+ const namespace = telemetryMetrics.manager.namespace(TELEMETRY_NAMESPACE)
269
+ guardrailMetrics.drain((metric, tags, count) => {
270
+ namespace.count(metric, tags).inc(count)
271
+ })
272
+ }
273
+
226
274
  /**
227
275
  * Detect which debugger endpoint is available on the agent
228
276
  *
@@ -34,7 +34,6 @@ module.exports = inspectSegment
34
34
  * truncates objects before inspecting them.
35
35
  *
36
36
  * @param {unknown} value
37
- * @returns {string}
38
37
  */
39
38
  function inspectSegment (value) {
40
39
  if (value === null || (typeof value !== 'object' && typeof value !== 'function')) {
@@ -99,7 +98,6 @@ function inspectSegment (value) {
99
98
  *
100
99
  * @param {Collection} value
101
100
  * @param {boolean} isMap
102
- * @returns {string}
103
101
  */
104
102
  function inspectCollection (value, isMap) {
105
103
  if (NODE_MAJOR !== 18) return inspect(value, segmentInspectOptions)
@@ -137,7 +135,6 @@ function inspectCollection (value, isMap) {
137
135
  * Determine whether inspecting a value could invoke a proxy trap or toStringTag getter.
138
136
  *
139
137
  * @param {unknown} value
140
- * @returns {boolean}
141
138
  */
142
139
  function inspectionCanRunUserCode (value) {
143
140
  const type = typeof value
@@ -1,7 +1,13 @@
1
1
  'use strict'
2
2
 
3
+ const { types } = require('node:util')
4
+
3
5
  const { MAX_SNAPSHOTS_PER_SECOND_GLOBALLY } = require('./devtools_client/defaults')
6
+ const { MAX_MESSAGE_LENGTH } = require('./constants')
7
+ const { EVENT_TYPE, SKIPPED_REASON } = require('./guardrail-metrics')
4
8
  const {
9
+ CONDITION_ERROR_FLAG,
10
+ CONDITION_ERROR_THROTTLE_NS,
5
11
  DD_TRACE_SYMBOL,
6
12
  MAX_SAMPLED_PROBES_PER_PAUSE,
7
13
  PROBE_SAMPLER_SYMBOL,
@@ -22,12 +28,20 @@ module.exports = {
22
28
  /**
23
29
  * Install the runtime sampler in the debuggee context.
24
30
  *
31
+ * @param {import('./guardrail-metrics').GuardrailMetrics} guardrailMetrics - Counters for skipped probe hits.
25
32
  * @returns {SharedArrayBuffer} The shared sampler buffer to pass to the debugger worker.
26
33
  */
27
- function installProbeSampler () {
34
+ function installProbeSampler (guardrailMetrics) {
28
35
  const buffer = createProbeSamplerBuffer()
29
36
 
30
37
  const lastCaptureNsByProbeId = new Map()
38
+ /**
39
+ * Probes whose condition recently failed to evaluate, keyed by probe id. The error is kept until the worker picks it
40
+ * up for the error result.
41
+ *
42
+ * @type {Map<string, { throttledUntilNs: bigint, error: string | undefined }>}
43
+ */
44
+ const conditionErrorByProbeId = new Map()
31
45
  const sampledProbeIndexes = new Int32Array(buffer)
32
46
  Atomics.store(sampledProbeIndexes, SAMPLED_PROBE_COUNT_INDEX, 0)
33
47
  Atomics.store(sampledProbeIndexes, SAMPLED_PROBE_OVERFLOW_INDEX, 0)
@@ -44,27 +58,29 @@ function installProbeSampler () {
44
58
  * @param {string} probeId - The probe id.
45
59
  * @param {bigint} nsBetweenSampling - Minimum nanoseconds between samples for this probe.
46
60
  * @param {boolean} isSnapshotProducingProbe - Whether this probe counts toward the global snapshot sample limit.
47
- * @returns {boolean} Whether this probe should make the breakpoint condition pause.
48
61
  */
49
62
  makeSampleDecision (probeIndex, probeId, nsBetweenSampling, isSnapshotProducingProbe) {
50
63
  const now = process.hrtime.bigint()
51
64
  const lastCaptureNs = lastCaptureNsByProbeId.get(probeId)
52
- if (lastCaptureNs !== undefined && now - lastCaptureNs < nsBetweenSampling) return false
65
+ if (lastCaptureNs !== undefined && now - lastCaptureNs < nsBetweenSampling) {
66
+ guardrailMetrics.eventSkipped(
67
+ SKIPPED_REASON.RATE_LIMIT_PROBE,
68
+ isSnapshotProducingProbe === true ? EVENT_TYPE.SNAPSHOT : EVENT_TYPE.LOG
69
+ )
70
+ return false
71
+ }
53
72
 
54
73
  let shouldResetGlobalSnapshotRateWindow = false
55
74
  if (isSnapshotProducingProbe === true) {
56
75
  if (now - globalSnapshotSamplingRateWindowStart > oneSecondNs) {
57
76
  shouldResetGlobalSnapshotRateWindow = true
58
77
  } else if (snapshotsSampledWithinTheLastSecond >= MAX_SNAPSHOTS_PER_SECOND_GLOBALLY) {
78
+ guardrailMetrics.eventSkipped(SKIPPED_REASON.RATE_LIMIT_GLOBAL, EVENT_TYPE.SNAPSHOT)
59
79
  return false
60
80
  }
61
81
  }
62
82
 
63
- const sampledProbeCount = Atomics.add(sampledProbeIndexes, SAMPLED_PROBE_COUNT_INDEX, 1)
64
- if (sampledProbeCount >= MAX_SAMPLED_PROBES_PER_PAUSE) {
65
- Atomics.store(sampledProbeIndexes, SAMPLED_PROBE_OVERFLOW_INDEX, 1)
66
- return false
67
- }
83
+ if (!storeSampledProbeIndex(probeIndex)) return false
68
84
 
69
85
  if (isSnapshotProducingProbe === true) {
70
86
  if (shouldResetGlobalSnapshotRateWindow === true) {
@@ -76,10 +92,56 @@ function installProbeSampler () {
76
92
  }
77
93
 
78
94
  lastCaptureNsByProbeId.set(probeId, now)
79
- Atomics.store(sampledProbeIndexes, SAMPLED_PROBE_INDEXES_START + sampledProbeCount, probeIndex)
80
95
  return true
81
96
  },
82
97
 
98
+ /**
99
+ * Decide if a probe's condition should be evaluated, or skipped because a recent evaluation error throttled it.
100
+ *
101
+ * @param {string} probeId - The probe id.
102
+ */
103
+ shouldEvaluateCondition (probeId) {
104
+ const state = conditionErrorByProbeId.get(probeId)
105
+ if (state === undefined) return true
106
+ if (process.hrtime.bigint() < state.throttledUntilNs) return false
107
+ conditionErrorByProbeId.delete(probeId)
108
+ return true
109
+ },
110
+
111
+ /**
112
+ * Record that a probe's condition threw, throttle the probe, and request a pause if the error can be reported.
113
+ *
114
+ * Error results bypass the per-probe and global rate limits: they are rate limited by the throttle instead, which
115
+ * allows one error result per probe per window. If the shared buffer is full, the error is dropped but the throttle
116
+ * is retained.
117
+ *
118
+ * @param {number} probeIndex - The worker-side probe sampling index.
119
+ * @param {string} probeId - The probe id.
120
+ * @param {unknown} error - The value thrown by the condition.
121
+ */
122
+ conditionError (probeIndex, probeId, error) {
123
+ const stored = storeSampledProbeIndex(probeIndex | CONDITION_ERROR_FLAG)
124
+ conditionErrorByProbeId.set(probeId, {
125
+ throttledUntilNs: process.hrtime.bigint() + CONDITION_ERROR_THROTTLE_NS,
126
+ error: stored ? describeError(error) : undefined,
127
+ })
128
+ return stored
129
+ },
130
+
131
+ /**
132
+ * Hand over the recorded condition error for a probe to the worker. Called by the worker on the paused thread.
133
+ *
134
+ * @param {string} probeId - The probe id.
135
+ * @returns {string | undefined} The error description, if any.
136
+ */
137
+ takeConditionError (probeId) {
138
+ const state = conditionErrorByProbeId.get(probeId)
139
+ if (state === undefined) return
140
+ const { error } = state
141
+ state.error = undefined
142
+ return error
143
+ },
144
+
83
145
  /**
84
146
  * Remove cached sampling state for a probe.
85
147
  *
@@ -87,9 +149,25 @@ function installProbeSampler () {
87
149
  */
88
150
  remove (probeId) {
89
151
  lastCaptureNsByProbeId.delete(probeId)
152
+ conditionErrorByProbeId.delete(probeId)
90
153
  },
91
154
  }
92
155
 
156
+ /**
157
+ * Hand a sampled probe index over to the worker for the upcoming pause.
158
+ *
159
+ * @param {number} value - The probe sampling index, possibly with flags set.
160
+ */
161
+ function storeSampledProbeIndex (value) {
162
+ const sampledProbeCount = Atomics.add(sampledProbeIndexes, SAMPLED_PROBE_COUNT_INDEX, 1)
163
+ if (sampledProbeCount >= MAX_SAMPLED_PROBES_PER_PAUSE) {
164
+ Atomics.store(sampledProbeIndexes, SAMPLED_PROBE_OVERFLOW_INDEX, 1)
165
+ return false
166
+ }
167
+ Atomics.store(sampledProbeIndexes, SAMPLED_PROBE_INDEXES_START + sampledProbeCount, value)
168
+ return true
169
+ }
170
+
93
171
  return buffer
94
172
  }
95
173
 
@@ -100,6 +178,52 @@ function uninstallProbeSampler () {
100
178
  delete ddTraceGlobal[Symbol.for(PROBE_SAMPLER_SYMBOL)]
101
179
  }
102
180
 
181
+ /**
182
+ * Describe a value thrown by a probe condition without invoking user code. Conditions can throw anything, including
183
+ * errors with accessors and proxies whose traps have side effects.
184
+ *
185
+ * @param {unknown} error - The thrown value.
186
+ */
187
+ function describeError (error) {
188
+ if (typeof error === 'string') return truncateErrorDescription(error)
189
+ if (error === null || (typeof error !== 'object' && typeof error !== 'function')) {
190
+ return 'Unknown evaluation error'
191
+ }
192
+
193
+ const name = getErrorStringProperty(error, 'name')
194
+ const message = getErrorStringProperty(error, 'message')
195
+ if (name === undefined) return truncateErrorDescription(message ?? 'Unknown evaluation error')
196
+ if (message === undefined) return truncateErrorDescription(name)
197
+
198
+ return truncateErrorDescription(`${name}: ${message}`)
199
+ }
200
+
201
+ /**
202
+ * Bound an error description before retaining or transferring it.
203
+ *
204
+ * @param {string} description - The description to bound.
205
+ */
206
+ function truncateErrorDescription (description) {
207
+ return description.length > MAX_MESSAGE_LENGTH
208
+ ? `${description.slice(0, MAX_MESSAGE_LENGTH)}…`
209
+ : description
210
+ }
211
+
212
+ /**
213
+ * Read a string-valued error property without invoking accessors or proxy traps.
214
+ *
215
+ * @param {object} error - The thrown object to inspect.
216
+ * @param {'name' | 'message'} property - The property to find.
217
+ */
218
+ function getErrorStringProperty (error, property) {
219
+ while (error !== null) {
220
+ if (types.isProxy(error)) return
221
+ const descriptor = Object.getOwnPropertyDescriptor(error, property)
222
+ if (descriptor !== undefined) return typeof descriptor.value === 'string' ? descriptor.value : undefined
223
+ error = Object.getPrototypeOf(error)
224
+ }
225
+ }
226
+
103
227
  /**
104
228
  * Create the shared buffer used to hand sampled probe indexes from breakpoint conditions to the debugger worker.
105
229
  *
@@ -3,13 +3,43 @@
3
3
  const DD_TRACE_SYMBOL = 'dd-trace'
4
4
  const PROBE_SAMPLER_SYMBOL = 'dd-trace.debugger.probeSampler'
5
5
 
6
- // Shared sampler contract used by the main debugger bootstrap and the devtools worker.
6
+ // Shared sampler contract used by the main debugger bootstrap and the devtools worker. The debuggee hands sampled
7
+ // probes to the worker through a shared Int32Array, drained by the worker on every pause:
8
+ //
9
+ // +----------+----------+----------+----------+- - - -+------------+
10
+ // slot | 0 | 1 | 2 | 3 | | 2+MAX-1 |
11
+ // holds | count | overflow | value | value | ... | value |
12
+ // +----------+----------+----------+----------+- - - -+------------+
13
+ // ^COUNT ^OVERFLOW ^INDEXES_START
7
14
  const MAX_SAMPLED_PROBES_PER_PAUSE = 256
8
15
  const SAMPLED_PROBE_COUNT_INDEX = 0
9
16
  const SAMPLED_PROBE_OVERFLOW_INDEX = 1
10
17
  const SAMPLED_PROBE_INDEXES_START = 2
11
18
 
19
+ // Each value above is a probe sampling index, with this flag set in bit 30 when the pause is for reporting a
20
+ // condition evaluation error instead of a probe result. Bit 31 stays unused because the array is signed:
21
+ //
22
+ // +--------+------------+--------------------------------------------+
23
+ // bit | 31 | 30 | 29..0 |
24
+ // means | unused | CONDITION_ | samplingIndex |
25
+ // | (sign) | ERROR_FLAG | |
26
+ // +--------+------------+--------------------------------------------+
27
+ //
28
+ // 0x0000_0007 probe #7 matched -> worker captures as usual
29
+ // 0x4000_0007 probe #7's condition threw -> worker takes the recorded error, captures nothing
30
+ //
31
+ // write: probeIndex | CONDITION_ERROR_FLAG
32
+ // read: value & ~CONDITION_ERROR_FLAG -> the sampling index
33
+ // value & CONDITION_ERROR_FLAG -> non-zero when the condition threw
34
+ const CONDITION_ERROR_FLAG = 1 << 30
35
+
36
+ // A probe whose condition failed to evaluate is not evaluated again for this long. One error result is reported per
37
+ // window, so a probe with a broken condition stays visible without repeatedly paying for the failing evaluation.
38
+ const CONDITION_ERROR_THROTTLE_NS = 5n * 60n * 1_000_000_000n // 5 minutes
39
+
12
40
  module.exports = {
41
+ CONDITION_ERROR_FLAG,
42
+ CONDITION_ERROR_THROTTLE_NS,
13
43
  DD_TRACE_SYMBOL,
14
44
  MAX_SAMPLED_PROBES_PER_PAUSE,
15
45
  PROBE_SAMPLER_SYMBOL,
@@ -207,7 +207,6 @@ class DogStatsDClient {
207
207
  /**
208
208
  * @param {boolean|(() => void)} [forceTelemetry] - Whether to ignore the telemetry interval, or completion callback
209
209
  * @param {() => void} [done] - Called after serverless deliveries complete
210
- * @returns {void}
211
210
  */
212
211
  flush (forceTelemetry = false, done) {
213
212
  if (typeof forceTelemetry === 'function') {
@@ -238,7 +237,6 @@ class DogStatsDClient {
238
237
  /**
239
238
  * @param {boolean} force - Whether to ignore the telemetry interval
240
239
  * @param {((send: (done?: () => void) => void) => void)} [track] - Tracks a non-serverless delivery
241
- * @returns {void}
242
240
  */
243
241
  #flushTelemetry (force, track) {
244
242
  const telemetry = this.telemetry
@@ -291,7 +289,6 @@ class DogStatsDClient {
291
289
  * @param {DogStatsDBufferState} state - Payload state to flush
292
290
  * @param {boolean} recordTelemetry - Whether to record the transport outcome
293
291
  * @param {((send: (done?: () => void) => void) => void)} [track] - Tracks a non-serverless delivery
294
- * @returns {void}
295
292
  */
296
293
  #flush (state, recordTelemetry, track) {
297
294
  const queue = this._enqueue(state)
@@ -314,7 +311,6 @@ class DogStatsDClient {
314
311
 
315
312
  /**
316
313
  * @param {number} bytes - Number of bytes sent
317
- * @returns {void}
318
314
  */
319
315
  #recordSent (bytes) {
320
316
  const telemetry = this.telemetry
@@ -326,7 +322,6 @@ class DogStatsDClient {
326
322
  /**
327
323
  * @param {number} bytes - Number of bytes dropped
328
324
  * @param {number} [packets] - Number of packets dropped
329
- * @returns {void}
330
325
  */
331
326
  #recordDropped (bytes, packets = 1) {
332
327
  const telemetry = this.telemetry
@@ -341,7 +336,6 @@ class DogStatsDClient {
341
336
  * @param {Buffer[]} queue - The metrics to send
342
337
  * @param {boolean} recordTelemetry - Whether to record the transport outcome
343
338
  * @param {() => void} [done] - Called after delivery completes
344
- * @returns {void}
345
339
  * @memberof DogStatsDClient
346
340
  */
347
341
  _sendHttp (queue, recordTelemetry, done) {
@@ -375,7 +369,6 @@ class DogStatsDClient {
375
369
  * @param {Buffer[]} queue - The metrics to send
376
370
  * @param {boolean} recordTelemetry - Whether to record the transport outcome
377
371
  * @param {() => void} [done] - Called after delivery completes
378
- * @returns {void}
379
372
  * @memberof DogStatsDClient
380
373
  */
381
374
  _sendUdp (queue, recordTelemetry, done) {
@@ -411,7 +404,6 @@ class DogStatsDClient {
411
404
  * @param {number} family - The family of the address
412
405
  * @param {boolean} recordTelemetry - Whether to record the transport outcome
413
406
  * @param {() => void} [done] - Called after every packet completes
414
- * @returns {void}
415
407
  * @memberof DogStatsDClient
416
408
  */
417
409
  _sendUdpFromQueue (queue, address, family, recordTelemetry, done) {
@@ -457,7 +449,6 @@ class DogStatsDClient {
457
449
  * @param {string[]} tags - The metric tags
458
450
  * @param {string} [tagsPrefix] - Serialized global tags
459
451
  * @param {DogStatsDBufferState} [state] - Payload state receiving the metric
460
- * @returns {void}
461
452
  * @memberof DogStatsDClient
462
453
  */
463
454
  _add (stat, value, type, tags, tagsPrefix = this.#tagsPrefix, state = this.#metrics) {
@@ -482,7 +473,6 @@ class DogStatsDClient {
482
473
  * @param {string} stat - Telemetry metric name
483
474
  * @param {number} value - Telemetry metric value
484
475
  * @param {string} [typeLabel] - Submitted or aggregated metric type
485
- * @returns {void}
486
476
  */
487
477
  #addTelemetry (stat, value, typeLabel) {
488
478
  const tags = typeLabel === undefined ? undefined : [`metrics_type:${typeLabel}`]
@@ -496,7 +486,6 @@ class DogStatsDClient {
496
486
  *
497
487
  * @param {string} message - The message to write
498
488
  * @param {DogStatsDBufferState} [state] - Payload state receiving the message
499
- * @returns {void}
500
489
  * @memberof DogStatsDClient
501
490
  */
502
491
  _write (message, state = this.#metrics) {
@@ -605,7 +594,6 @@ class MetricsAggregationClient {
605
594
  /**
606
595
  * @param {boolean|(() => void)} [forceTelemetry] - Whether to ignore the telemetry interval, or completion callback
607
596
  * @param {() => void} [done] - Called after serverless deliveries complete
608
- * @returns {void}
609
597
  */
610
598
  flush (forceTelemetry = false, done) {
611
599
  if (typeof forceTelemetry === 'function') {
@@ -680,9 +668,6 @@ class MetricsAggregationClient {
680
668
  this.count(name, -count, tags)
681
669
  }
682
670
 
683
- /**
684
- * @returns {number} Number of gauge contexts flushed
685
- */
686
671
  _captureGauges () {
687
672
  let metrics = 0
688
673
  const contexts = this._captureTree(this._gauges, (node, name, tags) => {
@@ -696,9 +681,6 @@ class MetricsAggregationClient {
696
681
  return contexts
697
682
  }
698
683
 
699
- /**
700
- * @returns {number} Number of counter contexts flushed
701
- */
702
684
  _captureCounters () {
703
685
  let metrics = 0
704
686
  const contexts = this._captureTree(this._counters, (node, name, tags) => {
@@ -712,9 +694,6 @@ class MetricsAggregationClient {
712
694
  return contexts
713
695
  }
714
696
 
715
- /**
716
- * @returns {number} Number of histogram contexts flushed
717
- */
718
697
  _captureHistograms () {
719
698
  let metrics = 0
720
699
  const contexts = this._captureTree(this._histograms, (node, name, tags) => {
@@ -740,7 +719,6 @@ class MetricsAggregationClient {
740
719
  /**
741
720
  * @param {Map<string, MetricNode>} tree - Metric context tree
742
721
  * @param {CaptureMetric} fn - Called for every context with submissions
743
- * @returns {number} Number of contexts with submissions
744
722
  */
745
723
  _captureTree (tree, fn) {
746
724
  let contexts = 0
@@ -757,7 +735,6 @@ class MetricsAggregationClient {
757
735
  * @param {string} name - Metric name
758
736
  * @param {string[]} tags - Current metric tags
759
737
  * @param {CaptureMetric} fn - Called for every context with submissions
760
- * @returns {number} Number of contexts with submissions
761
738
  */
762
739
  _captureNode (node, name, tags, fn) {
763
740
  let contexts = 0
@@ -74,13 +74,11 @@ class CrossPayloadAgentEncoder extends AgentEncoder {
74
74
  return super.makePayload()
75
75
  }
76
76
 
77
- /** @returns {void} */
78
77
  reset () {
79
78
  this.#prepareReset()
80
79
  super.reset()
81
80
  }
82
81
 
83
- /** @returns {void} */
84
82
  #prepareReset () {
85
83
  const crossPayloadState = this.#crossPayloadState
86
84
  if (crossPayloadState !== undefined && !prepareCrossPayloadReset(crossPayloadState)) {
@@ -129,7 +127,6 @@ function markPayloadString (crossPayloadState, value) {
129
127
 
130
128
  /**
131
129
  * @param {ReturnType<typeof createCrossPayloadState>} crossPayloadState
132
- * @returns {boolean}
133
130
  */
134
131
  function prepareCrossPayloadReset (crossPayloadState) {
135
132
  const learning = crossPayloadState.learningPayloadCount < CROSS_PAYLOAD_LEARNING_PAYLOAD_LIMIT
@@ -136,7 +136,6 @@ function formatSpanWithLegacyEvents (span) {
136
136
  * replacer hooks).
137
137
  *
138
138
  * @param {Array<{ name: unknown, startTime: number, attributes?: object }>} spanEvents
139
- * @returns {string}
140
139
  */
141
140
  function stringifySpanEvents (spanEvents) {
142
141
  let result = '['
@@ -200,7 +199,6 @@ function stringifyAttributeValue (value) {
200
199
  * conversion (which is what `JSON.stringify` calls internally).
201
200
  *
202
201
  * @param {number} value
203
- * @returns {string}
204
202
  */
205
203
  function jsonNumber (value) {
206
204
  if (Number.isFinite(value)) return String(value)
@@ -215,7 +213,6 @@ function jsonNumber (value) {
215
213
  * lone surrogates, etc.).
216
214
  *
217
215
  * @param {string} value
218
- * @returns {string}
219
216
  */
220
217
  function escapeJsonString (value) {
221
218
  for (let index = 0; index < value.length; index++) {
@@ -649,7 +646,6 @@ class AgentEncoder {
649
646
  * @param {number} offset
650
647
  * @param {Buffer} keyPrefix Precomputed `[key, 0xCF]`.
651
648
  * @param {{ toBuffer: () => Uint8Array | number[] }} identifier
652
- * @returns {number}
653
649
  */
654
650
  #writeIdAt (target, offset, keyPrefix, identifier) {
655
651
  target.set(keyPrefix, offset)
@@ -871,7 +867,6 @@ class AgentEncoder {
871
867
  * @param {MsgpackChunk} bytes
872
868
  * @param {string} key
873
869
  * @param {unknown} value
874
- * @returns {boolean}
875
870
  */
876
871
  #emitAttribute (bytes, key, value) {
877
872
  if (typeof value === 'string') {
@@ -911,7 +906,6 @@ class AgentEncoder {
911
906
  * @param {MsgpackChunk} bytes
912
907
  * @param {string} key
913
908
  * @param {Array<unknown>} array
914
- * @returns {boolean}
915
909
  */
916
910
  #emitArrayAttribute (bytes, key, array) {
917
911
  const sectionStart = bytes.length
@@ -946,7 +940,6 @@ class AgentEncoder {
946
940
  * @param {MsgpackChunk} bytes
947
941
  * @param {string} key
948
942
  * @param {unknown} value
949
- * @returns {boolean}
950
943
  */
951
944
  #emitArrayItem (bytes, key, value) {
952
945
  if (typeof value === 'string') {
@@ -173,7 +173,6 @@ class AgentEncoder extends BaseEncoder {
173
173
  * @param {Uint8Array} target
174
174
  * @param {number} offset
175
175
  * @param {number} index
176
- * @returns {number}
177
176
  */
178
177
  #writeIndexAt (target, offset, index) {
179
178
  target[offset] = 0xCE
@@ -192,7 +191,6 @@ class AgentEncoder extends BaseEncoder {
192
191
  * @param {Uint8Array} target
193
192
  * @param {number} offset
194
193
  * @param {{ toBuffer: () => Uint8Array | number[] }} identifier
195
- * @returns {number}
196
194
  */
197
195
  #writeIdAt (target, offset, identifier) {
198
196
  target[offset] = 0xCF
@@ -53,7 +53,6 @@ function truncateSpanTestOpt (span) {
53
53
  * the formatter no longer reshapes events, it hands the raw array through.
54
54
  *
55
55
  * @param {{ startTime: number }} event
56
- * @returns {number}
57
56
  */
58
57
  function eventTimeNano (event) {
59
58
  return Math.round(event.startTime * 1e6)
@@ -2,8 +2,7 @@
2
2
 
3
3
  const { fetchAgentInfo } = require('../agent/info')
4
4
  const log = require('../log')
5
-
6
- const TRAILING_SLASHES = /\/+$/
5
+ const { stripTrailingSlashes } = require('./path')
7
6
 
8
7
  /**
9
8
  * Receiver discovery contract
@@ -81,14 +80,14 @@ function selectEVPProxyPath (agentInfo, { supportedPaths, requiredHeaders = [] }
81
80
  const advertisedPaths = new Set()
82
81
  for (const endpoint of agentInfo.endpoints) {
83
82
  if (typeof endpoint === 'string') {
84
- advertisedPaths.add(endpoint.replace(TRAILING_SLASHES, ''))
83
+ advertisedPaths.add(stripTrailingSlashes(endpoint))
85
84
  }
86
85
  }
87
86
 
88
87
  for (const supportedPath of supportedPaths) {
89
88
  if (typeof supportedPath !== 'string') continue
90
89
 
91
- const normalizedPath = supportedPath.replace(TRAILING_SLASHES, '')
90
+ const normalizedPath = stripTrailingSlashes(supportedPath)
92
91
  if (advertisedPaths.has(normalizedPath)) {
93
92
  return normalizedPath
94
93
  }
@@ -107,7 +106,6 @@ function selectEVPProxyPath (agentInfo, { supportedPaths, requiredHeaders = [] }
107
106
  * @param {string[]} [options.requiredHeaders] - Headers that the proxy must forward unchanged to intake. Each
108
107
  * header must appear in `evp_proxy_allowed_headers`. Do not include routing headers that the Agent consumes.
109
108
  * @param {(error: Error|null, route?: {url: URL, basePath: string}) => void} callback - Result callback
110
- * @returns {void}
111
109
  */
112
110
  function discoverEVPProxy (url, options, callback) {
113
111
  fetchAgentInfo(url, (error, agentInfo) => {