dd-trace 5.81.0 → 5.83.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 (371) hide show
  1. package/LICENSE-3rdparty.csv +78 -79
  2. package/ci/init.js +6 -6
  3. package/index.d.ts +159 -3
  4. package/loader-hook.mjs +8 -3
  5. package/package.json +64 -66
  6. package/packages/datadog-core/src/storage.js +7 -7
  7. package/packages/datadog-core/src/utils/src/parse-tags.js +1 -1
  8. package/packages/datadog-esbuild/index.js +14 -7
  9. package/packages/datadog-esbuild/src/utils.js +14 -2
  10. package/packages/datadog-instrumentations/src/aerospike.js +3 -2
  11. package/packages/datadog-instrumentations/src/ai.js +9 -5
  12. package/packages/datadog-instrumentations/src/amqp10.js +1 -1
  13. package/packages/datadog-instrumentations/src/amqplib.js +4 -4
  14. package/packages/datadog-instrumentations/src/anthropic.js +2 -2
  15. package/packages/datadog-instrumentations/src/apollo-server-core.js +2 -2
  16. package/packages/datadog-instrumentations/src/apollo-server.js +1 -1
  17. package/packages/datadog-instrumentations/src/apollo.js +3 -2
  18. package/packages/datadog-instrumentations/src/avsc.js +1 -1
  19. package/packages/datadog-instrumentations/src/aws-sdk.js +1 -1
  20. package/packages/datadog-instrumentations/src/azure-event-hubs.js +4 -3
  21. package/packages/datadog-instrumentations/src/azure-functions.js +2 -2
  22. package/packages/datadog-instrumentations/src/azure-service-bus.js +3 -4
  23. package/packages/datadog-instrumentations/src/bluebird.js +1 -1
  24. package/packages/datadog-instrumentations/src/bullmq.js +11 -0
  25. package/packages/datadog-instrumentations/src/bunyan.js +1 -1
  26. package/packages/datadog-instrumentations/src/cassandra-driver.js +1 -1
  27. package/packages/datadog-instrumentations/src/child_process.js +3 -3
  28. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +3 -3
  29. package/packages/datadog-instrumentations/src/couchbase.js +1 -1
  30. package/packages/datadog-instrumentations/src/crypto.js +1 -1
  31. package/packages/datadog-instrumentations/src/cucumber.js +13 -14
  32. package/packages/datadog-instrumentations/src/cypress.js +1 -1
  33. package/packages/datadog-instrumentations/src/dns.js +1 -1
  34. package/packages/datadog-instrumentations/src/elasticsearch.js +1 -1
  35. package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +1 -1
  36. package/packages/datadog-instrumentations/src/express.js +1 -1
  37. package/packages/datadog-instrumentations/src/fs.js +1 -1
  38. package/packages/datadog-instrumentations/src/generic-pool.js +1 -1
  39. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +137 -15
  40. package/packages/datadog-instrumentations/src/google-cloud-vertexai.js +2 -3
  41. package/packages/datadog-instrumentations/src/google-genai.js +3 -3
  42. package/packages/datadog-instrumentations/src/graphql.js +2 -2
  43. package/packages/datadog-instrumentations/src/grpc/client.js +1 -1
  44. package/packages/datadog-instrumentations/src/grpc/server.js +1 -1
  45. package/packages/datadog-instrumentations/src/helpers/bundler-register.js +1 -1
  46. package/packages/datadog-instrumentations/src/helpers/hook.js +1 -1
  47. package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -1
  48. package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -1
  49. package/packages/datadog-instrumentations/src/helpers/instrumentations.js +4 -3
  50. package/packages/datadog-instrumentations/src/helpers/register.js +9 -11
  51. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -2
  52. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/bullmq.json +106 -0
  53. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +2 -1
  54. package/packages/datadog-instrumentations/src/helpers/router-helper.js +1 -1
  55. package/packages/datadog-instrumentations/src/helpers/shared-utils.js +9 -0
  56. package/packages/datadog-instrumentations/src/hono.js +55 -10
  57. package/packages/datadog-instrumentations/src/http/client.js +2 -2
  58. package/packages/datadog-instrumentations/src/ioredis.js +1 -1
  59. package/packages/datadog-instrumentations/src/iovalkey.js +1 -1
  60. package/packages/datadog-instrumentations/src/jest.js +37 -16
  61. package/packages/datadog-instrumentations/src/kafkajs.js +3 -3
  62. package/packages/datadog-instrumentations/src/knex.js +1 -1
  63. package/packages/datadog-instrumentations/src/koa.js +2 -1
  64. package/packages/datadog-instrumentations/src/ldapjs.js +1 -1
  65. package/packages/datadog-instrumentations/src/light-my-request.js +93 -0
  66. package/packages/datadog-instrumentations/src/limitd-client.js +1 -1
  67. package/packages/datadog-instrumentations/src/lodash.js +1 -2
  68. package/packages/datadog-instrumentations/src/mariadb.js +1 -2
  69. package/packages/datadog-instrumentations/src/memcached.js +1 -1
  70. package/packages/datadog-instrumentations/src/mocha/main.js +2 -2
  71. package/packages/datadog-instrumentations/src/mocha/worker.js +1 -1
  72. package/packages/datadog-instrumentations/src/mocha.js +1 -1
  73. package/packages/datadog-instrumentations/src/mongodb-core.js +1 -1
  74. package/packages/datadog-instrumentations/src/mongodb.js +1 -1
  75. package/packages/datadog-instrumentations/src/mongoose.js +1 -1
  76. package/packages/datadog-instrumentations/src/mquery.js +1 -1
  77. package/packages/datadog-instrumentations/src/mysql.js +2 -2
  78. package/packages/datadog-instrumentations/src/mysql2.js +3 -3
  79. package/packages/datadog-instrumentations/src/net.js +14 -6
  80. package/packages/datadog-instrumentations/src/next.js +1 -1
  81. package/packages/datadog-instrumentations/src/nyc.js +2 -2
  82. package/packages/datadog-instrumentations/src/openai.js +2 -2
  83. package/packages/datadog-instrumentations/src/opensearch.js +1 -1
  84. package/packages/datadog-instrumentations/src/oracledb.js +1 -1
  85. package/packages/datadog-instrumentations/src/otel-sdk-trace.js +5 -5
  86. package/packages/datadog-instrumentations/src/pg.js +7 -5
  87. package/packages/datadog-instrumentations/src/pino.js +1 -1
  88. package/packages/datadog-instrumentations/src/playwright.js +4 -4
  89. package/packages/datadog-instrumentations/src/prisma.js +52 -37
  90. package/packages/datadog-instrumentations/src/process.js +1 -1
  91. package/packages/datadog-instrumentations/src/promise-js.js +1 -1
  92. package/packages/datadog-instrumentations/src/promise.js +1 -1
  93. package/packages/datadog-instrumentations/src/protobufjs.js +1 -1
  94. package/packages/datadog-instrumentations/src/q.js +1 -1
  95. package/packages/datadog-instrumentations/src/redis.js +1 -1
  96. package/packages/datadog-instrumentations/src/rhea.js +1 -1
  97. package/packages/datadog-instrumentations/src/selenium.js +3 -3
  98. package/packages/datadog-instrumentations/src/sequelize.js +1 -2
  99. package/packages/datadog-instrumentations/src/sharedb.js +1 -1
  100. package/packages/datadog-instrumentations/src/tedious.js +1 -1
  101. package/packages/datadog-instrumentations/src/undici.js +15 -4
  102. package/packages/datadog-instrumentations/src/url.js +1 -1
  103. package/packages/datadog-instrumentations/src/vitest.js +1 -1
  104. package/packages/datadog-instrumentations/src/vm.js +1 -1
  105. package/packages/datadog-instrumentations/src/when.js +1 -1
  106. package/packages/datadog-instrumentations/src/winston.js +1 -1
  107. package/packages/datadog-instrumentations/src/ws.js +3 -2
  108. package/packages/datadog-plugin-amqp10/src/index.js +1 -1
  109. package/packages/datadog-plugin-amqplib/src/index.js +1 -1
  110. package/packages/datadog-plugin-anthropic/src/index.js +1 -1
  111. package/packages/datadog-plugin-aws-sdk/src/base.js +4 -4
  112. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/index.js +1 -1
  113. package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +4 -4
  114. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -2
  115. package/packages/datadog-plugin-aws-sdk/src/util.js +3 -3
  116. package/packages/datadog-plugin-azure-event-hubs/src/index.js +1 -1
  117. package/packages/datadog-plugin-azure-event-hubs/src/producer.js +21 -7
  118. package/packages/datadog-plugin-azure-service-bus/src/index.js +1 -1
  119. package/packages/datadog-plugin-azure-service-bus/src/producer.js +6 -2
  120. package/packages/datadog-plugin-bullmq/src/consumer.js +60 -0
  121. package/packages/datadog-plugin-bullmq/src/index.js +18 -0
  122. package/packages/datadog-plugin-bullmq/src/producer.js +178 -0
  123. package/packages/datadog-plugin-confluentinc-kafka-javascript/src/index.js +1 -1
  124. package/packages/datadog-plugin-cucumber/src/index.js +2 -2
  125. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +2 -2
  126. package/packages/datadog-plugin-cypress/src/plugin.js +1 -1
  127. package/packages/datadog-plugin-dd-trace-api/src/index.js +2 -2
  128. package/packages/datadog-plugin-express/src/code_origin.js +21 -15
  129. package/packages/datadog-plugin-express/src/index.js +1 -1
  130. package/packages/datadog-plugin-fastify/src/code_origin.js +17 -4
  131. package/packages/datadog-plugin-fastify/src/index.js +1 -1
  132. package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +13 -3
  133. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +171 -12
  134. package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +1 -2
  135. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +160 -13
  136. package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +217 -0
  137. package/packages/datadog-plugin-google-cloud-vertexai/src/index.js +1 -1
  138. package/packages/datadog-plugin-google-genai/src/index.js +1 -1
  139. package/packages/datadog-plugin-graphql/src/resolve.js +1 -1
  140. package/packages/datadog-plugin-grpc/src/index.js +1 -1
  141. package/packages/datadog-plugin-http/src/client.js +2 -1
  142. package/packages/datadog-plugin-http/src/index.js +25 -5
  143. package/packages/datadog-plugin-http2/src/client.js +2 -2
  144. package/packages/datadog-plugin-http2/src/index.js +1 -1
  145. package/packages/datadog-plugin-jest/src/index.js +2 -2
  146. package/packages/datadog-plugin-kafkajs/src/index.js +1 -1
  147. package/packages/datadog-plugin-langchain/src/index.js +1 -1
  148. package/packages/datadog-plugin-mocha/src/index.js +2 -2
  149. package/packages/datadog-plugin-moleculer/src/index.js +1 -1
  150. package/packages/datadog-plugin-mongodb-core/src/index.js +8 -4
  151. package/packages/datadog-plugin-openai/src/index.js +1 -1
  152. package/packages/datadog-plugin-openai/src/stream-helpers.js +30 -10
  153. package/packages/datadog-plugin-openai/src/tracing.js +2 -2
  154. package/packages/datadog-plugin-playwright/src/index.js +3 -3
  155. package/packages/datadog-plugin-rhea/src/index.js +1 -1
  156. package/packages/datadog-plugin-undici/src/index.js +305 -2
  157. package/packages/datadog-plugin-vitest/src/index.js +5 -5
  158. package/packages/datadog-plugin-ws/src/close.js +56 -3
  159. package/packages/datadog-plugin-ws/src/index.js +4 -0
  160. package/packages/datadog-plugin-ws/src/producer.js +39 -4
  161. package/packages/datadog-plugin-ws/src/receiver.js +39 -3
  162. package/packages/datadog-plugin-ws/src/server.js +13 -1
  163. package/packages/datadog-plugin-ws/src/util.js +107 -0
  164. package/packages/datadog-shimmer/src/shimmer.js +2 -2
  165. package/packages/dd-trace/index.js +19 -0
  166. package/packages/dd-trace/src/aiguard/sdk.js +3 -3
  167. package/packages/dd-trace/src/appsec/graphql.js +2 -2
  168. package/packages/dd-trace/src/appsec/iast/analyzers/code-injection-analyzer.js +1 -1
  169. package/packages/dd-trace/src/appsec/iast/analyzers/command-injection-analyzer.js +1 -1
  170. package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +1 -1
  171. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-base-analyzer.js +1 -1
  172. package/packages/dd-trace/src/appsec/iast/analyzers/injection-analyzer.js +1 -1
  173. package/packages/dd-trace/src/appsec/iast/analyzers/ldap-injection-analyzer.js +1 -1
  174. package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +3 -3
  175. package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +1 -1
  176. package/packages/dd-trace/src/appsec/iast/analyzers/ssrf-analyzer.js +1 -1
  177. package/packages/dd-trace/src/appsec/iast/analyzers/untrusted-deserialization-analyzer.js +1 -1
  178. package/packages/dd-trace/src/appsec/iast/analyzers/unvalidated-redirect-analyzer.js +1 -1
  179. package/packages/dd-trace/src/appsec/iast/analyzers/weak-cipher-analyzer.js +1 -1
  180. package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +3 -2
  181. package/packages/dd-trace/src/appsec/iast/analyzers/weak-randomness-analyzer.js +1 -1
  182. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +3 -3
  183. package/packages/dd-trace/src/appsec/iast/index.js +5 -5
  184. package/packages/dd-trace/src/appsec/iast/security-controls/index.js +1 -1
  185. package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +1 -2
  186. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +1 -1
  187. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -1
  188. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +11 -15
  189. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +1 -1
  190. package/packages/dd-trace/src/appsec/iast/telemetry/namespaces.js +1 -1
  191. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +3 -3
  192. package/packages/dd-trace/src/appsec/index.js +8 -8
  193. package/packages/dd-trace/src/appsec/rasp/command_injection.js +1 -1
  194. package/packages/dd-trace/src/appsec/rasp/index.js +3 -5
  195. package/packages/dd-trace/src/appsec/rasp/lfi.js +1 -1
  196. package/packages/dd-trace/src/appsec/rc-products.js +10 -0
  197. package/packages/dd-trace/src/appsec/recommended.json +230 -3
  198. package/packages/dd-trace/src/appsec/remote_config.js +177 -0
  199. package/packages/dd-trace/src/appsec/reporter.js +3 -3
  200. package/packages/dd-trace/src/appsec/rule_manager.js +37 -20
  201. package/packages/dd-trace/src/appsec/sdk/index.js +1 -1
  202. package/packages/dd-trace/src/appsec/sdk/set_user.js +1 -1
  203. package/packages/dd-trace/src/appsec/sdk/track_event.js +2 -2
  204. package/packages/dd-trace/src/appsec/sdk/user_blocking.js +2 -2
  205. package/packages/dd-trace/src/appsec/user_tracking.js +2 -2
  206. package/packages/dd-trace/src/appsec/waf/index.js +17 -3
  207. package/packages/dd-trace/src/appsec/waf/waf_manager.js +11 -0
  208. package/packages/dd-trace/src/azure_metadata.js +15 -4
  209. package/packages/dd-trace/src/baggage.js +36 -11
  210. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +5 -1
  211. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +6 -0
  212. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -2
  213. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -2
  214. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +2 -2
  215. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +2 -2
  216. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
  217. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -3
  218. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +3 -3
  219. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +5 -5
  220. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +1 -1
  221. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -2
  222. package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +4 -4
  223. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -4
  224. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +2 -2
  225. package/packages/dd-trace/src/{config_defaults.js → config/defaults.js} +5 -4
  226. package/packages/dd-trace/src/{config-helper.js → config/helper.js} +88 -15
  227. package/packages/dd-trace/src/{config.js → config/index.js} +115 -67
  228. package/packages/dd-trace/src/config/remote_config.js +202 -0
  229. package/packages/dd-trace/src/{config_stable.js → config/stable.js} +20 -32
  230. package/packages/dd-trace/src/{supported-configurations.json → config/supported-configurations.json} +5 -0
  231. package/packages/dd-trace/src/constants.js +5 -0
  232. package/packages/dd-trace/src/crashtracking/crashtracker.js +11 -2
  233. package/packages/dd-trace/src/datastreams/checkpointer.js +2 -2
  234. package/packages/dd-trace/src/datastreams/index.js +1 -1
  235. package/packages/dd-trace/src/datastreams/pathway.js +7 -7
  236. package/packages/dd-trace/src/datastreams/processor.js +3 -3
  237. package/packages/dd-trace/src/datastreams/writer.js +3 -3
  238. package/packages/dd-trace/src/debugger/config.js +1 -0
  239. package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
  240. package/packages/dd-trace/src/debugger/devtools_client/config.js +1 -1
  241. package/packages/dd-trace/src/debugger/devtools_client/index.js +7 -2
  242. package/packages/dd-trace/src/debugger/devtools_client/send.js +6 -6
  243. package/packages/dd-trace/src/debugger/devtools_client/session.js +1 -1
  244. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +5 -5
  245. package/packages/dd-trace/src/debugger/devtools_client/snapshot/constants.js +1 -1
  246. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +2 -2
  247. package/packages/dd-trace/src/debugger/devtools_client/state.js +1 -1
  248. package/packages/dd-trace/src/debugger/devtools_client/status.js +2 -2
  249. package/packages/dd-trace/src/debugger/index.js +84 -16
  250. package/packages/dd-trace/src/dogstatsd.js +5 -4
  251. package/packages/dd-trace/src/encode/0.4.js +3 -3
  252. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +2 -2
  253. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +1 -1
  254. package/packages/dd-trace/src/encode/span-stats.js +6 -1
  255. package/packages/dd-trace/src/exporter.js +2 -2
  256. package/packages/dd-trace/src/exporters/agent/index.js +2 -4
  257. package/packages/dd-trace/src/exporters/agent/writer.js +9 -14
  258. package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +2 -2
  259. package/packages/dd-trace/src/exporters/common/docker.js +2 -2
  260. package/packages/dd-trace/src/exporters/common/request.js +3 -3
  261. package/packages/dd-trace/src/exporters/common/util.js +2 -2
  262. package/packages/dd-trace/src/exporters/common/writer.js +1 -1
  263. package/packages/dd-trace/src/exporters/span-stats/index.js +1 -1
  264. package/packages/dd-trace/src/external-logger/src/index.js +1 -2
  265. package/packages/dd-trace/src/flare/index.js +2 -2
  266. package/packages/dd-trace/src/guardrails/index.js +6 -3
  267. package/packages/dd-trace/src/guardrails/telemetry.js +1 -1
  268. package/packages/dd-trace/src/id.js +1 -1
  269. package/packages/dd-trace/src/index.js +4 -4
  270. package/packages/dd-trace/src/lambda/handler.js +5 -5
  271. package/packages/dd-trace/src/lambda/index.js +2 -2
  272. package/packages/dd-trace/src/lambda/runtime/patch.js +6 -6
  273. package/packages/dd-trace/src/lambda/runtime/ritm.js +3 -3
  274. package/packages/dd-trace/src/llmobs/constants/tags.js +14 -1
  275. package/packages/dd-trace/src/llmobs/index.js +10 -11
  276. package/packages/dd-trace/src/llmobs/noop.js +2 -0
  277. package/packages/dd-trace/src/llmobs/plugins/ai/index.js +38 -7
  278. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +30 -9
  279. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +3 -3
  280. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +2 -2
  281. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +1 -1
  282. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +1 -1
  283. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/embedding.js +1 -1
  284. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/llm.js +1 -1
  285. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/vectorstore.js +1 -1
  286. package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +16 -0
  287. package/packages/dd-trace/src/llmobs/plugins/openai/index.js +19 -5
  288. package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +22 -10
  289. package/packages/dd-trace/src/llmobs/plugins/vertexai.js +1 -1
  290. package/packages/dd-trace/src/llmobs/sdk.js +46 -26
  291. package/packages/dd-trace/src/llmobs/span_processor.js +26 -20
  292. package/packages/dd-trace/src/llmobs/tagger.js +175 -1
  293. package/packages/dd-trace/src/llmobs/telemetry.js +3 -4
  294. package/packages/dd-trace/src/llmobs/writers/base.js +117 -38
  295. package/packages/dd-trace/src/llmobs/writers/spans.js +5 -5
  296. package/packages/dd-trace/src/log/index.js +5 -5
  297. package/packages/dd-trace/src/noop/proxy.js +5 -5
  298. package/packages/dd-trace/src/noop/span.js +1 -1
  299. package/packages/dd-trace/src/openfeature/index.js +2 -2
  300. package/packages/dd-trace/src/openfeature/noop.js +14 -14
  301. package/packages/dd-trace/src/openfeature/remote_config.js +31 -0
  302. package/packages/dd-trace/src/openfeature/writers/base.js +12 -13
  303. package/packages/dd-trace/src/openfeature/writers/exposures.js +9 -9
  304. package/packages/dd-trace/src/opentelemetry/context_manager.js +2 -2
  305. package/packages/dd-trace/src/opentelemetry/logs/logger.js +1 -1
  306. package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +4 -4
  307. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +9 -8
  308. package/packages/dd-trace/src/opentelemetry/metrics/instruments.js +3 -3
  309. package/packages/dd-trace/src/opentelemetry/metrics/meter.js +2 -2
  310. package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +4 -4
  311. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +36 -11
  312. package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +2 -2
  313. package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +11 -10
  314. package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +1 -1
  315. package/packages/dd-trace/src/opentelemetry/span.js +2 -2
  316. package/packages/dd-trace/src/opentelemetry/tracer.js +51 -9
  317. package/packages/dd-trace/src/opentracing/propagation/text_map.js +68 -28
  318. package/packages/dd-trace/src/opentracing/span.js +7 -7
  319. package/packages/dd-trace/src/opentracing/tracer.js +5 -5
  320. package/packages/dd-trace/src/payload-tagging/index.js +6 -2
  321. package/packages/dd-trace/src/plugin_manager.js +8 -6
  322. package/packages/dd-trace/src/plugins/apollo.js +1 -1
  323. package/packages/dd-trace/src/plugins/ci_plugin.js +27 -27
  324. package/packages/dd-trace/src/plugins/database.js +1 -1
  325. package/packages/dd-trace/src/plugins/index.js +5 -1
  326. package/packages/dd-trace/src/plugins/log_plugin.js +1 -1
  327. package/packages/dd-trace/src/plugins/outbound.js +1 -1
  328. package/packages/dd-trace/src/plugins/tracing.js +1 -1
  329. package/packages/dd-trace/src/plugins/util/ci.js +5 -8
  330. package/packages/dd-trace/src/plugins/util/git-cache.js +3 -3
  331. package/packages/dd-trace/src/plugins/util/git.js +8 -8
  332. package/packages/dd-trace/src/plugins/util/stacktrace.js +1 -1
  333. package/packages/dd-trace/src/plugins/util/test.js +25 -25
  334. package/packages/dd-trace/src/plugins/util/user-provided-git.js +41 -43
  335. package/packages/dd-trace/src/plugins/util/web.js +8 -5
  336. package/packages/dd-trace/src/priority_sampler.js +15 -16
  337. package/packages/dd-trace/src/process-tags/index.js +31 -29
  338. package/packages/dd-trace/src/profiler.js +4 -39
  339. package/packages/dd-trace/src/profiling/config.js +104 -50
  340. package/packages/dd-trace/src/profiling/exporter_cli.js +8 -8
  341. package/packages/dd-trace/src/profiling/exporters/agent.js +6 -6
  342. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +9 -2
  343. package/packages/dd-trace/src/profiling/index.js +1 -1
  344. package/packages/dd-trace/src/profiling/libuv-size.js +1 -1
  345. package/packages/dd-trace/src/profiling/profiler.js +61 -7
  346. package/packages/dd-trace/src/profiling/profilers/event_plugins/event.js +1 -1
  347. package/packages/dd-trace/src/profiling/profilers/events.js +2 -2
  348. package/packages/dd-trace/src/profiling/profilers/wall.js +4 -4
  349. package/packages/dd-trace/src/proxy.js +43 -20
  350. package/packages/dd-trace/src/remote_config/capabilities.js +3 -0
  351. package/packages/dd-trace/src/remote_config/index.js +541 -137
  352. package/packages/dd-trace/src/require-package-json.js +1 -1
  353. package/packages/dd-trace/src/ritm.js +58 -31
  354. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +3 -3
  355. package/packages/dd-trace/src/serverless.js +17 -1
  356. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +8 -0
  357. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +8 -0
  358. package/packages/dd-trace/src/span_format.js +1 -1
  359. package/packages/dd-trace/src/span_processor.js +4 -4
  360. package/packages/dd-trace/src/span_stats.js +6 -4
  361. package/packages/dd-trace/src/standalone/index.js +1 -1
  362. package/packages/dd-trace/src/startup-log.js +7 -16
  363. package/packages/dd-trace/src/telemetry/dependencies.js +3 -3
  364. package/packages/dd-trace/src/telemetry/endpoints.js +75 -13
  365. package/packages/dd-trace/src/telemetry/logs/index.js +1 -1
  366. package/packages/dd-trace/src/telemetry/send-data.js +103 -4
  367. package/packages/dd-trace/src/telemetry/telemetry.js +238 -114
  368. package/packages/dd-trace/src/tracer.js +3 -3
  369. package/packages/dd-trace/src/tracer_metadata.js +19 -15
  370. package/packages/dd-trace/src/remote_config/manager.js +0 -368
  371. /package/packages/dd-trace/src/{git_properties.js → config/git_properties.js} +0 -0
