dd-trace 5.53.0 → 5.55.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 (368) hide show
  1. package/LICENSE-3rdparty.csv +2 -1
  2. package/ci/cypress/plugin.js +8 -0
  3. package/ci/cypress/polyfills.js +23 -0
  4. package/ci/init.js +8 -7
  5. package/index.d.ts +33 -16
  6. package/initialize.mjs +5 -6
  7. package/package.json +40 -38
  8. package/packages/datadog-code-origin/index.js +22 -4
  9. package/packages/datadog-core/src/utils/src/get.js +1 -1
  10. package/packages/datadog-core/src/utils/src/has.js +1 -1
  11. package/packages/datadog-core/src/utils/src/kebabcase.js +4 -6
  12. package/packages/datadog-core/src/utils/src/parse-tags.js +1 -1
  13. package/packages/datadog-core/src/utils/src/pick.js +2 -2
  14. package/packages/datadog-core/src/utils/src/set.js +1 -1
  15. package/packages/datadog-core/src/utils/src/uniq.js +1 -1
  16. package/packages/datadog-instrumentations/src/amqp10.js +19 -17
  17. package/packages/datadog-instrumentations/src/amqplib.js +52 -35
  18. package/packages/datadog-instrumentations/src/apollo.js +2 -2
  19. package/packages/datadog-instrumentations/src/aws-sdk.js +1 -1
  20. package/packages/datadog-instrumentations/src/cassandra-driver.js +10 -10
  21. package/packages/datadog-instrumentations/src/child_process.js +1 -2
  22. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +89 -75
  23. package/packages/datadog-instrumentations/src/cookie-parser.js +1 -1
  24. package/packages/datadog-instrumentations/src/couchbase.js +6 -9
  25. package/packages/datadog-instrumentations/src/cucumber.js +108 -68
  26. package/packages/datadog-instrumentations/src/cypress.js +2 -1
  27. package/packages/datadog-instrumentations/src/dns.js +5 -5
  28. package/packages/datadog-instrumentations/src/elasticsearch.js +9 -10
  29. package/packages/datadog-instrumentations/src/fastify.js +7 -9
  30. package/packages/datadog-instrumentations/src/fs.js +1 -1
  31. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +35 -43
  32. package/packages/datadog-instrumentations/src/graphql.js +7 -10
  33. package/packages/datadog-instrumentations/src/grpc/client.js +11 -23
  34. package/packages/datadog-instrumentations/src/grpc/server.js +7 -20
  35. package/packages/datadog-instrumentations/src/hapi.js +10 -11
  36. package/packages/datadog-instrumentations/src/helpers/extract-package-and-module-path.js +16 -10
  37. package/packages/datadog-instrumentations/src/helpers/fetch.js +4 -5
  38. package/packages/datadog-instrumentations/src/helpers/hook.js +2 -3
  39. package/packages/datadog-instrumentations/src/helpers/hooks.js +0 -1
  40. package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -41
  41. package/packages/datadog-instrumentations/src/helpers/register.js +11 -12
  42. package/packages/datadog-instrumentations/src/http/client.js +14 -20
  43. package/packages/datadog-instrumentations/src/jest.js +201 -143
  44. package/packages/datadog-instrumentations/src/kafkajs.js +52 -44
  45. package/packages/datadog-instrumentations/src/knex.js +4 -4
  46. package/packages/datadog-instrumentations/src/koa.js +2 -3
  47. package/packages/datadog-instrumentations/src/ldapjs.js +3 -4
  48. package/packages/datadog-instrumentations/src/mariadb.js +49 -65
  49. package/packages/datadog-instrumentations/src/mocha/main.js +116 -73
  50. package/packages/datadog-instrumentations/src/mocha/utils.js +36 -12
  51. package/packages/datadog-instrumentations/src/mocha/worker.js +6 -0
  52. package/packages/datadog-instrumentations/src/mocha.js +3 -1
  53. package/packages/datadog-instrumentations/src/mongodb-core.js +1 -1
  54. package/packages/datadog-instrumentations/src/mysql.js +30 -37
  55. package/packages/datadog-instrumentations/src/mysql2.js +53 -47
  56. package/packages/datadog-instrumentations/src/net.js +1 -1
  57. package/packages/datadog-instrumentations/src/next.js +1 -0
  58. package/packages/datadog-instrumentations/src/nyc.js +3 -2
  59. package/packages/datadog-instrumentations/src/openai.js +22 -24
  60. package/packages/datadog-instrumentations/src/oracledb.js +1 -1
  61. package/packages/datadog-instrumentations/src/otel-sdk-trace.js +4 -3
  62. package/packages/datadog-instrumentations/src/pg.js +3 -5
  63. package/packages/datadog-instrumentations/src/playwright.js +123 -83
  64. package/packages/datadog-instrumentations/src/protobufjs.js +3 -4
  65. package/packages/datadog-instrumentations/src/redis.js +4 -4
  66. package/packages/datadog-instrumentations/src/restify.js +9 -13
  67. package/packages/datadog-instrumentations/src/rhea.js +42 -54
  68. package/packages/datadog-instrumentations/src/router.js +30 -32
  69. package/packages/datadog-instrumentations/src/tedious.js +2 -3
  70. package/packages/datadog-instrumentations/src/vitest.js +87 -52
  71. package/packages/datadog-plugin-amqp10/src/consumer.js +7 -3
  72. package/packages/datadog-plugin-amqp10/src/producer.js +7 -3
  73. package/packages/datadog-plugin-amqplib/src/client.js +6 -2
  74. package/packages/datadog-plugin-amqplib/src/consumer.js +7 -3
  75. package/packages/datadog-plugin-amqplib/src/producer.js +7 -3
  76. package/packages/datadog-plugin-amqplib/src/util.js +1 -1
  77. package/packages/datadog-plugin-apollo/src/gateway/request.js +5 -6
  78. package/packages/datadog-plugin-apollo/src/gateway/validate.js +2 -3
  79. package/packages/datadog-plugin-avsc/src/schema_iterator.js +12 -12
  80. package/packages/datadog-plugin-aws-sdk/src/base.js +15 -10
  81. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +2 -2
  82. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +13 -13
  83. package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +3 -5
  84. package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +28 -43
  85. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -2
  86. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +10 -11
  87. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +4 -6
  88. package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +3 -5
  89. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +3 -5
  90. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +2 -3
  91. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +11 -15
  92. package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +1 -1
  93. package/packages/datadog-plugin-aws-sdk/src/util.js +5 -6
  94. package/packages/datadog-plugin-cassandra-driver/src/index.js +1 -1
  95. package/packages/datadog-plugin-child_process/src/index.js +4 -4
  96. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +23 -23
  97. package/packages/datadog-plugin-cucumber/src/index.js +60 -4
  98. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +99 -28
  99. package/packages/datadog-plugin-cypress/src/plugin.js +11 -1
  100. package/packages/datadog-plugin-cypress/src/support.js +24 -5
  101. package/packages/datadog-plugin-dd-trace-api/src/index.js +2 -1
  102. package/packages/datadog-plugin-elasticsearch/src/index.js +1 -1
  103. package/packages/datadog-plugin-express/src/code_origin.js +30 -0
  104. package/packages/datadog-plugin-express/src/index.js +10 -12
  105. package/packages/datadog-plugin-express/src/tracing.js +19 -0
  106. package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +7 -3
  107. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +12 -7
  108. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +6 -2
  109. package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +27 -10
  110. package/packages/datadog-plugin-graphql/src/execute.js +2 -2
  111. package/packages/datadog-plugin-graphql/src/index.js +10 -8
  112. package/packages/datadog-plugin-graphql/src/resolve.js +19 -12
  113. package/packages/datadog-plugin-graphql/src/tools/index.js +1 -0
  114. package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -0
  115. package/packages/datadog-plugin-graphql/src/tools/transforms.js +1 -0
  116. package/packages/datadog-plugin-grpc/src/client.js +2 -2
  117. package/packages/datadog-plugin-grpc/src/util.js +2 -2
  118. package/packages/datadog-plugin-http/src/client.js +23 -13
  119. package/packages/datadog-plugin-http2/src/client.js +24 -25
  120. package/packages/datadog-plugin-jest/src/index.js +26 -23
  121. package/packages/datadog-plugin-jest/src/util.js +8 -8
  122. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +3 -1
  123. package/packages/datadog-plugin-kafkajs/src/consumer.js +9 -5
  124. package/packages/datadog-plugin-kafkajs/src/producer.js +8 -3
  125. package/packages/datadog-plugin-kafkajs/src/utils.js +1 -1
  126. package/packages/datadog-plugin-langchain/src/handlers/chain.js +7 -7
  127. package/packages/datadog-plugin-langchain/src/handlers/embedding.js +2 -2
  128. package/packages/datadog-plugin-langchain/src/handlers/language_models/chat_model.js +6 -4
  129. package/packages/datadog-plugin-langchain/src/handlers/language_models/llm.js +5 -4
  130. package/packages/datadog-plugin-langchain/src/tracing.js +11 -10
  131. package/packages/datadog-plugin-mariadb/src/index.js +3 -9
  132. package/packages/datadog-plugin-mocha/src/index.js +39 -14
  133. package/packages/datadog-plugin-mongodb-core/src/index.js +3 -2
  134. package/packages/datadog-plugin-mysql/src/index.js +22 -9
  135. package/packages/datadog-plugin-mysql2/src/index.js +16 -0
  136. package/packages/datadog-plugin-net/src/tcp.js +1 -1
  137. package/packages/datadog-plugin-next/src/index.js +7 -6
  138. package/packages/datadog-plugin-openai/src/services.js +6 -10
  139. package/packages/datadog-plugin-openai/src/tracing.js +12 -18
  140. package/packages/datadog-plugin-oracledb/src/index.js +1 -1
  141. package/packages/datadog-plugin-playwright/src/index.js +25 -4
  142. package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +8 -9
  143. package/packages/datadog-plugin-redis/src/index.js +2 -4
  144. package/packages/datadog-plugin-rhea/src/consumer.js +8 -6
  145. package/packages/datadog-plugin-rhea/src/producer.js +5 -2
  146. package/packages/datadog-plugin-router/src/index.js +1 -1
  147. package/packages/datadog-plugin-selenium/src/index.js +1 -6
  148. package/packages/datadog-plugin-vitest/src/index.js +52 -35
  149. package/packages/datadog-shimmer/src/shimmer.js +4 -8
  150. package/packages/dd-trace/src/appsec/api_security_sampler.js +2 -2
  151. package/packages/dd-trace/src/appsec/blocked_templates.js +1 -1
  152. package/packages/dd-trace/src/appsec/blocking.js +6 -20
  153. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +0 -1
  154. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +0 -1
  155. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +0 -1
  156. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +0 -1
  157. package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +7 -12
  158. package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +5 -8
  159. package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +4 -0
  160. package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +9 -12
  161. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +5 -4
  162. package/packages/dd-trace/src/appsec/iast/context/context-plugin.js +2 -3
  163. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +3 -3
  164. package/packages/dd-trace/src/appsec/iast/index.js +1 -0
  165. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +102 -7
  166. package/packages/dd-trace/src/appsec/iast/path-line.js +7 -8
  167. package/packages/dd-trace/src/appsec/iast/security-controls/index.js +16 -24
  168. package/packages/dd-trace/src/appsec/iast/security-controls/parser.js +6 -6
  169. package/packages/dd-trace/src/appsec/iast/taint-tracking/filter.js +2 -2
  170. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +3 -3
  171. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +4 -28
  172. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +2 -8
  173. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +3 -4
  174. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -1
  175. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +7 -8
  176. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
  177. package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +7 -7
  178. package/packages/dd-trace/src/appsec/iast/telemetry/verbosity.js +2 -3
  179. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/range-utils.js +10 -11
  180. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +1 -1
  181. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +1 -1
  182. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +7 -7
  183. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +23 -28
  184. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +3 -3
  185. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +4 -4
  186. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +6 -11
  187. package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +0 -1
  188. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +9 -11
  189. package/packages/dd-trace/src/appsec/index.js +5 -5
  190. package/packages/dd-trace/src/appsec/rasp/index.js +15 -15
  191. package/packages/dd-trace/src/appsec/rasp/lfi.js +2 -1
  192. package/packages/dd-trace/src/appsec/reporter.js +232 -41
  193. package/packages/dd-trace/src/appsec/rule_manager.js +2 -2
  194. package/packages/dd-trace/src/appsec/sdk/set_user.js +2 -2
  195. package/packages/dd-trace/src/appsec/sdk/track_event.js +3 -3
  196. package/packages/dd-trace/src/appsec/stack_trace.js +2 -4
  197. package/packages/dd-trace/src/appsec/telemetry/index.js +31 -1
  198. package/packages/dd-trace/src/appsec/telemetry/rasp.js +3 -5
  199. package/packages/dd-trace/src/appsec/telemetry/waf.js +3 -5
  200. package/packages/dd-trace/src/appsec/user_tracking.js +3 -5
  201. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +8 -4
  202. package/packages/dd-trace/src/azure_metadata.js +9 -9
  203. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +9 -8
  204. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +2 -2
  205. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +3 -2
  206. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +3 -3
  207. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +3 -2
  208. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +3 -2
  209. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +3 -2
  210. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +6 -4
  211. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +6 -5
  212. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +7 -6
  213. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +0 -2
  214. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +3 -2
  215. package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +5 -4
  216. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +12 -8
  217. package/packages/dd-trace/src/ci-visibility/telemetry.js +4 -0
  218. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +3 -2
  219. package/packages/dd-trace/src/config-helper.js +89 -0
  220. package/packages/dd-trace/src/config.js +159 -129
  221. package/packages/dd-trace/src/config_stable.js +10 -7
  222. package/packages/dd-trace/src/datastreams/encoding.js +9 -9
  223. package/packages/dd-trace/src/datastreams/fnv.js +2 -2
  224. package/packages/dd-trace/src/datastreams/pathway.js +4 -4
  225. package/packages/dd-trace/src/datastreams/processor.js +5 -7
  226. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +7 -7
  227. package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +4 -6
  228. package/packages/dd-trace/src/datastreams/size.js +1 -1
  229. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +75 -69
  230. package/packages/dd-trace/src/debugger/devtools_client/condition.js +7 -10
  231. package/packages/dd-trace/src/debugger/devtools_client/defaults.js +1 -1
  232. package/packages/dd-trace/src/debugger/devtools_client/index.js +9 -2
  233. package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +18 -38
  234. package/packages/dd-trace/src/debugger/devtools_client/send.js +3 -2
  235. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +1 -2
  236. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +1 -1
  237. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +11 -14
  238. package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +4 -4
  239. package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +2 -10
  240. package/packages/dd-trace/src/debugger/devtools_client/state.js +10 -3
  241. package/packages/dd-trace/src/debugger/index.js +1 -0
  242. package/packages/dd-trace/src/dogstatsd.js +7 -6
  243. package/packages/dd-trace/src/encode/0.4.js +14 -11
  244. package/packages/dd-trace/src/encode/0.5.js +4 -6
  245. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +8 -8
  246. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +1 -1
  247. package/packages/dd-trace/src/encode/tags-processors.js +1 -1
  248. package/packages/dd-trace/src/exporter.js +7 -6
  249. package/packages/dd-trace/src/exporters/agent/writer.js +1 -5
  250. package/packages/dd-trace/src/exporters/common/docker.js +4 -3
  251. package/packages/dd-trace/src/exporters/common/form-data.js +6 -4
  252. package/packages/dd-trace/src/exporters/common/request.js +5 -2
  253. package/packages/dd-trace/src/exporters/common/util.js +4 -2
  254. package/packages/dd-trace/src/external-logger/src/index.js +5 -5
  255. package/packages/dd-trace/src/flare/file.js +1 -5
  256. package/packages/dd-trace/src/format.js +1 -1
  257. package/packages/dd-trace/src/git_properties.js +1 -1
  258. package/packages/dd-trace/src/id.js +15 -9
  259. package/packages/dd-trace/src/iitm.js +10 -22
  260. package/packages/dd-trace/src/index.js +4 -3
  261. package/packages/dd-trace/src/lambda/handler.js +7 -6
  262. package/packages/dd-trace/src/lambda/index.js +2 -1
  263. package/packages/dd-trace/src/lambda/runtime/patch.js +7 -6
  264. package/packages/dd-trace/src/lambda/runtime/ritm.js +4 -3
  265. package/packages/dd-trace/src/llmobs/constants/tags.js +1 -0
  266. package/packages/dd-trace/src/llmobs/index.js +21 -5
  267. package/packages/dd-trace/src/llmobs/noop.js +18 -20
  268. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +6 -6
  269. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +2 -6
  270. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +3 -3
  271. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +11 -13
  272. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +6 -6
  273. package/packages/dd-trace/src/llmobs/plugins/openai.js +2 -3
  274. package/packages/dd-trace/src/llmobs/sdk.js +4 -3
  275. package/packages/dd-trace/src/llmobs/span_processor.js +1 -1
  276. package/packages/dd-trace/src/llmobs/tagger.js +129 -102
  277. package/packages/dd-trace/src/llmobs/util.js +9 -9
  278. package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
  279. package/packages/dd-trace/src/llmobs/writers/util.js +1 -1
  280. package/packages/dd-trace/src/log/index.js +9 -8
  281. package/packages/dd-trace/src/log/log.js +1 -1
  282. package/packages/dd-trace/src/log/writer.js +3 -4
  283. package/packages/dd-trace/src/msgpack/chunk.js +3 -3
  284. package/packages/dd-trace/src/msgpack/encoder.js +31 -31
  285. package/packages/dd-trace/src/noop/dogstatsd.js +6 -6
  286. package/packages/dd-trace/src/noop/span.js +4 -6
  287. package/packages/dd-trace/src/noop/tracer.js +1 -2
  288. package/packages/dd-trace/src/opentelemetry/span_processor.js +2 -2
  289. package/packages/dd-trace/src/opentelemetry/tracer.js +7 -6
  290. package/packages/dd-trace/src/opentracing/propagation/log.js +10 -13
  291. package/packages/dd-trace/src/opentracing/propagation/text_map.js +40 -37
  292. package/packages/dd-trace/src/opentracing/propagation/tracestate.js +8 -4
  293. package/packages/dd-trace/src/opentracing/span.js +16 -20
  294. package/packages/dd-trace/src/opentracing/tracer.js +9 -6
  295. package/packages/dd-trace/src/payload-tagging/config/index.js +17 -21
  296. package/packages/dd-trace/src/payload-tagging/index.js +1 -1
  297. package/packages/dd-trace/src/payload-tagging/tagging.js +6 -6
  298. package/packages/dd-trace/src/pkg.js +1 -1
  299. package/packages/dd-trace/src/plugin_manager.js +4 -3
  300. package/packages/dd-trace/src/plugins/ci_plugin.js +87 -11
  301. package/packages/dd-trace/src/plugins/consumer.js +2 -2
  302. package/packages/dd-trace/src/plugins/inbound.js +5 -1
  303. package/packages/dd-trace/src/plugins/index.js +0 -1
  304. package/packages/dd-trace/src/plugins/outbound.js +4 -5
  305. package/packages/dd-trace/src/plugins/plugin.js +1 -1
  306. package/packages/dd-trace/src/plugins/producer.js +2 -2
  307. package/packages/dd-trace/src/plugins/storage.js +2 -2
  308. package/packages/dd-trace/src/plugins/util/ci.js +28 -20
  309. package/packages/dd-trace/src/plugins/util/git.js +166 -12
  310. package/packages/dd-trace/src/plugins/util/inferred_proxy.js +1 -1
  311. package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
  312. package/packages/dd-trace/src/plugins/util/llm.js +27 -10
  313. package/packages/dd-trace/src/plugins/util/stacktrace.js +9 -2
  314. package/packages/dd-trace/src/plugins/util/test.js +315 -51
  315. package/packages/dd-trace/src/plugins/util/url.js +1 -1
  316. package/packages/dd-trace/src/plugins/util/urlfilter.js +13 -17
  317. package/packages/dd-trace/src/plugins/util/user-provided-git.js +14 -4
  318. package/packages/dd-trace/src/plugins/util/web.js +8 -8
  319. package/packages/dd-trace/src/priority_sampler.js +64 -53
  320. package/packages/dd-trace/src/profiling/config.js +51 -35
  321. package/packages/dd-trace/src/profiling/exporter_cli.js +20 -20
  322. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  323. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +7 -6
  324. package/packages/dd-trace/src/profiling/exporters/file.js +2 -1
  325. package/packages/dd-trace/src/profiling/index.js +2 -1
  326. package/packages/dd-trace/src/profiling/profiler.js +44 -6
  327. package/packages/dd-trace/src/profiling/profilers/events.js +14 -17
  328. package/packages/dd-trace/src/profiling/profilers/shared.js +6 -1
  329. package/packages/dd-trace/src/profiling/profilers/space.js +3 -3
  330. package/packages/dd-trace/src/profiling/profilers/wall.js +6 -7
  331. package/packages/dd-trace/src/profiling/ssi-heuristics.js +3 -5
  332. package/packages/dd-trace/src/profiling/ssi-telemetry-mock-profiler.js +3 -1
  333. package/packages/dd-trace/src/profiling/tagger.js +21 -13
  334. package/packages/dd-trace/src/profiling/webspan-utils.js +1 -1
  335. package/packages/dd-trace/src/proxy.js +9 -10
  336. package/packages/dd-trace/src/random_sampler.js +40 -0
  337. package/packages/dd-trace/src/rate_limiter.js +4 -4
  338. package/packages/dd-trace/src/remote_config/index.js +3 -7
  339. package/packages/dd-trace/src/remote_config/manager.js +25 -13
  340. package/packages/dd-trace/src/require-package-json.js +1 -1
  341. package/packages/dd-trace/src/ritm.js +8 -8
  342. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -4
  343. package/packages/dd-trace/src/sampler.js +41 -4
  344. package/packages/dd-trace/src/sampling_rule.js +12 -3
  345. package/packages/dd-trace/src/scope.js +1 -1
  346. package/packages/dd-trace/src/serverless.js +11 -4
  347. package/packages/dd-trace/src/service-naming/schemas/util.js +1 -1
  348. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +2 -3
  349. package/packages/dd-trace/src/span_processor.js +5 -4
  350. package/packages/dd-trace/src/span_sampler.js +4 -1
  351. package/packages/dd-trace/src/standalone/tracesource.js +2 -3
  352. package/packages/dd-trace/src/standalone/tracesource_priority_sampler.js +1 -2
  353. package/packages/dd-trace/src/startup-log.js +6 -18
  354. package/packages/dd-trace/src/supported-configurations.json +439 -0
  355. package/packages/dd-trace/src/telemetry/dependencies.js +64 -59
  356. package/packages/dd-trace/src/telemetry/logs/log-collector.js +9 -10
  357. package/packages/dd-trace/src/telemetry/metrics.js +10 -5
  358. package/packages/dd-trace/src/telemetry/send-data.js +8 -7
  359. package/packages/dd-trace/src/telemetry/telemetry.js +31 -45
  360. package/packages/dd-trace/src/tracer.js +3 -7
  361. package/packages/dd-trace/src/util.js +1 -6
  362. package/version.js +1 -0
  363. package/packages/datadog-instrumentations/src/paperplane.js +0 -77
  364. package/packages/datadog-plugin-paperplane/src/index.js +0 -25
  365. package/packages/datadog-plugin-paperplane/src/logger.js +0 -11
  366. package/packages/datadog-plugin-paperplane/src/server.js +0 -24
  367. package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +0 -122
  368. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/header-sensitive-analyzer.js +0 -20
