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
@@ -1,10 +1,9 @@
1
1
  const { performance, constants, PerformanceObserver } = require('perf_hooks')
2
- const { END_TIMESTAMP_LABEL, SPAN_ID_LABEL, LOCAL_ROOT_SPAN_ID_LABEL } = require('./shared')
2
+ const { END_TIMESTAMP_LABEL, SPAN_ID_LABEL, LOCAL_ROOT_SPAN_ID_LABEL, encodeProfileAsync } = require('./shared')
3
3
  const { Function, Label, Line, Location, Profile, Sample, StringTable, ValueType } = require('pprof-format')
4
- const pprof = require('@datadog/pprof/')
5
4
 
6
5
  // perf_hooks uses millis, with fractional part representing nanos. We emit nanos into the pprof file.
7
- const MS_TO_NS = 1000000
6
+ const MS_TO_NS = 1_000_000
8
7
 
9
8
  // While this is an "events profiler", meaning it emits a pprof file based on events observed as
10
9
  // perf_hooks events, the emitted pprof file uses the type "timeline".
@@ -50,10 +49,10 @@ class GCDecorator {
50
49
  // Create labels for all GC performance flags and kinds of GC
51
50
  for (const [key, value] of Object.entries(constants)) {
52
51
  if (key.startsWith('NODE_PERFORMANCE_GC_FLAGS_')) {
53
- this.flagObj[key.substring(26).toLowerCase()] = value
52
+ this.flagObj[key.slice(26).toLowerCase()] = value
54
53
  } else if (key.startsWith('NODE_PERFORMANCE_GC_')) {
55
54
  // It's a constant for a kind of GC
56
- const kind = key.substring(20).toLowerCase()
55
+ const kind = key.slice(20).toLowerCase()
57
56
  this.kindLabels[value] = labelFromStr(stringTable, kindLabelKey, kind)
58
57
  }
59
58
  }
@@ -258,6 +257,12 @@ class EventSerializer {
258
257
  }
259
258
  }
260
259
 
260
+ function add (items) {
261
+ for (const item of items.getEntries()) {
262
+ this.eventHandler(item)
263
+ }
264
+ }
265
+
261
266
  /**
262
267
  * Class that sources timeline events through Node.js performance measurement APIs.
263
268
  */
@@ -272,12 +277,6 @@ class NodeApiEventSource {
272
277
  // if already started, do nothing
273
278
  if (this.observer) return
274
279
 
275
- function add (items) {
276
- for (const item of items.getEntries()) {
277
- this.eventHandler(item)
278
- }
279
- }
280
-
281
280
  this.observer = new PerformanceObserver(add.bind(this))
282
281
  this.observer.observe({ entryTypes: this.entryTypes })
283
282
  }
@@ -381,17 +380,15 @@ class EventsProfiler {
381
380
  }
382
381
  }
383
382
 