@@ -1,10 +1,313 @@
1
1
  'use strict'
2
2
 
3
- const FetchPlugin = require('../../datadog-plugin-fetch/src/index.js')
3
+ const HttpClientPlugin = require('../../datadog-plugin-http/src/client')
4
+ const { storage } = require('../../datadog-core')
5
+ const tags = require('../../../ext/tags')
6
+ const formats = require('../../../ext/formats')
7
+ const HTTP_HEADERS = formats.HTTP_HEADERS
8
+ const log = require('../../dd-trace/src/log')
9
+ const { CLIENT_PORT_KEY } = require('../../dd-trace/src/constants')
4
10
 
5
- class UndiciPlugin extends FetchPlugin {
11
+ const {
12
+ HTTP_STATUS_CODE,
13
+ HTTP_REQUEST_HEADERS,
14
+ HTTP_RESPONSE_HEADERS,
15
+ } = tags
16
+
17
+ // WeakMap to store span context for native undici request objects
18
+ const requestContexts = new WeakMap()
19
+
20
+ class UndiciPlugin extends HttpClientPlugin {
6
21
  static id = 'undici'
7
22
  static prefix = 'tracing:apm:undici:fetch'
23
+
24
+ constructor (...args) {
25
+ super(...args)
26
+
27
+ // Subscribe to native undici diagnostic channels for undici >= 4.7.0
28
+ // These channels fire for ALL undici requests (fetch, request, stream, etc.)
29
+ this.addSub('undici:request:create', this.#onNativeRequestCreate.bind(this))
30
+ this.addSub('undici:request:headers', this.#onNativeRequestHeaders.bind(this))
31
+ this.addSub('undici:request:trailers', this.#onNativeRequestTrailers.bind(this))
32
+ this.addSub('undici:request:error', this.#onNativeRequestError.bind(this))
33
+ }
34
+
35
+ // ===========================================
36
+ // Native undici diagnostic channel handlers
37
+ // These fire for undici >= 4.7.0 for ALL request types (fetch, request, stream, etc.)
38
+ // ===========================================
39
+
40
+ #onNativeRequestCreate ({ request }) {
41
+ if (!request) return
42
+
43
+ const store = storage('legacy').getStore()
44
+ const { origin = '', path = '/' } = request
45
+ const method = request.method?.toUpperCase() ?? 'GET'
46
+
47
+ // Parse origin to extract protocol, hostname, port
48
+ let protocol = 'http:'
49
+ let hostname = 'localhost'
50
+ let port = ''
51
+
52
+ try {
53
+ const url = new URL(origin)
54
+ protocol = url.protocol
55
+ hostname = url.hostname
56
+ port = url.port
57
+ } catch {
58
+ // If origin is not a valid URL, use defaults
59
+ }
60
+
61
+ const host = port ? `${hostname}:${port}` : hostname
62
+ const pathname = path.split(/[?#]/)[0]
63
+ const uri = `${protocol}//${host}${pathname}`
64
+
65
+ const allowed = this.config.filter(uri)
66
+ const childOf = store && allowed ? store.span : null
67
+
68
+ const span = this.startSpan(this.operationName(), {
69
+ childOf,
70
+ meta: {
71
+ 'span.kind': 'client',
72
+ 'http.method': method,
73
+ 'http.url': uri,
74
+ 'out.host': hostname
75
+ },
76
+ metrics: {
77
+ [CLIENT_PORT_KEY]: port ? Number.parseInt(port, 10) : undefined
78
+ },
79
+ service: this.serviceName({ pluginConfig: this.config, sessionDetails: { host: hostname, port } }),
80
+ resource: method,
81
+ type: 'http'
82
+ }, false)
83
+
84
+ // Disable recording if not allowed
85
+ if (!allowed) {
86
+ span._spanContext._trace.record = false
87
+ }
88
+
89
+ // Capture request headers if configured
90
+ if (request.headers && this.config.headers) {
91
+ addConfiguredHeaders(span, request.headers, this.config.headers, HTTP_REQUEST_HEADERS)
92
+ }
93
+
94
+ // Inject trace headers if propagation is allowed
95
+ if (this.config.propagationFilter(uri)) {
96
+ const headers = {}
97
+ this.tracer.inject(span, HTTP_HEADERS, headers)
98
+
99
+ // Use addHeader if available (undici provides this on the request object)
100
+ if (typeof request.addHeader === 'function') {
101
+ for (const [name, value] of Object.entries(headers)) {
102
+ request.addHeader(name, value)
103
+ }
104
+ }
105
+ }
106
+
107
+ // Store span context for request for later retrieval
108
+ requestContexts.set(request, {
109
+ span,
110
+ store,
111
+ uri
112
+ })
113
+
114
+ // Enter the span context
115
+ storage('legacy').enterWith({ ...store, span })
116
+ }
117
+
118
+ #onNativeRequestHeaders ({ request, response }) {
119
+ const ctx = requestContexts.get(request)
120
+ if (!ctx) return
121
+
122
+ const { span } = ctx
123
+ const statusCode = response?.statusCode
124
+
125
+ if (statusCode) {
126
+ span.setTag(HTTP_STATUS_CODE, statusCode)
127
+
128
+ if (!this.config.validateStatus(statusCode)) {
129
+ span.setTag('error', 1)
130
+ }
131
+ }
132
+
133
+ // Add response headers if configured
134
+ if (response?.headers && this.config.headers) {
135
+ addConfiguredHeaders(span, response.headers, this.config.headers, HTTP_RESPONSE_HEADERS)
136
+ }
137
+ }
138
+
139
+ #onNativeRequestTrailers ({ request }) {
140
+ const ctx = requestContexts.get(request)
141
+ if (!ctx) return
142
+
143
+ const { span, store } = ctx
144
+
145
+ // Call the request hook if configured
146
+ this.config.hooks.request(span, null, null)
147
+
148
+ // Finish the span
149
+ span.finish()
150
+
151
+ // Clean up
152
+ requestContexts.delete(request)
153
+
154
+ // Restore parent store
155
+ if (store) {
156
+ storage('legacy').enterWith(store)
157
+ }
158
+ }
159
+
160
+ #onNativeRequestError ({ request, error }) {
161
+ const ctx = requestContexts.get(request)
162
+ if (!ctx) return
163
+
164
+ const { span, store } = ctx
165
+
166
+ // Don't record AbortError as an error - it's user-initiated cancellation
167
+ if (error && error.name !== 'AbortError') {
168
+ span.setTag('error', error)
169
+ }
170
+
171
+ // Call the request hook if configured
172
+ this.config.hooks.request(span, null, null)
173
+
174
+ // Finish the span
175
+ span.finish()
176
+
177
+ // Clean up
178
+ requestContexts.delete(request)
179
+
180
+ // Restore parent store
181
+ if (store) {
182
+ storage('legacy').enterWith(store)
183
+ }
184
+ }
185
+
186
+ // ===========================================
187
+ // Fetch-based tracing channel handlers
188
+ // These handle fetch() for undici < 4.7.0 (before native DC was added)
189
+ // ===========================================
190
+
191
+ bindStart (ctx) {
192
+ const req = ctx.req
193
+ const options = new URL(req.url)
194
+ options.headers = Object.fromEntries(req.headers.entries())
195
+ options.method = req.method
196
+
197
+ ctx.args = { options }
198
+
199
+ const store = super.bindStart(ctx)
200
+
201
+ // Inject trace headers back into the request
202
+ for (const name of Object.keys(options.headers)) {
203
+ if (!req.headers.has(name)) {
204
+ req.headers.set(name, options.headers[name])
205
+ }
206
+ }
207
+
208
+ return store
209
+ }
210
+
211
+ error (ctx) {
212
+ // Don't record AbortError as an error - it's user-initiated cancellation
213
+ if (!ctx.error || ctx.error.name !== 'AbortError') {
214
+ return super.error(ctx)
215
+ }
216
+ }
217
+
218
+ asyncEnd (ctx) {
219
+ ctx.res = ctx.result
220
+ return this.finish(ctx)
221
+ }
222
+
223
+ configure (config) {
224
+ return super.configure(normalizeConfig(config))
225
+ }
226
+ }
227
+
228
+ // Add configured headers to span with appropriate tags
229
+ function addConfiguredHeaders (span, rawHeaders, configuredHeaders, headerType) {
230
+ const headers = normalizeHeaders(rawHeaders)
231
+
232
+ for (const [key, tag] of configuredHeaders) {
233
+ const value = headers[key]
234
+ if (value) {
235
+ span.setTag(tag || `${headerType}.${key}`, value)
236
+ }
237
+ }
8
238
  }
9
239
 
240
+ // Normalize headers to an object, handling different undici formats:
241
+ // - Array format: alternating key-value pairs (undici >= 6.0.0)
242
+ // - String format: HTTP header lines like "key: value\r\n" (undici 5.x)
243
+ // - Object format: already a headers object
244
+ function normalizeHeaders (headers) {
245
+ if (!headers) return {}
246
+
247
+ // String format (undici 5.x): "key: value\r\nkey2: value2\r\n"
248
+ if (typeof headers === 'string') {
249
+ const result = {}
250
+ const lines = headers.split('\r\n')
251
+ for (const line of lines) {
252
+ if (!line) continue
253
+ const colonIndex = line.indexOf(':')
254
+ if (colonIndex > 0) {
255
+ const key = line.slice(0, colonIndex).toLowerCase().trim()
256
+ const value = line.slice(colonIndex + 1).trim()
257
+ result[key] = value
258
+ }
259
+ }
260
+ return result
261
+ }
262
+
263
+ // Array format (undici >= 6.0.0): alternating key-value pairs
264
+ if (Array.isArray(headers)) {
265
+ const result = {}
266
+ for (let i = 0; i < headers.length; i += 2) {
267
+ const key = headers[i]
268
+ if (typeof key === 'string') {
269
+ result[key.toLowerCase()] = headers[i + 1]
270
+ } else if (Buffer.isBuffer(key)) {
271
+ result[key.toString().toLowerCase()] = headers[i + 1]?.toString?.() || headers[i + 1]
272
+ }
273
+ }
274
+ return result
275
+ }
276
+
277
+ // Object format: use as-is
278
+ return headers
279
+ }
280
+
281
+ function normalizeConfig (config) {
282
+ const validateStatus = getStatusValidator(config)
283
+ const hooks = getHooks(config)
284
+
285
+ return {
286
+ ...config,
287
+ validateStatus,
288
+ hooks
289
+ }
290
+ }
291
+
292
+ function getStatusValidator (config) {
293
+ if (typeof config.validateStatus === 'function') {
294
+ return config.validateStatus
295
+ } else if (Object.hasOwn(config, 'validateStatus')) {
296
+ log.error('Expected `validateStatus` to be a function.')
297
+ }
298
+ return defaultValidateStatus
299
+ }
300
+
301
+ function defaultValidateStatus (code) {
302
+ return code < 400 || code >= 500
303
+ }
304
+
305
+ function getHooks (config) {
306
+ const request = config.hooks?.request ?? noop
307
+
308
+ return { request }
309
+ }
310
+
311
+ function noop () {}
312
+
10
313
  module.exports = UndiciPlugin
@@ -2,7 +2,7 @@
2
2
 
3
3
  const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
4
4
  const { storage } = require('../../datadog-core')
5
- const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
5
+ const { getValueFromEnvSources } = require('../../dd-trace/src/config/helper')
6
6
 
7
7
  const {
8
8
  TEST_STATUS,
@@ -281,11 +281,11 @@ class VitestPlugin extends CiPlugin {
281
281
  this.addBind('ci:vitest:test-suite:start', (ctx) => {
282
282
  const { testSuiteAbsolutePath, frameworkVersion } = ctx
283
283
 
284
- this.command = getEnvironmentVariable('DD_CIVISIBILITY_TEST_COMMAND')
284
+ this.command = getValueFromEnvSources('DD_CIVISIBILITY_TEST_COMMAND')
285
285
  this.frameworkVersion = frameworkVersion
286
286
  const testSessionSpanContext = this.tracer.extract('text_map', {
287
- 'x-datadog-trace-id': getEnvironmentVariable('DD_CIVISIBILITY_TEST_SESSION_ID'),
288
- 'x-datadog-parent-id': getEnvironmentVariable('DD_CIVISIBILITY_TEST_MODULE_ID')
287
+ 'x-datadog-trace-id': getValueFromEnvSources('DD_CIVISIBILITY_TEST_SESSION_ID'),
288
+ 'x-datadog-parent-id': getValueFromEnvSources('DD_CIVISIBILITY_TEST_MODULE_ID')
289
289
  })
290
290
 
291
291
  const trimmedCommand = DD_MAJOR < 6 ? this.command : 'vitest run'
@@ -405,7 +405,7 @@ class VitestPlugin extends CiPlugin {
405
405
  finishAllTraceSpans(this.testSessionSpan)
406
406
  this.telemetry.count(TELEMETRY_TEST_SESSION, {
407
407
  provider: this.ciProviderName,
408
- autoInjected: !!getEnvironmentVariable('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER')
408
+ autoInjected: !!getValueFromEnvSources('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER')
409
409
  })
410
410
  this.tracer._exporter.flush(onFinish)
411
411
  })
@@ -1,6 +1,16 @@
1
1
  'use strict'
2
2
 
3
3
  const TracingPlugin = require('../../dd-trace/src/plugins/tracing.js')
4
+ const {
5
+ WEBSOCKET_PTR_KIND,
6
+ SPAN_POINTER_DIRECTION,
7
+ SPAN_POINTER_DIRECTION_NAME
8
+ } = require('../../dd-trace/src/constants')
9
+ const {
10
+ incrementWebSocketCounter,
11
+ buildWebSocketSpanPointerHash,
12
+ hasDistributedTracingContext
13
+ } = require('./util')
4
14
 
5
15
  class WSClosePlugin extends TracingPlugin {
6
16
  static get id () { return 'ws' }
@@ -10,11 +20,9 @@ class WSClosePlugin extends TracingPlugin {
10
20
 
11
21
  bindStart (ctx) {
12
22
  const {
13
- traceWebsocketMessagesEnabled,
14
23
  traceWebsocketMessagesInheritSampling,
15
24
  traceWebsocketMessagesSeparateTraces
16
25
  } = this.config
17
- if (!traceWebsocketMessagesEnabled) return
18
26
 
19
27
  const { code, data, socket, isPeerClose } = ctx
20
28
  if (!socket?.spanContext) return
@@ -60,7 +68,52 @@ class WSClosePlugin extends TracingPlugin {
60
68
  end (ctx) {
61
69
  if (!Object.hasOwn(ctx, 'result') || !ctx.span) return
62
70
 
63
- if (ctx.socket.spanContext) ctx.span.addLink({ context: ctx.socket.spanContext })
71
+ if (ctx.socket.spanContext) {
72
+ const linkAttributes = {}
73
+
74
+ // Determine link kind based on whether this is peer close (incoming) or self close (outgoing)
75
+ const isIncoming = ctx.isPeerClose
76
+ linkAttributes['dd.kind'] = isIncoming ? 'executed_by' : 'resuming'
77
+
78
+ // Add span pointer for context propagation
79
+ if (this.config.traceWebsocketMessagesEnabled && ctx.socket.handshakeSpan) {
80
+ const handshakeSpan = ctx.socket.handshakeSpan
81
+
82
+ // Only add span pointers if distributed tracing is enabled and handshake has distributed context
83
+ if (hasDistributedTracingContext(handshakeSpan, ctx.socket)) {
84
+ const counterType = isIncoming ? 'receiveCounter' : 'sendCounter'
85
+ const counter = incrementWebSocketCounter(ctx.socket, counterType)
86
+ const handshakeContext = handshakeSpan.context()
87
+
88
+ const ptrHash = buildWebSocketSpanPointerHash(
89
+ handshakeContext._traceId,
90
+ handshakeContext._spanId,
91
+ counter,
92
+ true, // isServer
93
+ isIncoming
94
+ )
95
+
96
+ const directionName = isIncoming
97
+ ? SPAN_POINTER_DIRECTION_NAME.UPSTREAM
98
+ : SPAN_POINTER_DIRECTION_NAME.DOWNSTREAM
99
+ const direction = isIncoming
100
+ ? SPAN_POINTER_DIRECTION.UPSTREAM
101
+ : SPAN_POINTER_DIRECTION.DOWNSTREAM
102
+
103
+ // Add span pointer attributes to link
104
+ linkAttributes['link.name'] = directionName
105
+ linkAttributes['dd.kind'] = 'span-pointer'
106
+ linkAttributes['ptr.kind'] = WEBSOCKET_PTR_KIND
107
+ linkAttributes['ptr.dir'] = direction
108
+ linkAttributes['ptr.hash'] = ptrHash
109
+ }
110
+ }
111
+
112
+ ctx.span.addLink({
113
+ context: ctx.socket.spanContext,
114
+ attributes: linkAttributes
115
+ })
116
+ }
64
117
 
65
118
  ctx.span.finish()
66
119
  }
@@ -19,6 +19,10 @@ class WSPlugin extends CompositePlugin {
19
19
  }
20
20
 
21
21
  configure (config) {
22
+ if (!config.traceWebsocketMessagesEnabled) {
23
+ super.configure(false)
24
+ return
25
+ }
22
26
  return super.configure(config)
23
27
  }
24
28
  }
@@ -1,6 +1,16 @@
1
1
  'use strict'
2
2
 
3
3
  const TracingPlugin = require('../../dd-trace/src/plugins/tracing.js')
4
+ const {
5
+ WEBSOCKET_PTR_KIND,
6
+ SPAN_POINTER_DIRECTION,
7
+ SPAN_POINTER_DIRECTION_NAME
8
+ } = require('../../dd-trace/src/constants')
9
+ const {
10
+ incrementWebSocketCounter,
11
+ buildWebSocketSpanPointerHash,
12
+ hasDistributedTracingContext
13
+ } = require('./util')
4
14
 
5
15
  class WSProducerPlugin extends TracingPlugin {
6
16
  static get id () { return 'ws' }
@@ -9,9 +19,6 @@ class WSProducerPlugin extends TracingPlugin {
9
19
  static get kind () { return 'producer' }
10
20
 
11
21
  bindStart (ctx) {
12
- const messagesEnabled = this.config.traceWebsocketMessagesEnabled
13
- if (!messagesEnabled) return
14
-
15
22
  const { byteLength, socket, binary } = ctx
16
23
  if (!socket.spanContext) return
17
24
 
@@ -51,9 +58,37 @@ class WSProducerPlugin extends TracingPlugin {
51
58
  if (!Object.hasOwn(ctx, 'result') || !ctx.span) return
52
59
 
53
60
  if (ctx.socket.spanContext) {
61
+ const linkAttributes = { 'dd.kind': 'resuming' }
62
+
63
+ // Add span pointer for context propagation
64
+ if (this.config.traceWebsocketMessagesEnabled && ctx.socket.handshakeSpan) {
65
+ const handshakeSpan = ctx.socket.handshakeSpan
66
+
67
+ // Only add span pointers if distributed tracing is enabled and handshake has distributed context
68
+ if (hasDistributedTracingContext(handshakeSpan, ctx.socket)) {
69
+ const counter = incrementWebSocketCounter(ctx.socket, 'sendCounter')
70
+ const handshakeContext = handshakeSpan.context()
71
+
72
+ const ptrHash = buildWebSocketSpanPointerHash(
73
+ handshakeContext._traceId,
74
+ handshakeContext._spanId,
75
+ counter,
76
+ true, // isServer
77
+ false // isIncoming (this is outgoing)
78
+ )
79
+
80
+ // Add span pointer attributes to link
81
+ linkAttributes['link.name'] = SPAN_POINTER_DIRECTION_NAME.DOWNSTREAM
82
+ linkAttributes['dd.kind'] = 'span-pointer'
83
+ linkAttributes['ptr.kind'] = WEBSOCKET_PTR_KIND
84
+ linkAttributes['ptr.dir'] = SPAN_POINTER_DIRECTION.DOWNSTREAM
85
+ linkAttributes['ptr.hash'] = ptrHash
86
+ }
87
+ }
88
+
54
89
  ctx.span.addLink({
55
90
  context: ctx.socket.spanContext,
56
- attributes: { 'dd.kind': 'resuming' },
91
+ attributes: linkAttributes,
57
92
  })
58
93
  }
59
94
 
@@ -1,6 +1,16 @@
1
1
  'use strict'
2
2
 
3
3
  const TracingPlugin = require('../../dd-trace/src/plugins/tracing.js')
4
+ const {
5
+ WEBSOCKET_PTR_KIND,
6
+ SPAN_POINTER_DIRECTION,
7
+ SPAN_POINTER_DIRECTION_NAME
8
+ } = require('../../dd-trace/src/constants')
9
+ const {
10
+ incrementWebSocketCounter,
11
+ buildWebSocketSpanPointerHash,
12
+ hasDistributedTracingContext
13
+ } = require('./util')
4
14
 
5
15
  class WSReceiverPlugin extends TracingPlugin {
6
16
  static get id () { return 'ws' }
@@ -10,11 +20,9 @@ class WSReceiverPlugin extends TracingPlugin {
10
20
 
11
21
  bindStart (ctx) {
12
22
  const {
13
- traceWebsocketMessagesEnabled,
14
23
  traceWebsocketMessagesInheritSampling,
15
24
  traceWebsocketMessagesSeparateTraces
16
25
  } = this.config
17
- if (!traceWebsocketMessagesEnabled) return
18
26
 
19
27
  const { byteLength, socket, binary } = ctx
20
28
  if (!socket.spanContext) return
@@ -61,9 +69,37 @@ class WSReceiverPlugin extends TracingPlugin {
61
69
  if (!Object.hasOwn(ctx, 'result') || !ctx.span) return
62
70
 
63
71
  if (ctx.socket.spanContext) {
72
+ const linkAttributes = { 'dd.kind': 'executed_by' }
73
+
74
+ // Add span pointer for context propagation
75
+ if (this.config.traceWebsocketMessagesEnabled && ctx.socket.handshakeSpan) {
76
+ const handshakeSpan = ctx.socket.handshakeSpan
77
+
78
+ // Only add span pointers if distributed tracing is enabled and handshake has distributed context
79
+ if (hasDistributedTracingContext(handshakeSpan, ctx.socket)) {
80
+ const counter = incrementWebSocketCounter(ctx.socket, 'receiveCounter')
81
+ const handshakeContext = handshakeSpan.context()
82
+
83
+ const ptrHash = buildWebSocketSpanPointerHash(
84
+ handshakeContext._traceId,
85
+ handshakeContext._spanId,
86
+ counter,
87
+ true, // isServer
88
+ true // isIncoming
89
+ )
90
+
91
+ // Add span pointer attributes to link
92
+ linkAttributes['link.name'] = SPAN_POINTER_DIRECTION_NAME.UPSTREAM
93
+ linkAttributes['dd.kind'] = 'span-pointer'
94
+ linkAttributes['ptr.kind'] = WEBSOCKET_PTR_KIND
95
+ linkAttributes['ptr.dir'] = SPAN_POINTER_DIRECTION.UPSTREAM
96
+ linkAttributes['ptr.hash'] = ptrHash
97
+ }
98
+ }
99
+
64
100
  ctx.span.addLink({
65
101
  context: ctx.socket.spanContext,
66
- attributes: { 'dd.kind': 'executed_by' },
102
+ attributes: linkAttributes,
67
103
  })
68
104
  }
69
105
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  const TracingPlugin = require('../../dd-trace/src/plugins/tracing.js')
4
4
  const tags = require('../../../ext/tags.js')
5
+ const { FORMAT_HTTP_HEADERS } = require('../../../ext/formats')
6
+ const { initWebSocketMessageCounters } = require('./util')
5
7
 
6
8
  const HTTP_STATUS_CODE = tags.HTTP_STATUS_CODE
7
9
 
@@ -28,9 +30,13 @@ class WSServerPlugin extends TracingPlugin {
28
30
 
29
31
  ctx.args = { options }
30
32
 
33
+ // Extract distributed tracing context from request headers
34
+ const childOf = this.tracer.extract(FORMAT_HTTP_HEADERS, req.headers)
35
+
31
36
  const service = this.serviceName({ pluginConfig: this.config })
32
37
  const span = this.startSpan(this.operationName(), {
33
38
  service,
39
+ childOf,
34
40
  meta: {
35
41
  'span.type': 'websocket',
36
42
  'http.upgraded': 'websocket',
@@ -38,7 +44,6 @@ class WSServerPlugin extends TracingPlugin {
38
44
  'http.url': uri,
39
45
  'resource.name': `${options.method} ${route}`,
40
46
  'span.kind': 'server'
41
-
42
47
  }
43
48
 
44
49
  }, ctx)
@@ -46,6 +51,13 @@ class WSServerPlugin extends TracingPlugin {
46
51
 
47
52
  ctx.socket.spanContext = ctx.span._spanContext
48
53
  ctx.socket.spanContext.spanTags = ctx.span._spanContext._tags
54
+ // Store the handshake span for use in message span pointers
55
+ ctx.socket.handshakeSpan = ctx.span
56
+ // Store the request headers for distributed tracing check
57
+ ctx.socket.requestHeaders = req.headers
58
+
59
+ // Initialize message counters for span pointers
60
+ initWebSocketMessageCounters(ctx.socket)
49
61
 
50
62
  return ctx.currentStore
51
63
  }