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
@@ -34,7 +34,66 @@ for (const deprecation of Object.keys(deprecations)) {
34
34
  )
35
35
  }
36
36
 
37
+ let localStableConfig
38
+ let fleetStableConfig
39
+ let stableConfigWarnings
40
+ let stableConfigLoaded = false
41
+
42
+ function loadStableConfig () {
43
+ stableConfigLoaded = true
44
+
45
+ // Lazy require to avoid circular dependency at module load time.
46
+ const { isInServerlessEnvironment } = require('../serverless')
47
+ if (isInServerlessEnvironment()) {
48
+ // Stable config is not supported in serverless environments.
49
+ return
50
+ }
51
+
52
+ const StableConfig = require('./stable')
53
+ const instance = new StableConfig()
54
+ localStableConfig = instance.localEntries
55
+ fleetStableConfig = instance.fleetEntries
56
+ stableConfigWarnings = instance.warnings
57
+ }
58
+
59
+ function getValueFromSource (name, source) {
60
+ const value = source[name]
61
+
62
+ if (value === undefined && aliases[name]) {
63
+ for (const alias of aliases[name]) {
64
+ if (source[alias] !== undefined) {
65
+ return source[alias]
66
+ }
67
+ }
68
+ }
69
+
70
+ return value
71
+ }
72
+
73
+ function validateAccess (name) {
74
+ if ((name.startsWith('DD_') || name.startsWith('OTEL_') || aliasToCanonical[name]) &&
75
+ !supportedConfigurations[name]) {
76
+ throw new Error(`Missing ${name} env/configuration in "supported-configurations.json" file.`)
77
+ }
78
+ }
79
+
37
80
  module.exports = {
81
+ /**
82
+ * Expose raw stable config maps and warnings for consumers that need
83
+ * per-source access (e.g. telemetry in Config).
84
+ *
85
+ * @returns {{ localStableConfig: object, fleetStableConfig: object, stableConfigWarnings: string[] }}
86
+ */
87
+ getStableConfigSources () {
88
+ if (!stableConfigLoaded) {
89
+ loadStableConfig()
90
+ }
91
+ return {
92
+ localStableConfig,
93
+ fleetStableConfig,
94
+ stableConfigWarnings,
95
+ }
96
+ },
38
97
  /**
39
98
  * Returns the environment variables that are supported by the tracer
40
99
  * (including all non-Datadog/OTEL specific environment variables).
@@ -46,6 +105,7 @@ module.exports = {
46
105
  getEnvironmentVariables () {
47
106
  const configs = {}
48
107
  for (const [key, value] of Object.entries(process.env)) {
108
+ // TODO(BridgeAR): Handle telemetry reporting for aliases.
49
109
  if (key.startsWith('DD_') || key.startsWith('OTEL_') || aliasToCanonical[key]) {
50
110
  if (supportedConfigurations[key]) {
51
111
  configs[key] = value
@@ -72,28 +132,41 @@ module.exports = {
72
132
  return configs
73
133
  },
74
134
 
135
+ getEnvironmentVariable (name) {
136
+ validateAccess(name)
137
+ return getValueFromSource(name, process.env)
138
+ },
139
+
75
140
  /**
76
- * Returns the environment variable, if it's supported or a non Datadog
77
- * configuration. Otherwise, it throws an error.
141
+ * Returns the value stored at the given name, assumed to be in environment variable format,
142
+ * from the supported env sources (process.env, local stable config, fleet stable config).
143
+ * Falls back to aliases if the canonical name is not set.
78
144
  *
79
145
  * @param {string} name Environment variable name
80
146
  * @returns {string|undefined}
81
147
  * @throws {Error} if the configuration is not supported
82
148
  */
83
- // This method, and callers of this method, need to be updated to check for declarative config sources as well.
84
- getEnvironmentVariable (name) {
85
- if ((name.startsWith('DD_') || name.startsWith('OTEL_') || aliasToCanonical[name]) &&
86
- !supportedConfigurations[name]) {
87
- throw new Error(`Missing ${name} env/configuration in "supported-configurations.json" file.`)
149
+ getValueFromEnvSources (name) {
150
+ validateAccess(name)
151
+
152
+ if (!stableConfigLoaded) {
153
+ loadStableConfig()
88
154
  }
89
- const config = process.env[name]
90
- if (config === undefined && aliases[name]) {
91
- for (const alias of aliases[name]) {
92
- if (process.env[alias] !== undefined) {
93
- return process.env[alias]
94
- }
155
+
156
+ if (fleetStableConfig !== undefined) {
157
+ const fromFleet = getValueFromSource(name, fleetStableConfig)
158
+ if (fromFleet !== undefined) {
159
+ return fromFleet
95
160
  }
96
161
  }
97
- return config
98
- }
162
+
163
+ const fromEnv = getValueFromSource(name, process.env)
164
+ if (fromEnv !== undefined) {
165
+ return fromEnv
166
+ }
167
+
168
+ if (localStableConfig !== undefined) {
169
+ return getValueFromSource(name, localStableConfig)
170
+ }
171
+ },
99
172
  }
@@ -2,25 +2,30 @@
2
2
 
3
3
  const fs = require('fs')
4
4
  const os = require('os')
5
- const uuid = require('../../../vendor/dist/crypto-randomuuid') // we need to keep the old uuid dep because of cypress
6
5
  const { URL } = require('url')
7
-
8
- const log = require('./log')
9
- const tagger = require('./tagger')
10
- const set = require('../../datadog-core/src/utils/src/set')
11
- const { isTrue, isFalse, normalizeProfilingEnabledValue } = require('./util')
12
- const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('./plugins/util/tags')
6
+ const path = require('path')
7
+ const uuid = require('../../../../vendor/dist/crypto-randomuuid') // we need to keep the old uuid dep because of cypress
8
+
9
+ const set = require('../../../datadog-core/src/utils/src/set')
10
+ const { DD_MAJOR } = require('../../../../version')
11
+ const log = require('../log')
12
+ const tagger = require('../tagger')
13
+ const { isTrue, isFalse, normalizeProfilingEnabledValue } = require('../util')
14
+ const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../plugins/util/tags')
15
+ const { updateConfig } = require('../telemetry')
16
+ const telemetryMetrics = require('../telemetry/metrics')
17
+ const {
18
+ isInServerlessEnvironment,
19
+ getIsGCPFunction,
20
+ getIsAzureFunction,
21
+ enableGCPPubSubPushSubscription
22
+ } = require('../serverless')
23
+ const { ORIGIN_KEY } = require('../constants')
24
+ const { appendRules } = require('../payload-tagging/config')
13
25
  const { getGitMetadataFromGitProperties, removeUserSensitiveInfo, getRemoteOriginURL, resolveGitHeadSHA } =
14
26
  require('./git_properties')
15
- const { updateConfig } = require('./telemetry')
16
- const telemetryMetrics = require('./telemetry/metrics')
17
- const { isInServerlessEnvironment, getIsGCPFunction, getIsAzureFunction } = require('./serverless')
18
- const { ORIGIN_KEY } = require('./constants')
19
- const { appendRules } = require('./payload-tagging/config')
20
- const { getEnvironmentVariable: getEnv, getEnvironmentVariables } = require('./config-helper')
21
- const defaults = require('./config_defaults')
22
- const path = require('path')
23
- const { DD_MAJOR } = require('../../../version')
27
+ const { getEnvironmentVariable: getEnv, getEnvironmentVariables, getStableConfigSources } = require('./helper')
28
+ const defaults = require('./defaults')
24
29
 
25
30
  const tracerMetrics = telemetryMetrics.manager.namespace('tracers')
26
31
 
@@ -182,7 +187,7 @@ function validateNamingVersion (versionString) {
182
187
  * @param {string | string[]} input
183
188
  */
184
189
  function splitJSONPathRules (input) {
185
- if (!input) return
190
+ if (!input || input === '$') return
186
191
  if (Array.isArray(input)) return input
187
192
  if (input === 'all') return []
188
193
  return input.split(',')
@@ -271,13 +276,14 @@ class Config {
271
276
 
272
277
  constructor (options = {}) {
273
278
  if (!isInServerlessEnvironment()) {
274
- // Bail out early if we're in a serverless environment, stable config isn't supported
275
- const StableConfig = require('./config_stable')
276
- this.stableConfig = new StableConfig()
279
+ const configEnvSources = getStableConfigSources()
280
+ this.stableConfig = {
281
+ fleetEntries: configEnvSources.fleetStableConfig,
282
+ localEntries: configEnvSources.localStableConfig,
283
+ warnings: configEnvSources.stableConfigWarnings
284
+ }
277
285
  }
278
286
 
279
- const envs = getEnvironmentVariables()
280
-
281
287
  options = {
282
288
  ...options,
283
289
  appsec: options.appsec == null ? options.experimental?.appsec : options.appsec,
@@ -321,11 +327,10 @@ class Config {
321
327
  this.#defaults = defaults
322
328
  this.#applyDefaults()
323
329
  this.#applyStableConfig(this.stableConfig?.localEntries ?? {}, this.#localStableConfig)
324
- this.#applyEnvironment(envs)
330
+ this.#applyEnvironment()
325
331
  this.#applyStableConfig(this.stableConfig?.fleetEntries ?? {}, this.#fleetStableConfig)
326
332
  this.#applyOptions(options)
327
333
  this.#applyCalculated()
328
- this.#applyRemote({})
329
334
  this.#merge()
330
335
 
331
336
  tagger.add(this.tags, {
@@ -342,7 +347,7 @@ class Config {
342
347
  }
343
348
 
344
349
  if (this.gitMetadataEnabled) {
345
- this.#loadGitMetadata(envs)
350
+ this.#loadGitMetadata()
346
351
  }
347
352
  }
348
353
 
@@ -350,15 +355,38 @@ class Config {
350
355
  return this.#parsedDdTags
351
356
  }
352
357
 
353
- // Supports only a subset of options for now.
354
- configure (options, remote) {
355
- if (remote) {
356
- this.#applyRemote(options)
357
- } else {
358
- this.#applyOptions(options)
358
+ /**
359
+ * Set the configuration with remote config settings.
360
+ * Applies remote configuration, recalculates derived values, and merges all configuration sources.
361
+ *
362
+ * @param {import('./config/remote_config').RemoteConfigOptions|null} options - Configurations received via Remote
363
+ * Config or null to reset all remote configuration
364
+ */
365
+ setRemoteConfig (options) {
366
+ // Clear all RC-managed fields to ensure previous values don't persist.
367
+ // State is instead managed by the `RCClientLibConfigManager` class
368
+ this.#remote = {}
369
+ this.#remoteUnprocessed = {}
370
+
371
+ // Special case: if options is null, nothing to apply
372
+ // This happens when all remote configs are removed
373
+ if (options !== null) {
374
+ this.#applyRemoteConfig(options)
359
375
  }
360
376
 
361
- // TODO: test
377
+ this.#applyCalculated()
378
+ this.#merge()
379
+ }
380
+
381
+ // TODO: Remove the `updateOptions` method. We don't want to support updating the config this way
382
+ /**
383
+ * Updates the configuration with new programmatic options.
384
+ *
385
+ * @deprecated This method should not be used and will be removed in a future version.
386
+ * @param {object} options - Configuration options to apply (same format as tracer init options)
387
+ */
388
+ updateOptions (options) {
389
+ this.#applyOptions(options)
362
390
  this.#applyCalculated()
363
391
  this.#merge()
364
392
  }
@@ -475,6 +503,7 @@ class Config {
475
503
  DD_IAST_STACK_TRACE_ENABLED,
476
504
  DD_INJECTION_ENABLED,
477
505
  DD_INJECT_FORCE,
506
+ DD_ENABLE_NX_SERVICE_NAME,
478
507
  DD_INSTRUMENTATION_TELEMETRY_ENABLED,
479
508
  DD_INSTRUMENTATION_CONFIG_ID,
480
509
  DD_LOGS_INJECTION,
@@ -588,7 +617,8 @@ class Config {
588
617
  OTEL_BSP_SCHEDULE_DELAY,
589
618
  OTEL_BSP_MAX_EXPORT_BATCH_SIZE,
590
619
  OTEL_BSP_MAX_QUEUE_SIZE,
591
- OTEL_METRIC_EXPORT_INTERVAL
620
+ OTEL_METRIC_EXPORT_INTERVAL,
621
+ NX_TASK_TARGET_PROJECT
592
622
  } = source
593
623
 
594
624
  const tags = {}
@@ -801,6 +831,7 @@ class Config {
801
831
  this.#setBoolean(target, 'injectForce', DD_INJECT_FORCE)
802
832
  this.#setBoolean(target, 'isAzureFunction', getIsAzureFunction())
803
833
  this.#setBoolean(target, 'isGCPFunction', getIsGCPFunction())
834
+ this.#setBoolean(target, 'gcpPubSubPushSubscriptionEnabled', enableGCPPubSubPushSubscription())
804
835
  target['langchain.spanCharLimit'] = maybeInt(DD_LANGCHAIN_SPAN_CHAR_LIMIT)
805
836
  target['langchain.spanPromptCompletionSampleRate'] = maybeFloat(DD_LANGCHAIN_SPAN_PROMPT_COMPLETION_SAMPLE_RATE)
806
837
  this.#setBoolean(target, 'legacyBaggageEnabled', DD_TRACE_LEGACY_BAGGAGE_ENABLED)
@@ -858,7 +889,22 @@ class Config {
858
889
  this.#setSamplingRule(target, 'sampler.rules', safeJsonParse(DD_TRACE_SAMPLING_RULES))
859
890
  unprocessedTarget['sampler.rules'] = DD_TRACE_SAMPLING_RULES
860
891
  this.#setString(target, 'scope', DD_TRACE_SCOPE)
861
- this.#setString(target, 'service', DD_SERVICE || tags.service || OTEL_SERVICE_NAME)
892
+ // Priority:
893
+ // DD_SERVICE > tags.service > OTEL_SERVICE_NAME > NX_TASK_TARGET_PROJECT (if DD_ENABLE_NX_SERVICE_NAME) > default
894
+ let serviceName = DD_SERVICE || tags.service || OTEL_SERVICE_NAME
895
+ if (!serviceName && NX_TASK_TARGET_PROJECT) {
896
+ if (isTrue(DD_ENABLE_NX_SERVICE_NAME)) {
897
+ serviceName = NX_TASK_TARGET_PROJECT
898
+ } else if (DD_MAJOR < 6) {
899
+ // Warn about v6 behavior change for Nx projects
900
+ log.warn(
901
+ 'NX_TASK_TARGET_PROJECT is set but no service name was configured. ' +
902
+ 'In v6, NX_TASK_TARGET_PROJECT will be used as the default service name. ' +
903
+ 'Set DD_ENABLE_NX_SERVICE_NAME=true to opt-in to this behavior now, or set a service name explicitly.'
904
+ )
905
+ }
906
+ }
907
+ this.#setString(target, 'service', serviceName)
862
908
  if (DD_SERVICE_MAPPING) {
863
909
  target.serviceMapping = Object.fromEntries(
864
910
  DD_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
@@ -1152,9 +1198,8 @@ class Config {
1152
1198
  // This is reliant on environment config being set before options.
1153
1199
  // This is to make sure the origins of each value are tracked appropriately for telemetry.
1154
1200
  // We'll only set `llmobs.enabled` on the opts when it's not set on the environment, and options.llmobs is provided.
1155
- const llmobsEnabledEnv = this.#env['llmobs.enabled']
1156
- if (llmobsEnabledEnv == null && options.llmobs) {
1157
- this.#setBoolean(opts, 'llmobs.enabled', !!options.llmobs)
1201
+ if (this.#env['llmobs.enabled'] == null && options.llmobs) {
1202
+ this.#setBoolean(opts, 'llmobs.enabled', true)
1158
1203
  }
1159
1204
  }
1160
1205
 
@@ -1284,31 +1329,36 @@ class Config {
1284
1329
  }
1285
1330
  }
1286
1331
 
1287
- #applyRemote (options) {
1332
+ /**
1333
+ * Applies remote configuration options from APM_TRACING configs.
1334
+ *
1335
+ * @param {import('./config/remote_config').RemoteConfigOptions} options - Configurations received via Remote Config
1336
+ */
1337
+ #applyRemoteConfig (options) {
1288
1338
  const opts = this.#remote
1289
- const tags = {}
1290
- const headerTags = options.tracing_header_tags
1291
- ? options.tracing_header_tags.map(tag => {
1292
- return tag.tag_name ? `${tag.header}:${tag.tag_name}` : tag.header
1293
- })
1294
- : undefined
1295
-
1296
- tagger.add(tags, options.tracing_tags)
1297
- if (Object.keys(tags).length) tags['runtime-id'] = runtimeId
1298
1339
 
1340
+ this.#setBoolean(opts, 'dynamicInstrumentation.enabled', options.dynamic_instrumentation_enabled)
1341
+ this.#setBoolean(opts, 'codeOriginForSpans.enabled', options.code_origin_enabled)
1299
1342
  this.#setUnit(opts, 'sampleRate', options.tracing_sampling_rate)
1300
1343
  this.#setBoolean(opts, 'logInjection', options.log_injection_enabled)
1301
- opts.headerTags = headerTags
1302
- this.#setTags(opts, 'tags', tags)
1303
1344
  this.#setBoolean(opts, 'tracing', options.tracing_enabled)
1304
1345
  this.#remoteUnprocessed['sampler.rules'] = options.tracing_sampling_rules
1305
- this.#setSamplingRule(opts, 'sampler.rules', this.#reformatTags(options.tracing_sampling_rules))
1346
+ this.#setSamplingRule(opts, 'sampler.rules', this.#reformatTagsFromRC(options.tracing_sampling_rules))
1347
+
1348
+ opts.headerTags = options.tracing_header_tags?.map(tag => {
1349
+ return tag.tag_name ? `${tag.header}:${tag.tag_name}` : tag.header
1350
+ })
1351
+
1352
+ const tags = {}
1353
+ tagger.add(tags, options.tracing_tags)
1354
+ if (Object.keys(tags).length) tags['runtime-id'] = runtimeId
1355
+ this.#setTags(opts, 'tags', tags)
1306
1356
  }
1307
1357
 
1308
- #reformatTags (samplingRules) {
1358
+ #reformatTagsFromRC (samplingRules) {
1309
1359
  for (const rule of (samplingRules || [])) {
1310
- const reformattedTags = {}
1311
1360
  if (rule.tags) {
1361
+ const reformattedTags = {}
1312
1362
  for (const tag of rule.tags) {
1313
1363
  reformattedTags[tag.key] = tag.value_glob
1314
1364
  }
@@ -1473,26 +1523,24 @@ class Config {
1473
1523
  }
1474
1524
  }
1475
1525
 
1476
- #loadGitMetadata (envs) {
1526
+ #loadGitMetadata () {
1477
1527
  // try to read Git metadata from the environment variables
1478
1528
  this.repositoryUrl = removeUserSensitiveInfo(
1479
- envs.DD_GIT_REPOSITORY_URL ??
1480
- this.tags[GIT_REPOSITORY_URL]
1529
+ getEnv('DD_GIT_REPOSITORY_URL') ?? this.tags[GIT_REPOSITORY_URL]
1481
1530
  )
1482
- this.commitSHA = envs.DD_GIT_COMMIT_SHA ??
1483
- this.tags[GIT_COMMIT_SHA]
1531
+ this.commitSHA = getEnv('DD_GIT_COMMIT_SHA') ?? this.tags[GIT_COMMIT_SHA]
1484
1532
 
1485
1533
  // otherwise, try to read Git metadata from the git.properties file
1486
1534
  if (!this.repositoryUrl || !this.commitSHA) {
1487
- const DD_GIT_PROPERTIES_FILE = envs.DD_GIT_PROPERTIES_FILE ??
1488
- `${process.cwd()}/git.properties`
1535
+ const DD_GIT_PROPERTIES_FILE = getEnv('DD_GIT_PROPERTIES_FILE')
1536
+ const gitPropertiesFile = DD_GIT_PROPERTIES_FILE ?? `${process.cwd()}/git.properties`
1489
1537
  let gitPropertiesString
1490
1538
  try {
1491
- gitPropertiesString = fs.readFileSync(DD_GIT_PROPERTIES_FILE, 'utf8')
1539
+ gitPropertiesString = fs.readFileSync(gitPropertiesFile, 'utf8')
1492
1540
  } catch (e) {
1493
1541
  // Only log error if the user has set a git.properties path
1494
- if (envs.DD_GIT_PROPERTIES_FILE) {
1495
- log.error('Error reading DD_GIT_PROPERTIES_FILE: %s', DD_GIT_PROPERTIES_FILE, e)
1542
+ if (DD_GIT_PROPERTIES_FILE) {
1543
+ log.error('Error reading DD_GIT_PROPERTIES_FILE: %s', gitPropertiesFile, e)
1496
1544
  }
1497
1545
  }
1498
1546
  if (gitPropertiesString) {
@@ -1503,11 +1551,11 @@ class Config {
1503
1551
  }
1504
1552
  // otherwise, try to read Git metadata from the .git/ folder
1505
1553
  if (!this.repositoryUrl || !this.commitSHA) {
1506
- const DD_GIT_FOLDER_PATH = envs.DD_GIT_FOLDER_PATH ??
1507
- path.join(process.cwd(), '.git')
1554
+ const DD_GIT_FOLDER_PATH = getEnv('DD_GIT_FOLDER_PATH')
1555
+ const gitFolderPath = DD_GIT_FOLDER_PATH ?? path.join(process.cwd(), '.git')
1508
1556
  if (!this.repositoryUrl) {
1509
1557
  // try to read git config (repository URL)
1510
- const gitConfigPath = path.join(DD_GIT_FOLDER_PATH, 'config')
1558
+ const gitConfigPath = path.join(gitFolderPath, 'config')
1511
1559
  try {
1512
1560
  const gitConfigContent = fs.readFileSync(gitConfigPath, 'utf8')
1513
1561
  if (gitConfigContent) {
@@ -1515,14 +1563,14 @@ class Config {
1515
1563
  }
1516
1564
  } catch (e) {
1517
1565
  // Only log error if the user has set a .git/ path
1518
- if (envs.DD_GIT_FOLDER_PATH) {
1566
+ if (DD_GIT_FOLDER_PATH) {
1519
1567
  log.error('Error reading git config: %s', gitConfigPath, e)
1520
1568
  }
1521
1569
  }
1522
1570
  }
1523
1571
  if (!this.commitSHA) {
1524
1572
  // try to read git HEAD (commit SHA)
1525
- const gitHeadSha = resolveGitHeadSHA(DD_GIT_FOLDER_PATH)
1573
+ const gitHeadSha = resolveGitHeadSHA(gitFolderPath)
1526
1574
  if (gitHeadSha) {
1527
1575
  this.commitSHA = gitHeadSha
1528
1576
  }
@@ -0,0 +1,202 @@
1
+ 'use strict'
2
+
3
+ const RemoteConfigCapabilities = require('../remote_config/capabilities')
4
+ const log = require('../log')
5
+
6
+ module.exports = {
7
+ enable
8
+ }
9
+
10
+ /**
11
+ * @typedef {object} RemoteConfigOptions
12
+ * @property {boolean} [dynamic_instrumentation_enabled] - Enable Dynamic Instrumentation
13
+ * @property {boolean} [code_origin_enabled] - Enable code origin tagging for spans
14
+ * @property {Array<{header: string, tag_name?: string}>} [tracing_header_tags] - HTTP headers to tag
15
+ * @property {Array<string>} [tracing_tags] - Global tags (format: "key:value")
16
+ * @property {number} [tracing_sampling_rate] - Global sampling rate (0.0-1.0)
17
+ * @property {boolean} [log_injection_enabled] - Enable trace context log injection
18
+ * @property {boolean} [tracing_enabled] - Enable/disable tracing globally
19
+ * @property {Array<object>} [tracing_sampling_rules] - Trace sampling rules configuration
20
+ */
21
+
22
+ /**
23
+ * @typedef {ReturnType<import('../config')>} Config
24
+ */
25
+
26
+ /**
27
+ * Manages multiple APM_TRACING configurations with priority-based merging
28
+ */
29
+ class RCClientLibConfigManager {
30
+ /**
31
+ * @param {string} currentService - Current service name
32
+ * @param {string} currentEnv - Current environment name
33
+ */
34
+ constructor (currentService, currentEnv) {
35
+ this.configs = new Map() // config_id -> { conf, priority }
36
+ this.currentService = currentService
37
+ this.currentEnv = currentEnv
38
+ }
39
+
40
+ /**
41
+ * Calculate priority based on target specificity. Higher values take precedence.
42
+ * Priority order (highest → lowest):
43
+ * Service+Env (5) > Service (4) > Env (3) > Cluster (2) > Org (1)
44
+ *
45
+ * @param {object} conf - Remote config object with service_target and k8s_target_v2 properties
46
+ * @returns {number} Priority value from 1 (org-level) to 5 (service+env specific)
47
+ */
48
+ calculatePriority (conf) {
49
+ const serviceTarget = conf.service_target
50
+ const k8sTarget = conf.k8s_target_v2
51
+
52
+ if (serviceTarget) {
53
+ const service = serviceTarget.service
54
+ const env = serviceTarget.env
55
+
56
+ const hasSpecificService = service && service !== '*'
57
+ const hasSpecificEnv = env && env !== '*'
58
+
59
+ if (hasSpecificService && hasSpecificEnv) return 5
60
+ if (hasSpecificService) return 4
61
+ if (hasSpecificEnv) return 3
62
+ }
63
+
64
+ if (k8sTarget) return 2
65
+
66
+ return 1 // Org level
67
+ }
68
+
69
+ /**
70
+ * Check if config matches current service/env
71
+ *
72
+ * @param {object} conf - Remote config object with service_target property
73
+ * @returns {boolean} True if config matches current service/env or has no filter
74
+ */
75
+ matchesCurrentServiceEnv (conf) {
76
+ const serviceTarget = conf.service_target
77
+ if (!serviceTarget) return true // No filter means match all
78
+
79
+ const service = serviceTarget.service
80
+ const env = serviceTarget.env
81
+
82
+ // Check service match
83
+ if (service && service !== '*' && service !== this.currentService) {
84
+ log.debug('[config/remote_config] Ignoring config for service: %s (current: %s)',
85
+ service, this.currentService)
86
+ return false
87
+ }
88
+
89
+ // Check env match
90
+ if (env && env !== '*' && env !== this.currentEnv) {
91
+ log.debug('[config/remote_config] Ignoring config for env: %s (current: %s)',
92
+ env, this.currentEnv)
93
+ return false
94
+ }
95
+
96
+ return true
97
+ }
98
+
99
+ /**
100
+ * Add or update a config
101
+ *
102
+ * @param {string} configId - Unique identifier for the config
103
+ * @param {object} conf - Remote config object to add
104
+ */
105
+ addConfig (configId, conf) {
106
+ if (!this.matchesCurrentServiceEnv(conf)) {
107
+ return
108
+ }
109
+
110
+ const priority = this.calculatePriority(conf)
111
+ this.configs.set(configId, { conf, priority })
112
+
113
+ log.debug('[config/remote_config] Added config %s with priority %d', configId, priority)
114
+ }
115
+
116
+ /**
117
+ * Remove a config
118
+ *
119
+ * @param {string} configId - Unique identifier for the config to remove
120
+ */
121
+ removeConfig (configId) {
122
+ const removed = this.configs.delete(configId)
123
+ if (removed) {
124
+ log.debug('[config/remote_config] Removed config %s', configId)
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Get merged lib_config with higher priority configs overriding lower priority ones
130
+ *
131
+ * @returns {RemoteConfigOptions|null} Merged config object or null if no configs present
132
+ */
133
+ getMergedLibConfig () {
134
+ if (this.configs.size === 0) return null
135
+
136
+ let hasLibConfig = false
137
+
138
+ const merged = [...this.configs.values()]
139
+ .sort((a, b) => a.priority - b.priority)
140
+ .reduce((merged, { conf }) => {
141
+ if (conf.lib_config != null) hasLibConfig = true
142
+ return Object.assign(merged, conf.lib_config)
143
+ }, {})
144
+
145
+ return hasLibConfig ? merged : null
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Configures remote config for core APM tracing functionality
151
+ *
152
+ * @param {import('../remote_config')} rc - RemoteConfig instance
153
+ * @param {Config} config - Tracer config
154
+ * @param {() => void} onConfigUpdated - Function to call when config is updated
155
+ */
156
+ function enable (rc, config, onConfigUpdated) {
157
+ // This tracer supports receiving config subsets via the APM_TRACING product handler.
158
+ rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_MULTICONFIG, true)
159
+
160
+ // Tracing
161
+ rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_ENABLED, true)
162
+ rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_SAMPLE_RATE, true)
163
+ rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_SAMPLE_RULES, true)
164
+ rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_CUSTOM_TAGS, true)
165
+ rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_HTTP_HEADER_TAGS, true)
166
+
167
+ // Log Management
168
+ rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_LOGS_INJECTION, true)
169
+
170
+ // Debugger
171
+ rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_ENABLE_DYNAMIC_INSTRUMENTATION, true)
172
+
173
+ // Code Origin
174
+ rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_ENABLE_CODE_ORIGIN, true)
175
+
176
+ const rcClientLibConfigManager = new RCClientLibConfigManager(config.service, config.env)
177
+
178
+ // Subscribe to APM_TRACING product (setBatchHandler used below doesn't automatically subscribe)
179
+ rc.subscribeProducts('APM_TRACING')
180
+
181
+ // Use a batch handler to process all changes before updating the config. This is important in case there's
182
+ // conflicting configs between, for example, the org and service level.
183
+ rc.setBatchHandler(['APM_TRACING'], (transaction) => {
184
+ const { toUnapply, toApply, toModify } = transaction
185
+
186
+ for (const item of toUnapply) {
187
+ rcClientLibConfigManager.removeConfig(item.id)
188
+ transaction.ack(item.path)
189
+ }
190
+
191
+ for (const item of [...toApply, ...toModify]) {
192
+ rcClientLibConfigManager.addConfig(item.id, item.file)
193
+ transaction.ack(item.path)
194
+ }
195
+
196
+ // Get merged config and apply it
197
+ const mergedLibConfig = rcClientLibConfigManager.getMergedLibConfig()
198
+ config.setRemoteConfig(mergedLibConfig)
199
+
200
+ onConfigUpdated()
201
+ })
202
+ }