384
- if (options.codeHotspotsEnabled) {
383
+ this.eventSource = options.codeHotspotsEnabled
385
384
  // Use Datadog instrumentation to collect events with span IDs. Still use
386
385
  // Node API for GC events.
387
- this.eventSource = new CompositeEventSource([
386
+ ? new CompositeEventSource([
388
387
  new DatadogInstrumentationEventSource(eventHandler, eventFilter),
389
388
  new NodeApiEventSource(filteringEventHandler, ['gc'])
390
389
  ])
391
- } else {
392
390
  // Use Node API instrumentation to collect events without span IDs
393
- this.eventSource = new NodeApiEventSource(filteringEventHandler)
394
- }
391
+ : new NodeApiEventSource(filteringEventHandler)
395
392
  }
396
393
 
397
394
  start () {
@@ -412,7 +409,7 @@ class EventsProfiler {
412
409
  }
413
410
 
414
411
  encode (profile) {
415
- return pprof.encode(profile())
412
+ return encodeProfileAsync(profile())
416
413
  }
417
414
  }
418
415
 
@@ -36,6 +36,10 @@ function getNonJSThreadsLabels () {
36
36
  return { [THREAD_NAME_LABEL]: 'Non-JS threads', [THREAD_ID_LABEL]: 'NA', [OS_THREAD_ID_LABEL]: 'NA' }
37
37
  }
38
38
 
39
+ function encodeProfileAsync (profile) {
40
+ return profile.encodeAsync().then(Buffer.from)
41
+ }
42
+
39
43
  module.exports = {
40
44
  END_TIMESTAMP_LABEL,
41
45
  THREAD_NAME_LABEL,
@@ -46,5 +50,6 @@ module.exports = {
46
50
  threadNamePrefix,
47
51
  eventLoopThreadName,
48
52
  getNonJSThreadsLabels,
49
- getThreadLabels: cacheThreadLabels()
53
+ getThreadLabels: cacheThreadLabels(),
54
+ encodeProfileAsync
50
55
  }
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const { oomExportStrategies } = require('../constants')
4
- const { getThreadLabels } = require('./shared')
4
+ const { encodeProfileAsync, getThreadLabels } = require('./shared')
5
5
 
6
6
  function strategiesToCallbackMode (strategies, callbackMode) {
7
7
  return strategies.includes(oomExportStrategies.ASYNC_CALLBACK) ? callbackMode.Async : 0
@@ -10,7 +10,7 @@ function strategiesToCallbackMode (strategies, callbackMode) {
10
10
  class NativeSpaceProfiler {
11
11
  constructor (options = {}) {
12
12
  this.type = 'space'
13
- this._samplingInterval = options.samplingInterval || 512 * 1024
13
+ this._samplingInterval = options.heapSamplingInterval || 512 * 1024
14
14
  this._stackDepth = options.stackDepth || 64
15
15
  this._pprof = undefined
16
16
  this._oomMonitoring = options.oomMonitoring || {}
@@ -47,7 +47,7 @@ class NativeSpaceProfiler {
47
47
  }
48
48
 
49
49
  encode (profile) {
50
- return this._pprof.encode(profile)
50
+ return encodeProfileAsync(profile)
51
51
  }
52
52
 
53
53
  stop () {
@@ -10,7 +10,8 @@ const {
10
10
  SPAN_ID_LABEL,
11
11
  LOCAL_ROOT_SPAN_ID_LABEL,
12
12
  getNonJSThreadsLabels,
13
- getThreadLabels
13
+ getThreadLabels,
14
+ encodeProfileAsync
14
15
  } = require('./shared')
15
16
 
16
17
  const { isWebServerSpan, endpointNameFromTags, getStartedSpans } = require('../webspan-utils')
@@ -89,11 +90,9 @@ class NativeWallProfiler {
89
90
  this._pprof = undefined
90
91
 
91
92
  // Bind these to this so they can be used as callbacks
92
- if (this._withContexts) {
93
- if (this._captureSpanData) {
94
- this._enter = this._enter.bind(this)
95
- this._spanFinished = this._spanFinished.bind(this)
96
- }
93
+ if (this._withContexts && this._captureSpanData) {
94
+ this._enter = this._enter.bind(this)
95
+ this._spanFinished = this._spanFinished.bind(this)
97
96
  }
98
97
  this._generateLabels = this._generateLabels.bind(this)
99
98
 
@@ -326,7 +325,7 @@ class NativeWallProfiler {
326
325
  }
327
326
 
328
327
  encode (profile) {
329
- return this._pprof.encode(profile)
328
+ return encodeProfileAsync(profile)
330
329
  }
331
330
 
332
331
  stop () {
@@ -6,7 +6,7 @@ const dc = require('dc-polyfill')
6
6
  const log = require('../log')
7
7
 
8
8
  // If the process lives for at least 30 seconds, it's considered long-lived
9
- const DEFAULT_LONG_LIVED_THRESHOLD = 30000
9
+ const DEFAULT_LONG_LIVED_THRESHOLD = 30_000
10
10
 
11
11
  /**
12
12
  * This class embodies the SSI profiler-triggering heuristics and also emits telemetry metrics about
@@ -107,10 +107,8 @@ class SSIHeuristics {
107
107
  }
108
108
 
109
109
  _maybeTriggered () {
110
- if (!this.shortLived && !this.noSpan) {
111
- if (typeof this.triggeredCallback === 'function') {
112
- this.triggeredCallback.call(null)
113
- }
110
+ if (!this.shortLived && !this.noSpan && typeof this.triggeredCallback === 'function') {
111
+ this.triggeredCallback.call(null)
114
112
  }
115
113
  }
116
114
 
@@ -3,7 +3,9 @@
3
3
  const dc = require('dc-polyfill')
4
4
  const coalesce = require('koalas')
5
5
  const profileSubmittedChannel = dc.channel('datadog:profiling:mock-profile-submitted')
6
- const { DD_PROFILING_UPLOAD_PERIOD } = process.env
6
+ const { getEnvironmentVariable } = require('../config-helper')
7
+
8
+ const DD_PROFILING_UPLOAD_PERIOD = getEnvironmentVariable('DD_PROFILING_UPLOAD_PERIOD')
7
9
 
8
10
  let timerId
9
11
 
@@ -5,22 +5,30 @@ const tagger = {
5
5
  if (!tags) return {}
6
6
 
7
7
  switch (typeof tags) {
8
- case 'object':
8
+ case 'object': {
9
9
  if (Array.isArray(tags)) {
10
- return tags.reduce((prev, next) => {
11
- const parts = next.split(':')
12
- const key = parts.shift().trim()
13
- const value = parts.join(':').trim()
14
-
15
- if (!key || !value) return prev
10
+ const tagObject = {}
11
+ for (const tag of tags) {
12
+ const colon = tag.indexOf(':')
13
+ if (colon === -1) continue
14
+ const key = tag.slice(0, colon).trim()
15
+ const value = tag.slice(colon + 1).trim()
16
+ if (key.length !== 0 && value.length !== 0) {
17
+ tagObject[key] = value
18
+ }
19
+ }
20
+ return tagObject
21
+ }
16
22
 
17
- return Object.assign(prev, { [key]: value })
18
- }, {})
19
- } else {
20
- return tagger.parse(Object.keys(tags)
21
- .filter(key => tags[key] !== undefined && tags[key] !== null)
22
- .map(key => `${key}:${tags[key]}`))
23
+ const tagsArray = []
24
+ for (const [key, value] of Object.entries(tags)) {
25
+ if (value != null) {
26
+ tagsArray.push(`${key}:${value}`)
27
+ }
23
28
  }
29
+
30
+ return tagger.parse(tagsArray)
31
+ }
24
32
  case 'string':
25
33
  return tagger.parse(tags.split(','))
26
34
  default:
@@ -9,7 +9,7 @@ function endpointNameFromTags (tags) {
9
9
  return tags[RESOURCE_NAME] || [
10
10
  tags[HTTP_METHOD],
11
11
  tags[HTTP_ROUTE]
12
- ].filter(v => v).join(' ')
12
+ ].filter(Boolean).join(' ')
13
13
  }
14
14
 
15
15
  function getStartedSpans (context) {
@@ -10,6 +10,7 @@ const telemetry = require('./telemetry')
10
10
  const nomenclature = require('./service-naming')
11
11
  const PluginManager = require('./plugin_manager')
12
12
  const NoopDogStatsDClient = require('./noop/dogstatsd')
13
+ const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
13
14
  const {
14
15
  setBaggageItem,
15
16
  getBaggageItem,
@@ -189,18 +190,16 @@ class Tracer extends NoopProxy {
189
190
 
190
191
  this._modules.rewriter.enable(config)
191
192
 
192
- if (config.tracing) {
193
- if (config.isManualApiEnabled) {
194
- const TestApiManualPlugin = require('./ci-visibility/test-api-manual/test-api-manual-plugin')
195
- this._testApiManualPlugin = new TestApiManualPlugin(this)
196
- // `shouldGetEnvironmentData` is passed as false so that we only lazily calculate it
197
- // This is the only place where we need to do this because the rest of the plugins
198
- // are lazily configured when the library is imported.
199
- this._testApiManualPlugin.configure({ ...config, enabled: true }, false)
200
- }
193
+ if (config.tracing && config.isManualApiEnabled) {
194
+ const TestApiManualPlugin = require('./ci-visibility/test-api-manual/test-api-manual-plugin')
195
+ this._testApiManualPlugin = new TestApiManualPlugin(this)
196
+ // `shouldGetEnvironmentData` is passed as false so that we only lazily calculate it
197
+ // This is the only place where we need to do this because the rest of the plugins
198
+ // are lazily configured when the library is imported.
199
+ this._testApiManualPlugin.configure({ ...config, enabled: true }, false)
201
200
  }
202
201
  if (config.ciVisAgentlessLogSubmissionEnabled) {
203
- if (process.env.DD_API_KEY) {
202
+ if (getEnvironmentVariable('DD_API_KEY')) {
204
203
  const LogSubmissionPlugin = require('./ci-visibility/log-submission/log-submission-plugin')
205
204
  const automaticLogPlugin = new LogSubmissionPlugin(this)
206
205
  automaticLogPlugin.configure({ ...config, enabled: true })
@@ -0,0 +1,40 @@
1
+ 'use strict'
2
+
3
+ /**
4
+ * `RandomSampler` determines whether or not to sample an operation based on random chance.
5
+ *
6
+ * Use this class **only** when the operation you are sampling does **not have access**
7
+ * to a `Span` or its `SpanContext`.
8
+ *
9
+ * If a `Span` or its `SpanContext` **is** available, use the `Sampler` class instead as
10
+ * it uses a deterministic sampling algorithm consistent across all languages.
11
+ */
12
+ class RandomSampler {
13
+ /**
14
+ * @param {number} rate
15
+ */
16
+ constructor (rate) {
17
+ this._rate = rate
18
+ }
19
+
20
+ /**
21
+ * @returns {number}
22
+ */
23
+ rate () {
24
+ return this._rate
25
+ }
26
+
27
+ /**
28
+ * Determines whether an operation should be sampled based on the configured sampling rate.
29
+ *
30
+ * Returns `true` if the sampling decision passes (i.e., the operation should be sampled).
31
+ * This happens if the sampling rate is `1` (i.e., always sample) or if a random value falls below the rate.
32
+ *
33
+ * @returns {boolean} `true` if the operation should be sampled, otherwise `false`.
34
+ */
35
+ isSampled () {
36
+ return this._rate === 1 || Math.random() < this._rate
37
+ }
38
+ }
39
+
40
+ module.exports = RandomSampler
@@ -4,7 +4,7 @@ const limiter = require('limiter')
4
4
 
5
5
  class RateLimiter {
6
6
  constructor (rateLimit, interval = 'second') {
7
- this._rateLimit = parseInt(rateLimit)
7
+ this._rateLimit = Number.parseInt(rateLimit)
8
8
  this._limiter = new limiter.RateLimiter(this._rateLimit, interval)
9
9
  this._tokensRequested = 0
10
10
  this._prevIntervalTokens = 0
@@ -16,12 +16,12 @@ class RateLimiter {
16
16
  const curIntervalTokens = this._limiter.tokensThisInterval
17
17
  const allowed = this._isAllowed()
18
18
 
19
- if (curIntervalStart !== this._limiter.curIntervalStart) {
19
+ if (curIntervalStart === this._limiter.curIntervalStart) {
20
+ this._tokensRequested++
21
+ } else {
20
22
  this._prevIntervalTokens = curIntervalTokens
21
23
  this._prevTokensRequested = this._tokensRequested
22
24
  this._tokensRequested = 1
23
- } else {
24
- this._tokensRequested++
25
25
  }
26
26
 
27
27
  return allowed
@@ -61,13 +61,9 @@ function enable (config, appsec) {
61
61
 
62
62
  function enableOrDisableAppsec (action, rcConfig, config, appsec) {
63
63
  if (typeof rcConfig.asm?.enabled === 'boolean') {
64
- let shouldEnable
65
-
66
- if (action === 'apply' || action === 'modify') {
67
- shouldEnable = rcConfig.asm.enabled // take control
68
- } else {
69
- shouldEnable = config.appsec.enabled // give back control to local config
70
- }
64
+ const shouldEnable = action === 'apply' || action === 'modify'
65
+ ? rcConfig.asm.enabled // take control
66
+ : config.appsec.enabled // give back control to local config
71
67
 
72
68
  if (shouldEnable) {
73
69
  appsec.enable(config)
@@ -59,13 +59,17 @@ class RemoteConfigManager extends EventEmitter {
59
59
  targets_version: 0,
60
60
  // Use getter so `apply_*` can be updated async and still affect the content of `config_states`
61
61
  get config_states () {
62
- return Array.from(appliedConfigs.values()).map((conf) => ({
63
- id: conf.id,
64
- version: conf.version,
65
- product: conf.product,
66
- apply_state: conf.apply_state,
67
- apply_error: conf.apply_error
68
- }))
62
+ const configs = []
63
+ for (const conf of appliedConfigs.values()) {
64
+ configs.push({
65
+ id: conf.id,
66
+ version: conf.version,
67
+ product: conf.product,
68
+ apply_state: conf.apply_state,
69
+ apply_error: conf.apply_error
70
+ })
71
+ }
72
+ return configs
69
73
  },
70
74
  has_error: false,
71
75
  error: '',
@@ -125,7 +129,7 @@ class RemoteConfigManager extends EventEmitter {
125
129
  }
126
130
 
127
131
  updateProducts () {
128
- this.state.client.products = Array.from(this._handlers.keys())
132
+ this.state.client.products = [...this._handlers.keys()]
129
133
  }
130
134
 
131
135
  getPayload () {
@@ -246,11 +250,19 @@ class RemoteConfigManager extends EventEmitter {
246
250
  this.dispatch(toApply, 'apply')
247
251
  this.dispatch(toModify, 'modify')
248
252
 
249
- this.state.cached_target_files = Array.from(this.appliedConfigs.values()).map((conf) => ({
250
- path: conf.path,
251
- length: conf.length,
252
- hashes: Object.entries(conf.hashes).map((entry) => ({ algorithm: entry[0], hash: entry[1] }))
253
- }))
253
+ this.state.cached_target_files = []
254
+
255
+ for (const conf of this.appliedConfigs.values()) {
256
+ const hashes = []
257
+ for (const hash of Object.entries(conf.hashes)) {
258
+ hashes.push({ algorithm: hash[0], hash: hash[1] })
259
+ }
260
+ this.state.cached_target_files.push({
261
+ path: conf.path,
262
+ length: conf.length,
263
+ hashes
264
+ })
265
+ }
254
266
  }
255
267
  }
256
268
 
@@ -23,7 +23,7 @@ function requirePackageJson (name, module) {
23
23
  const candidate = path.join(modulePath, name, 'package.json')
24
24
  try {
25
25
  return JSON.parse(fs.readFileSync(candidate, 'utf8'))
26
- } catch (e) {
26
+ } catch {
27
27
  continue
28
28
  }
29
29
  }
@@ -4,6 +4,7 @@ const path = require('path')
4
4
  const Module = require('module')
5
5
  const parse = require('module-details-from-path')
6
6
  const dc = require('dc-polyfill')
7
+ const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
7
8
 
8
9
  const origRequire = Module.prototype.require
9
10
 
@@ -60,11 +61,11 @@ function Hook (modules, options, onrequire) {
60
61
  let filename
61
62
  try {
62
63
  filename = Module._resolveFilename(request, this)
63
- } catch (resolveErr) {
64
+ } catch {
64
65
  return _origRequire.apply(this, arguments)
65
66
  }
66
67
 
67
- const core = filename.indexOf(path.sep) === -1
68
+ const core = !filename.includes(path.sep)
68
69
  let name, basedir, hooks
69
70
  // return known patched modules immediately
70
71
  if (cache[filename]) {
@@ -82,9 +83,8 @@ function Hook (modules, options, onrequire) {
82
83
  if (patched) {
83
84
  // If it's already patched, just return it as-is.
84
85
  return origRequire.apply(this, arguments)
85
- } else {
86
- patching[filename] = true
87
86
  }
87
+ patching[filename] = true
88
88
 
89
89
  const payload = {
90
90
  filename,
@@ -110,10 +110,10 @@ function Hook (modules, options, onrequire) {
110
110
  if (!hooks) return exports // abort if module name isn't on whitelist
111
111
  name = filename
112
112
  } else {
113
- const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
114
- const hasLambdaHandler = process.env.DD_LAMBDA_HANDLER !== undefined
113
+ const inAWSLambda = getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME') !== undefined
114
+ const hasLambdaHandler = getEnvironmentVariable('DD_LAMBDA_HANDLER') !== undefined
115
115
  const segments = filename.split(path.sep)
116
- const filenameFromNodeModule = segments.lastIndexOf('node_modules') !== -1
116
+ const filenameFromNodeModule = segments.includes('node_modules')
117
117
  // decide how to assign the stat
118
118
  // first case will only happen when patching an AWS Lambda Handler
119
119
  const stat = inAWSLambda && hasLambdaHandler && !filenameFromNodeModule ? { name: filename } : parse(filename)
@@ -134,7 +134,7 @@ function Hook (modules, options, onrequire) {
134
134
  let res
135
135
  try {
136
136
  res = Module._findPath(name, [basedir, ...paths])
137
- } catch (e) {
137
+ } catch {
138
138
  // case where the file specified in package.json "main" doesn't exist
139
139
  // in this case, the file is treated as module-internal
140
140
  }
@@ -8,10 +8,11 @@ const { DogStatsDClient, MetricsAggregationClient } = require('../dogstatsd')
8
8
  const log = require('../log')
9
9
  const Histogram = require('../histogram')
10
10
  const { performance, PerformanceObserver } = require('perf_hooks')
11
+ const { getEnvironmentVariable } = require('../config-helper')
11
12
 
12
13
  const { NODE_MAJOR, NODE_MINOR } = require('../../../../version')
13
- const { DD_RUNTIME_METRICS_FLUSH_INTERVAL = '10000' } = process.env
14
- const INTERVAL = parseInt(DD_RUNTIME_METRICS_FLUSH_INTERVAL, 10)
14
+ const DD_RUNTIME_METRICS_FLUSH_INTERVAL = getEnvironmentVariable('DD_RUNTIME_METRICS_FLUSH_INTERVAL') ?? '10000'
15
+ const INTERVAL = Number.parseInt(DD_RUNTIME_METRICS_FLUSH_INTERVAL, 10)
15
16
 
16
17
  // Node >=16 has PerformanceObserver with `gc` type, but <16.7 had a critical bug.
17
18
  // See: https://github.com/nodejs/node/issues/39548
@@ -141,7 +142,7 @@ function captureCpuUsage () {
141
142
  time = process.hrtime()
142
143
  cpuUsage = process.cpuUsage()
143
144
 
144
- const elapsedMs = elapsedTime[0] * 1000 + elapsedTime[1] / 1000000
145
+ const elapsedMs = elapsedTime[0] * 1000 + elapsedTime[1] / 1_000_000
145
146
  const userPercent = 100 * elapsedUsage.user / 1000 / elapsedMs
146
147
  const systemPercent = 100 * elapsedUsage.system / 1000 / elapsedMs
147
148
  const totalPercent = userPercent + systemPercent
@@ -202,7 +203,7 @@ function captureGCMetrics () {
202
203
  const pause = {}
203
204
 
204
205
  for (const stat of profile.statistics) {
205
- const type = stat.gcType.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase()
206
+ const type = stat.gcType.replaceAll(/([a-z])([A-Z])/g, '$1_$2').toLowerCase()
206
207
 
207
208
  pause[type] = pause[type] || new Histogram()
208
209
  pause[type].record(stat.cost)
@@ -1,11 +1,31 @@
1
1
  'use strict'
2
2
 
3
+ // Maximum trace ID value is the maximum value for a 64-bit unsigned integer.
4
+ // Javascript cannot handle such large numbers, we will loose precision but it's fine
5
+ // as it is cast into a float64 when computing the threshold
6
+ const MAX_TRACE_ID = 2 ** 64 - 1
7
+
8
+ const UINT64_MODULO = 2n ** 64n
9
+
10
+ // Knuth's factor for the sampling algorithm
11
+ const SAMPLING_KNUTH_FACTOR = 1_111_111_111_111_111_111n
12
+
13
+ /**
14
+ * `Sampler` determines whether or not to sample a trace/span based on the trace ID.
15
+ *
16
+ * This class uses a deterministic sampling algorithm that is consistent across all languages.
17
+ */
3
18
  class Sampler {
19
+ #threshold = 0n
20
+
4
21
  /**
5
- * @param rate {number}
22
+ * @param {number} rate
6
23
  */
7
24
  constructor (rate) {
25
+ // TODO: Should this be moved up to the calling parts?
26
+ rate = Math.min(Math.max(rate, 0), 1)
8
27
  this._rate = rate
28
+ this.#threshold = BigInt(Math.floor(rate * MAX_TRACE_ID))
9
29
  }
10
30
 
11
31
  /**
@@ -15,11 +35,28 @@ class Sampler {
15
35
  return this._rate
16
36
  }
17
37
 
38
+ get threshold () {
39
+ return this.#threshold
40
+ }
41
+
18
42
  /**
19
- * @returns {boolean}
43
+ * Determines whether a trace/span should be sampled based on the configured sampling rate.
44
+ *
45
+ * @param {Span|SpanContext} span - The span or span context to evaluate.
46
+ * @returns {boolean} `true` if the trace/span should be sampled, otherwise `false`.
20
47
  */
21
- isSampled () {
22
- return this._rate === 1 || Math.random() < this._rate
48
+ isSampled (span) {
49
+ if (this._rate === 1) {
50
+ return true
51
+ }
52
+
53
+ if (this._rate === 0) {
54
+ return false
55
+ }
56
+
57
+ span = typeof span.context === 'function' ? span.context() : span
58
+
59
+ return (span._traceId.toBigInt() * SAMPLING_KNUTH_FACTOR) % UINT64_MODULO <= this.#threshold
23
60
  }
24
61
  }
25
62
 
@@ -69,7 +69,7 @@ function resourceLocator (span) {
69
69
  }
70
70
 
71
71
  class SamplingRule {
72
- constructor ({ name, service, resource, tags, sampleRate = 1.0, provenance = undefined, maxPerSecond } = {}) {
72
+ constructor ({ name, service, resource, tags, sampleRate = 1, provenance, maxPerSecond } = {}) {
73
73
  this.matchers = []
74
74
 
75
75
  if (name) {
@@ -112,6 +112,9 @@ class SamplingRule {
112
112
 
113
113
  match (span) {
114
114
  for (const matcher of this.matchers) {
115
+ // Rule is a special object with a .match() property.
116
+ // It has nothing to do with a regular expression.
117
+ // eslint-disable-next-line unicorn/prefer-regexp-test
115
118
  if (!matcher.match(span)) {
116
119
  return false
117
120
  }
@@ -120,8 +123,14 @@ class SamplingRule {
120
123
  return true
121
124
  }
122
125
 
123
- sample () {
124
- if (!this._sampler.isSampled()) {
126
+ /**
127
+ * Determines whether a span should be sampled based on the configured sampling rule.
128
+ *
129
+ * @param {Span|SpanContext} span - The span or span context to evaluate.
130
+ * @returns {boolean} `true` if the span should be sampled, otherwise `false`.
131
+ */
132
+ sample (span) {
133
+ if (!this._sampler.isSampled(span)) {
125
134
  return false
126
135
  }
127
136
 
@@ -52,7 +52,7 @@ class Scope {
52
52
  }
53
53
 
54
54
  _spanOrActive (span) {
55
- return span !== undefined ? span : this.active()
55
+ return span === undefined ? this.active() : span
56
56
  }
57
57
 
58
58
  _isPromise (promise) {