@@ -5,7 +5,6 @@ const RateLimiter = require('./rate_limiter')
5
5
  const Sampler = require('./sampler')
6
6
  const { setSamplingRules } = require('./startup-log')
7
7
  const SamplingRule = require('./sampling_rule')
8
- const { hasOwn } = require('./util')
9
8
 
10
9
  const {
11
10
  SAMPLING_MECHANISM_DEFAULT,
@@ -40,16 +39,28 @@ const DEFAULT_KEY = 'service:,env:'
40
39
  const defaultSampler = new Sampler(AUTO_KEEP)
41
40
 
42
41
  /**
43
- * from config.js
44
- * @typedef { sampleRate: number, provenance: string, rateLimit: number, rules: SamplingRule[] } SamplingConfig
42
+ * PrioritySampler is responsible for determining whether a span should be sampled
43
+ * based on various rules, rate limits, and priorities. It supports manual and
44
+ * automatic sampling mechanisms and integrates with Datadog's tracing system.
45
45
  *
46
- * empirically defined
47
- * @typedef {2|-1|1|0} SamplingPriority
46
+ * @class PrioritySampler
47
+ * @typedef {import('./opentracing/span')} DatadogSpan
48
+ * @typedef {import('./opentracing/span_context')} DatadogSpanContext
49
+ * @typedef {import('./standalone/product')} PRODUCTS
50
+ * @typedef {2|-1|1|0} SamplingPriority Empirically defined sampling priorities.
48
51
  */
49
52
  class PrioritySampler {
50
53
  /**
51
- * @param env {string}
52
- * @param config {SamplingConfig}
54
+ * Creates an instance of PrioritySampler.
55
+ *
56
+ * @typedef {Object} SamplingConfig
57
+ * @property {number} [sampleRate] - The default sample rate for traces.
58
+ * @property {string} [provenance] - The provenance of the sampling rule (e.g., "customer", "dynamic").
59
+ * @property {number} [rateLimit=100] - The maximum number of traces to sample per second.
60
+ * @property {Array<SamplingRule>} [rules=[]] - An array of sampling rules to apply.
61
+ *
62
+ * @param {string} env - The environment name (e.g., "production", "staging").
63
+ * @param {SamplingConfig} config - The configuration object for sampling.
53
64
  */
54
65
  constructor (env, config) {
55
66
  this.configure(env, config)
@@ -62,9 +73,9 @@ class PrioritySampler {
62
73
  * @param opts {SamplingConfig}
63
74
  */
64
75
  configure (env, opts = {}) {
65
- const { sampleRate, provenance = undefined, rateLimit = 100, rules = [] } = opts
76
+ const { sampleRate, provenance, rateLimit = 100, rules } = opts
66
77
  this._env = env
67
- this._rules = this.#_normalizeRules(rules, sampleRate, rateLimit, provenance)
78
+ this._rules = this.#normalizeRules(rules || [], sampleRate, rateLimit, provenance)
68
79
  this._limiter = new RateLimiter(rateLimit)
69
80
 
70
81
  log.trace(env, opts)
@@ -110,7 +121,7 @@ class PrioritySampler {
110
121
  return
111
122
  }
112
123
 
113
- this.#_addDecisionMaker(root)
124
+ this.#addDecisionMaker(root)
114
125
  }
115
126
 
116
127
  /**
@@ -154,7 +165,7 @@ class PrioritySampler {
154
165
  *
155
166
  * @param span {DatadogSpan}
156
167
  * @param samplingPriority {SamplingPriority}
157
- * @param product {import('./standalone/product').PRODUCTS}
168
+ * @param product {import('./standalone/product')}
158
169
  */
159
170
  setPriority (span, samplingPriority, product) {
160
171
  if (!span || !this.validate(samplingPriority)) return
@@ -174,7 +185,7 @@ class PrioritySampler {
174
185
 
175
186
  log.trace(span, samplingPriority, mechanism)
176
187
 
177
- this.#_addDecisionMaker(root)
188
+ this.#addDecisionMaker(root)
178
189
  }
179
190
 
180
191
  /**
@@ -193,11 +204,11 @@ class PrioritySampler {
193
204
  */
194
205
  _getPriorityFromAuto (span) {
195
206
  const context = this._getContext(span)
196
- const rule = this.#_findRule(span)
207
+ const rule = this.#findRule(span)
197
208
 
198
209
  return rule
199
- ? this.#_getPriorityByRule(context, rule)
200
- : this.#_getPriorityByAgent(context)
210
+ ? this.#getPriorityByRule(context, rule)
211
+ : this.#getPriorityByAgent(context)
201
212
  }
202
213
 
203
214
  /**
@@ -208,18 +219,17 @@ class PrioritySampler {
208
219
  * @returns {SamplingPriority}
209
220
  */
210
221
  _getPriorityFromTags (tags, _context) {
211
- if (hasOwn(tags, MANUAL_KEEP) && tags[MANUAL_KEEP] !== false) {
222
+ if (Object.hasOwn(tags, MANUAL_KEEP) && tags[MANUAL_KEEP] !== false) {
212
223
  return USER_KEEP
213
- } else if (hasOwn(tags, MANUAL_DROP) && tags[MANUAL_DROP] !== false) {
224
+ } else if (Object.hasOwn(tags, MANUAL_DROP) && tags[MANUAL_DROP] !== false) {
214
225
  return USER_REJECT
215
- } else {
216
- const priority = parseInt(tags[SAMPLING_PRIORITY], 10)
226
+ }
227
+ const priority = Number.parseInt(tags[SAMPLING_PRIORITY], 10)
217
228
 
218
- if (priority === 1 || priority === 2) {
219
- return USER_KEEP
220
- } else if (priority === 0 || priority === -1) {
221
- return USER_REJECT
222
- }
229
+ if (priority === 1 || priority === 2) {
230
+ return USER_KEEP
231
+ } else if (priority === 0 || priority === -1) {
232
+ return USER_REJECT
223
233
  }
224
234
  }
225
235
 
@@ -229,13 +239,13 @@ class PrioritySampler {
229
239
  * @param rule {SamplingRule}
230
240
  * @returns {SamplingPriority}
231
241
  */
232
- #_getPriorityByRule (context, rule) {
242
+ #getPriorityByRule (context, rule) {
233
243
  context._trace[SAMPLING_RULE_DECISION] = rule.sampleRate
234
244
  context._sampling.mechanism = SAMPLING_MECHANISM_RULE
235
245
  if (rule.provenance === 'customer') context._sampling.mechanism = SAMPLING_MECHANISM_REMOTE_USER
236
246
  if (rule.provenance === 'dynamic') context._sampling.mechanism = SAMPLING_MECHANISM_REMOTE_DYNAMIC
237
247
 
238
- return rule.sample() && this._isSampledByRateLimit(context)
248
+ return rule.sample(context) && this._isSampledByRateLimit(context)
239
249
  ? USER_KEEP
240
250
  : USER_REJECT
241
251
  }
@@ -258,19 +268,14 @@ class PrioritySampler {
258
268
  *
259
269
  * @param context {DatadogSpanContext}
260
270
  * @returns {SamplingPriority}
261
- * @private
262
271
  */
263
- #_getPriorityByAgent (context) {
272
+ #getPriorityByAgent (context) {
264
273
  const key = `service:${context._tags[SERVICE_NAME]},env:${this._env}`
265
274
  const sampler = this._samplers[key] || this._samplers[DEFAULT_KEY]
266
275
 
267
276
  context._trace[SAMPLING_AGENT_DECISION] = sampler.rate()
268
277
 
269
- if (sampler === defaultSampler) {
270
- context._sampling.mechanism = SAMPLING_MECHANISM_DEFAULT
271
- } else {
272
- context._sampling.mechanism = SAMPLING_MECHANISM_AGENT
273
- }
278
+ context._sampling.mechanism = sampler === defaultSampler ? SAMPLING_MECHANISM_DEFAULT : SAMPLING_MECHANISM_AGENT
274
279
 
275
280
  return sampler.isSampled(context) ? AUTO_KEEP : AUTO_REJECT
276
281
  }
@@ -278,10 +283,9 @@ class PrioritySampler {
278
283
  /**
279
284
  *
280
285
  * @param span {DatadogSpan}
281
- * @private
282
286
  * @returns {void}
283
287
  */
284
- #_addDecisionMaker (span) {
288
+ #addDecisionMaker (span) {
285
289
  const context = span.context()
286
290
  const trace = context._trace
287
291
  const priority = context._sampling.priority
@@ -297,32 +301,39 @@ class PrioritySampler {
297
301
  }
298
302
 
299
303
  /**
300
- *
301
- * @param rules {SamplingRule[]}
302
- * @param sampleRate {number}
303
- * @param rateLimit {number}
304
- * @param provenance {string}
304
+ * @param {Record<string, unknown>[] | Record<string, unknown>} rules - The sampling rules to normalize.
305
+ * @param {number} sampleRate
306
+ * @param {number} rateLimit
307
+ * @param {string} provenance
305
308
  * @returns {SamplingRule[]}
306
- * @private
307
309
  */
308
- #_normalizeRules (rules, sampleRate, rateLimit, provenance) {
309
- rules = [].concat(rules || [])
310
-
311
- return rules
312
- .concat({ sampleRate, maxPerSecond: rateLimit, provenance })
313
- .map(rule => ({ ...rule, sampleRate: parseFloat(rule.sampleRate) }))
314
- .filter(rule => !isNaN(rule.sampleRate))
315
- .map(SamplingRule.from)
310
+ #normalizeRules (rules, sampleRate, rateLimit, provenance) {
311
+ rules = Array.isArray(rules) ? rules.flat() : [rules]
312
+
313
+ rules.push({ sampleRate, maxPerSecond: rateLimit, provenance })
314
+
315
+ const result = []
316
+ for (const rule of rules) {
317
+ const sampleRate = Number.parseFloat(rule.sampleRate)
318
+ // TODO(BridgeAR): Debug logging invalid rules fails our tests.
319
+ // Should we definitely not know about these?
320
+ if (!Number.isNaN(sampleRate)) {
321
+ result.push(SamplingRule.from({ ...rule, sampleRate }))
322
+ }
323
+ }
324
+ return result
316
325
  }
317
326
 
318
327
  /**
319
328
  *
320
329
  * @param span {DatadogSpan}
321
- * @returns {SamplingRule}
322
- * @private
330
+ * @returns {SamplingRule|undefined}
323
331
  */
324
- #_findRule (span) {
332
+ #findRule (span) {
325
333
  for (const rule of this._rules) {
334
+ // Rule is a special object with a .match() property.
335
+ // It has nothing to do with a regular expression.
336
+ // eslint-disable-next-line unicorn/prefer-regexp-test
326
337
  if (rule.match(span)) return rule
327
338
  }
328
339
  }
@@ -330,7 +341,7 @@ class PrioritySampler {
330
341
  /**
331
342
  *
332
343
  * @param span {DatadogSpan}
333
- * @param product {import('./standalone/product').PRODUCTS}
344
+ * @param product {import('./standalone/product')}
334
345
  */
335
346
  static keepTrace (span, product) {
336
347
  span?._prioritySampler?.setPriority(span, USER_KEEP, product)
@@ -15,26 +15,26 @@ const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../plugins/util/tags')
15
15
  const { tagger } = require('./tagger')
16
16
  const { isFalse, isTrue } = require('../util')
17
17
  const { getAzureTagsFromMetadata, getAzureAppMetadata } = require('../azure_metadata')
18
+ const { getEnvironmentVariables } = require('../config-helper')
18
19
 
19
20
  class Config {
20
21
  constructor (options = {}) {
21
22
  const {
23
+ AWS_LAMBDA_FUNCTION_NAME: functionname,
22
24
  DD_AGENT_HOST,
23
25
  DD_ENV,
24
26
  DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED, // used for testing
25
27
  DD_PROFILING_CODEHOTSPOTS_ENABLED,
26
28
  DD_PROFILING_CPU_ENABLED,
27
29
  DD_PROFILING_DEBUG_SOURCE_MAPS,
30
+ DD_PROFILING_DEBUG_UPLOAD_COMPRESSION,
28
31
  DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,
29
- DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED,
30
- DD_PROFILING_EXPERIMENTAL_CPU_ENABLED,
31
- DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED,
32
32
  DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES,
33
33
  DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE,
34
34
  DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT,
35
35
  DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED,
36
- DD_PROFILING_EXPERIMENTAL_TIMELINE_ENABLED,
37
36
  DD_PROFILING_HEAP_ENABLED,
37
+ DD_PROFILING_HEAP_SAMPLING_INTERVAL,
38
38
  DD_PROFILING_PPROF_PREFIX,
39
39
  DD_PROFILING_PROFILERS,
40
40
  DD_PROFILING_SOURCE_MAP,
@@ -48,13 +48,12 @@ class Config {
48
48
  DD_TRACE_AGENT_PORT,
49
49
  DD_TRACE_AGENT_URL,
50
50
  DD_VERSION
51
- } = process.env
51
+ } = getEnvironmentVariables()
52
52
 
53
53
  const env = coalesce(options.env, DD_ENV)
54
54
  const service = options.service || DD_SERVICE || 'node'
55
55
  const host = os.hostname()
56
56
  const version = coalesce(options.version, DD_VERSION)
57
- const functionname = process.env.AWS_LAMBDA_FUNCTION_NAME
58
57
  // Must be longer than one minute so pad with five seconds
59
58
  const flushInterval = coalesce(options.interval, Number(DD_PROFILING_UPLOAD_PERIOD) * 1000, 65 * 1000)
60
59
  const uploadTimeout = coalesce(options.uploadTimeout,
@@ -84,16 +83,6 @@ class Config {
84
83
  }
85
84
 
86
85
  this.logger = ensureLogger(options.logger)
87
- const logger = this.logger
88
- function logExperimentalVarDeprecation (shortVarName) {
89
- const deprecatedEnvVarName = `DD_PROFILING_EXPERIMENTAL_${shortVarName}`
90
- const v = process.env[deprecatedEnvVarName]
91
- // not null, undefined, or NaN -- same logic as koalas.hasValue
92
- // eslint-disable-next-line no-self-compare
93
- if (v != null && v === v) {
94
- logger.warn(`${deprecatedEnvVarName} is deprecated. Use DD_PROFILING_${shortVarName} instead.`)
95
- }
96
- }
97
86
  // Profiler sampling contexts are not available on Windows, so features
98
87
  // depending on those (code hotspots and endpoint collection) need to default
99
88
  // to false on Windows.
@@ -117,9 +106,7 @@ class Config {
117
106
  this.sourceMap = sourceMap
118
107
  this.debugSourceMaps = isTrue(coalesce(options.debugSourceMaps, DD_PROFILING_DEBUG_SOURCE_MAPS, false))
119
108
  this.endpointCollectionEnabled = isTrue(coalesce(options.endpointCollection,
120
- DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,
121
- DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED, samplingContextsAvailable))
122
- logExperimentalVarDeprecation('ENDPOINT_COLLECTION_ENABLED')
109
+ DD_PROFILING_ENDPOINT_COLLECTION_ENABLED, samplingContextsAvailable))
123
110
  checkOptionWithSamplingContextAllowed(this.endpointCollectionEnabled, 'Endpoint collection')
124
111
 
125
112
  this.pprofPrefix = pprofPrefix
@@ -163,34 +150,63 @@ class Config {
163
150
  exportCommand
164
151
  }
165
152
 
166
- const profilers = options.profilers
167
- ? options.profilers
168
- : getProfilers({
169
- DD_PROFILING_HEAP_ENABLED,
170
- DD_PROFILING_WALLTIME_ENABLED,
171
- DD_PROFILING_PROFILERS
172
- })
153
+ const profilers = options.profilers || getProfilers({
154
+ DD_PROFILING_HEAP_ENABLED,
155
+ DD_PROFILING_WALLTIME_ENABLED,
156
+ DD_PROFILING_PROFILERS
157
+ })
173
158
 
174
159
  this.timelineEnabled = isTrue(coalesce(options.timelineEnabled,
175
- DD_PROFILING_TIMELINE_ENABLED,
176
- DD_PROFILING_EXPERIMENTAL_TIMELINE_ENABLED, samplingContextsAvailable))
177
- logExperimentalVarDeprecation('TIMELINE_ENABLED')
160
+ DD_PROFILING_TIMELINE_ENABLED, samplingContextsAvailable))
178
161
  checkOptionWithSamplingContextAllowed(this.timelineEnabled, 'Timeline view')
179
162
  this.timelineSamplingEnabled = isTrue(coalesce(options.timelineSamplingEnabled,
180
163
  DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED, true))
181
164
 
182
165
  this.codeHotspotsEnabled = isTrue(coalesce(options.codeHotspotsEnabled,
183
- DD_PROFILING_CODEHOTSPOTS_ENABLED,
184
- DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED, samplingContextsAvailable))
185
- logExperimentalVarDeprecation('CODEHOTSPOTS_ENABLED')
166
+ DD_PROFILING_CODEHOTSPOTS_ENABLED, samplingContextsAvailable))
186
167
  checkOptionWithSamplingContextAllowed(this.codeHotspotsEnabled, 'Code hotspots')
187
168
 
188
169
  this.cpuProfilingEnabled = isTrue(coalesce(options.cpuProfilingEnabled,
189
170
  DD_PROFILING_CPU_ENABLED,
190
- DD_PROFILING_EXPERIMENTAL_CPU_ENABLED, samplingContextsAvailable))
191
- logExperimentalVarDeprecation('CPU_ENABLED')
171
+ samplingContextsAvailable))
192
172
  checkOptionWithSamplingContextAllowed(this.cpuProfilingEnabled, 'CPU profiling')
193
173
 
174
+ this.heapSamplingInterval = coalesce(options.heapSamplingInterval,
175
+ Number(DD_PROFILING_HEAP_SAMPLING_INTERVAL))
176
+ const uploadCompression0 = coalesce(options.uploadCompression, DD_PROFILING_DEBUG_UPLOAD_COMPRESSION, 'on')
177
+ let [uploadCompression, level0] = uploadCompression0.split('-')
178
+ if (!['on', 'off', 'gzip', 'zstd'].includes(uploadCompression)) {
179
+ this.logger.warn(`Invalid profile upload compression method "${uploadCompression0}". Will use "on".`)
180
+ uploadCompression = 'on'
181
+ }
182
+ let level = level0 ? Number.parseInt(level0, 10) : undefined
183
+ if (level !== undefined) {
184
+ if (['on', 'off'].includes(uploadCompression)) {
185
+ this.logger.warn(`Compression levels are not supported for "${uploadCompression}".`)
186
+ level = undefined
187
+ } else if (Number.isNaN(level)) {
188
+ this.logger.warn(
189
+ `Invalid compression level "${level0}". Will use default level.`)
190
+ level = undefined
191
+ } else if (level < 1) {
192
+ this.logger.warn(`Invalid compression level ${level}. Will use 1.`)
193
+ level = 1
194
+ } else {
195
+ const maxLevel = { gzip: 9, zstd: 22 }[uploadCompression]
196
+ if (level > maxLevel) {
197
+ this.logger.warn(`Invalid compression level ${level}. Will use ${maxLevel}.`)
198
+ level = maxLevel
199
+ }
200
+ }
201
+ }
202
+
203
+ // Default to gzip
204
+ if (uploadCompression === 'on') {
205
+ uploadCompression = 'gzip'
206
+ }
207
+
208
+ this.uploadCompression = { method: uploadCompression, level }
209
+
194
210
  this.profilers = ensureProfilers(profilers, this)
195
211
  }
196
212
  }
@@ -307,7 +323,7 @@ function ensureProfilers (profilers, options) {
307
323
  }
308
324
 
309
325
  // Filter out any invalid profilers
310
- return profilers.filter(v => v)
326
+ return profilers.filter(Boolean)
311
327
  }
312
328
 
313
329
  function ensureLogger (logger) {
@@ -8,6 +8,7 @@ const { ConsoleLogger } = require('./loggers/console')
8
8
  const { tagger } = require('./tagger')
9
9
  const fs = require('fs')
10
10
  const { fileURLToPath } = require('url')
11
+ const { getEnvironmentVariable } = require('../config-helper')
11
12
 
12
13
  const logger = new ConsoleLogger()
13
14
  const timeoutMs = 15 * 1000
@@ -15,25 +16,24 @@ const timeoutMs = 15 * 1000
15
16
  function exporterFromURL (url) {
16
17
  if (url.protocol === 'file:') {
17
18
  return new FileExporter({ pprofPrefix: fileURLToPath(url) })
18
- } else {
19
- const injectionEnabled = (process.env.DD_INJECTION_ENABLED || '').split(',')
20
- const libraryInjected = injectionEnabled.length > 0
21
- const profilingEnabled = (process.env.DD_PROFILING_ENABLED || '').toLowerCase()
22
- const activation = ['true', '1'].includes(profilingEnabled)
23
- ? 'manual'
24
- : profilingEnabled === 'auto'
25
- ? 'auto'
26
- : injectionEnabled.includes('profiling')
27
- ? 'injection'
28
- : 'unknown'
29
- return new AgentExporter({
30
- url,
31
- logger,
32
- uploadTimeout: timeoutMs,
33
- libraryInjected,
34
- activation
35
- })
36
19
  }
20
+ const injectionEnabled = (getEnvironmentVariable('DD_INJECTION_ENABLED') ?? '').split(',')
21
+ const libraryInjected = injectionEnabled.length > 0
22
+ const profilingEnabled = (getEnvironmentVariable('DD_PROFILING_ENABLED') ?? '').toLowerCase()
23
+ const activation = ['true', '1'].includes(profilingEnabled)
24
+ ? 'manual'
25
+ : profilingEnabled === 'auto'
26
+ ? 'auto'
27
+ : injectionEnabled.includes('profiling')
28
+ ? 'injection'
29
+ : 'unknown'
30
+ return new AgentExporter({
31
+ url,
32
+ logger,
33
+ uploadTimeout: timeoutMs,
34
+ libraryInjected,
35
+ activation
36
+ })
37
37
  }
38
38
 
39
39
  async function exportProfile (urls, tags, profileType, profile) {
@@ -46,7 +46,7 @@ async function exportProfile (urls, tags, profileType, profile) {
46
46
 
47
47
  const encodedProfile = await encode(heap.convertProfile(profile, undefined, mapper))
48
48
  const start = new Date()
49
- for (const url of urls) {
49
+ await Promise.all(urls.map(async (url) => {
50
50
  const exporter = exporterFromURL(url)
51
51
 
52
52
  await exporter.export({
@@ -57,7 +57,7 @@ async function exportProfile (urls, tags, profileType, profile) {
57
57
  end: start,
58
58
  tags
59
59
  })
60
- }
60
+ }))
61
61
  }
62
62
 
63
63
  /** Expected command line arguments are:
@@ -150,7 +150,7 @@ class AgentExporter extends EventSerializer {
150
150
  'DD-EVP-ORIGIN-VERSION': version,
151
151
  ...form.getHeaders()
152
152
  },
153
- timeout: this._backoffTime * Math.pow(2, attempt)
153
+ timeout: this._backoffTime * 2 ** attempt
154
154
  }
155
155
 
156
156
  docker.inject(options.headers)
@@ -1,21 +1,22 @@
1
1
  const os = require('os')
2
2
  const perf = require('perf_hooks').performance
3
3
  const version = require('../../../../../package.json').version
4
+ const { getEnvironmentVariable } = require('../../config-helper')
4
5
 
5
6
  const libuvThreadPoolSize = (() => {
6
- const ss = process.env.UV_THREADPOOL_SIZE
7
+ const ss = getEnvironmentVariable('UV_THREADPOOL_SIZE')
7
8
  if (ss === undefined) {
8
9
  // Backend will apply the default size based on Node version.
9
- return undefined
10
+ return
10
11
  }
11
12
  // libuv uses atoi to parse the value, which is almost the same as parseInt, except that parseInt
12
13
  // will return NaN on invalid input, while atoi will return 0. This is handled at return.
13
- const s = parseInt(ss)
14
- // We dont' interpret the value further here in the library. Backend will interpret the number
14
+ const s = Number.parseInt(ss)
15
+ // We don't interpret the value further here in the library. Backend will interpret the number
15
16
  // based on Node version. In all currently known Node versions, 0 results in 1 worker thread,
16
17
  // negative values (because they're assigned to an unsigned int) become very high positive values,
17
18
  // and the value is finally capped at 1024.
18
- return isNaN(s) ? 0 : s
19
+ return Number.isNaN(s) ? 0 : s
19
20
  })()
20
21
 
21
22
  class EventSerializer {
@@ -87,7 +88,7 @@ class EventSerializer {
87
88
  // We'll keep it like this as we want cross-engine consistency. We
88
89
  // also aren't changing the format of the existing tag as we don't want
89
90
  // to break it.
90
- version: process.version.substring(1)
91
+ version: process.version.slice(1)
91
92
  }
92
93
  }
93
94
  })
@@ -6,8 +6,9 @@ const { threadId } = require('worker_threads')
6
6
  const writeFile = promisify(fs.writeFile)
7
7
  const { EventSerializer } = require('./event_serializer')
8
8
 
9
+ const pad = (n) => String(n).padStart(2, '0')
10
+
9
11
  function formatDateTime (t) {
10
- const pad = (n) => String(n).padStart(2, '0')
11
12
  return `${t.getUTCFullYear()}${pad(t.getUTCMonth() + 1)}${pad(t.getUTCDate())}` +
12
13
  `T${pad(t.getUTCHours())}${pad(t.getUTCMinutes())}${pad(t.getUTCSeconds())}Z`
13
14
  }
@@ -6,8 +6,9 @@ const SpaceProfiler = require('./profilers/space')
6
6
  const { AgentExporter } = require('./exporters/agent')
7
7
  const { FileExporter } = require('./exporters/file')
8
8
  const { ConsoleLogger } = require('./loggers/console')
9
+ const { getEnvironmentVariable } = require('../config-helper')
9
10
 
10
- const profiler = process.env.AWS_LAMBDA_FUNCTION_NAME ? new ServerlessProfiler() : new Profiler()
11
+ const profiler = getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME') ? new ServerlessProfiler() : new Profiler()
11
12
 
12
13
  module.exports = {
13
14
  profiler,
@@ -8,6 +8,9 @@ const { isWebServerSpan, endpointNameFromTags, getStartedSpans } = require('./we
8
8
  const dc = require('dc-polyfill')
9
9
  const crashtracker = require('../crashtracking')
10
10
 
11
+ const { promisify } = require('util')
12
+ const zlib = require('zlib')
13
+
11
14
  const profileSubmittedChannel = dc.channel('datadog:profiling:profile-submitted')
12
15
  const spanFinishedChannel = dc.channel('dd-trace:span:finish')
13
16
 
@@ -83,9 +86,37 @@ class Profiler extends EventEmitter {
83
86
  this._logger.debug(() => {
84
87
  return mapper.infoMap.size === 0
85
88
  ? 'Found no source maps'
86
- : `Found source maps for following files: [${Array.from(mapper.infoMap.keys()).join(', ')}]`
89
+ : `Found source maps for following files: [${[...mapper.infoMap.keys()].join(', ')}]`
87
90
  })
88
91
  }
92
+
93
+ const clevel = config.uploadCompression.level
94
+ switch (config.uploadCompression.method) {
95
+ case 'gzip':
96
+ this._compressionFn = promisify(zlib.gzip)
97
+ if (clevel !== undefined) {
98
+ this._compressionOptions = {
99
+ level: clevel
100
+ }
101
+ }
102
+ break
103
+ case 'zstd':
104
+ if (typeof zlib.zstdCompress === 'function') {
105
+ this._compressionFn = promisify(zlib.zstdCompress)
106
+ if (clevel !== undefined) {
107
+ this._compressionOptions = {
108
+ params: {
109
+ [zlib.constants.ZSTD_c_compressionLevel]: clevel
110
+ }
111
+ }
112
+ }
113
+ } else {
114
+ const zstdCompress = require('@datadog/libdatadog').load('datadog-js-zstd').zstd_compress
115
+ const level = clevel ?? 0 // 0 is zstd default compression level
116
+ this._compressionFn = (buffer) => Promise.resolve(Buffer.from(zstdCompress(buffer, level)))
117
+ }
118
+ break
119
+ }
89
120
  } catch (err) {
90
121
  this._logError(err)
91
122
  }
@@ -195,7 +226,7 @@ class Profiler extends EventEmitter {
195
226
  const encodedProfiles = {}
196
227
 
197
228
  try {
198
- if (Object.keys(this._config.profilers).length === 0) {
229
+ if (this._config.profilers.length === 0) {
199
230
  throw new Error('No profile types configured.')
200
231
  }
201
232
 
@@ -215,24 +246,31 @@ class Profiler extends EventEmitter {
215
246
  this._capture(this._timeoutInterval, endDate)
216
247
  }
217
248
 
249
+ let hasEncoded = false
250
+
218
251
  // encode and export asynchronously
219
- for (const { profiler, profile } of profiles) {
252
+ await Promise.all(profiles.map(async ({ profiler, profile }) => {
220
253
  try {
221
- encodedProfiles[profiler.type] = await profiler.encode(profile)
254
+ const encoded = await profiler.encode(profile)
255
+ const compressed = encoded instanceof Buffer && this._compressionFn !== undefined
256
+ ? await this._compressionFn(encoded, this._compressionOptions)
257
+ : encoded
258
+ encodedProfiles[profiler.type] = compressed
222
259
  this._logger.debug(() => {
223
260
  const profileJson = JSON.stringify(profile, (key, value) => {
224
261
  return typeof value === 'bigint' ? value.toString() : value
225
262
  })
226
263
  return `Collected ${profiler.type} profile: ` + profileJson
227
264
  })
265
+ hasEncoded = true
228
266
  } catch (err) {
229
267
  // If encoding one of the profile types fails, we should still try to
230
268
  // encode and submit the other profile types.
231
269
  this._logError(err)
232
270
  }
233
- }
271
+ }))
234
272
 
235
- if (Object.keys(encodedProfiles).length > 0) {
273
+ if (hasEncoded) {
236
274
  await this._submit(encodedProfiles, startDate, endDate, snapshotKind)
237
275
  profileSubmittedChannel.publish()
238
276
  this._logger.debug('Submitted profiles')