dd-trace 5.79.0 → 5.81.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 (242) hide show
  1. package/LICENSE-3rdparty.csv +79 -87
  2. package/ext/tags.d.ts +1 -0
  3. package/ext/tags.js +1 -0
  4. package/index.d.ts +46 -39
  5. package/initialize.mjs +10 -10
  6. package/loader-hook.mjs +10 -3
  7. package/package.json +23 -40
  8. package/packages/datadog-core/src/storage.js +4 -4
  9. package/packages/datadog-esbuild/index.js +36 -19
  10. package/packages/datadog-esbuild/src/utils.js +5 -1
  11. package/packages/datadog-instrumentations/index.js +1 -0
  12. package/packages/datadog-instrumentations/src/anthropic.js +12 -0
  13. package/packages/datadog-instrumentations/src/aws-sdk.js +13 -2
  14. package/packages/datadog-instrumentations/src/azure-service-bus.js +43 -36
  15. package/packages/datadog-instrumentations/src/cucumber.js +2 -2
  16. package/packages/datadog-instrumentations/src/find-my-way.js +6 -5
  17. package/packages/datadog-instrumentations/src/google-genai.js +120 -0
  18. package/packages/datadog-instrumentations/src/graphql.js +20 -0
  19. package/packages/datadog-instrumentations/src/helpers/hook.js +1 -0
  20. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  21. package/packages/datadog-instrumentations/src/helpers/instrument.js +12 -1
  22. package/packages/datadog-instrumentations/src/helpers/register.js +6 -1
  23. package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +27 -0
  24. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +152 -0
  25. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +5 -0
  26. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/langchain.js +237 -0
  27. package/packages/datadog-instrumentations/src/helpers/rewriter/loader.js +9 -0
  28. package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +11 -0
  29. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +139 -0
  30. package/packages/datadog-instrumentations/src/jest.js +1 -1
  31. package/packages/datadog-instrumentations/src/langchain.js +3 -109
  32. package/packages/datadog-instrumentations/src/mocha/main.js +1 -1
  33. package/packages/datadog-instrumentations/src/mysql2.js +1 -1
  34. package/packages/datadog-instrumentations/src/playwright.js +65 -16
  35. package/packages/datadog-instrumentations/src/router.js +1 -1
  36. package/packages/datadog-instrumentations/src/selenium.js +3 -1
  37. package/packages/datadog-instrumentations/src/ws.js +35 -17
  38. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +3 -2
  39. package/packages/datadog-plugin-azure-service-bus/src/producer.js +14 -5
  40. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +1 -1
  41. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +23 -2
  42. package/packages/datadog-plugin-cypress/src/plugin.js +1 -1
  43. package/packages/datadog-plugin-cypress/src/support.js +73 -31
  44. package/packages/datadog-plugin-google-genai/src/index.js +17 -0
  45. package/packages/datadog-plugin-google-genai/src/tracing.js +41 -0
  46. package/packages/datadog-plugin-graphql/src/tools/transforms.js +5 -4
  47. package/packages/datadog-plugin-jest/src/util.js +4 -3
  48. package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -1
  49. package/packages/datadog-plugin-kafkajs/src/producer.js +3 -1
  50. package/packages/datadog-plugin-langchain/src/tracing.js +7 -3
  51. package/packages/datadog-plugin-next/src/index.js +11 -3
  52. package/packages/datadog-plugin-openai/src/stream-helpers.js +1 -1
  53. package/packages/datadog-shimmer/src/shimmer.js +2 -2
  54. package/packages/dd-trace/src/aiguard/sdk.js +29 -14
  55. package/packages/dd-trace/src/appsec/api_security_sampler.js +1 -1
  56. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +1 -1
  57. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -1
  58. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +1 -2
  59. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
  60. package/packages/dd-trace/src/appsec/reporter.js +0 -4
  61. package/packages/dd-trace/src/baggage.js +11 -0
  62. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +4 -8
  63. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +1 -1
  64. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +4 -2
  65. package/packages/dd-trace/src/config.js +81 -7
  66. package/packages/dd-trace/src/config_defaults.js +15 -2
  67. package/packages/dd-trace/src/datastreams/encoding.js +23 -6
  68. package/packages/dd-trace/src/datastreams/pathway.js +40 -1
  69. package/packages/dd-trace/src/datastreams/processor.js +1 -1
  70. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -1
  71. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +15 -5
  72. package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
  73. package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -0
  74. package/packages/dd-trace/src/debugger/devtools_client/index.js +30 -15
  75. package/packages/dd-trace/src/debugger/devtools_client/inspector_promises_polyfill.js +2 -0
  76. package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +24 -18
  77. package/packages/dd-trace/src/debugger/devtools_client/send.js +18 -8
  78. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +103 -15
  79. package/packages/dd-trace/src/debugger/devtools_client/snapshot/constants.js +25 -0
  80. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +56 -25
  81. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +64 -23
  82. package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +3 -1
  83. package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +404 -0
  84. package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
  85. package/packages/dd-trace/src/debugger/devtools_client/state.js +7 -2
  86. package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
  87. package/packages/dd-trace/src/debugger/index.js +1 -1
  88. package/packages/dd-trace/src/encode/0.4.js +3 -3
  89. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +2 -2
  90. package/packages/dd-trace/src/encode/span-stats.js +7 -1
  91. package/packages/dd-trace/src/exporters/agent/writer.js +6 -13
  92. package/packages/dd-trace/src/histogram.js +1 -1
  93. package/packages/dd-trace/src/id.js +60 -0
  94. package/packages/dd-trace/src/lambda/runtime/ritm.js +2 -3
  95. package/packages/dd-trace/src/llmobs/constants/tags.js +1 -0
  96. package/packages/dd-trace/src/llmobs/index.js +5 -5
  97. package/packages/dd-trace/src/llmobs/noop.js +6 -0
  98. package/packages/dd-trace/src/llmobs/plugins/ai/index.js +1 -0
  99. package/packages/dd-trace/src/llmobs/plugins/genai/index.js +104 -0
  100. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +486 -0
  101. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +2 -2
  102. package/packages/dd-trace/src/llmobs/plugins/{openai.js → openai/index.js} +87 -39
  103. package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +114 -0
  104. package/packages/dd-trace/src/llmobs/sdk.js +10 -1
  105. package/packages/dd-trace/src/llmobs/span_processor.js +11 -6
  106. package/packages/dd-trace/src/llmobs/tagger.js +35 -17
  107. package/packages/dd-trace/src/msgpack/chunk.js +2 -2
  108. package/packages/dd-trace/src/msgpack/encoder.js +2 -3
  109. package/packages/dd-trace/src/msgpack/index.js +2 -2
  110. package/packages/dd-trace/src/openfeature/flagging_provider.js +5 -3
  111. package/packages/dd-trace/src/opentelemetry/logs/index.js +3 -3
  112. package/packages/dd-trace/src/opentelemetry/logs/logger.js +14 -8
  113. package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +6 -4
  114. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +9 -17
  115. package/packages/dd-trace/src/opentelemetry/metrics/constants.js +34 -0
  116. package/packages/dd-trace/src/opentelemetry/metrics/index.js +81 -0
  117. package/packages/dd-trace/src/opentelemetry/metrics/instruments.js +225 -0
  118. package/packages/dd-trace/src/opentelemetry/metrics/meter.js +171 -0
  119. package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +54 -0
  120. package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +62 -0
  121. package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +251 -0
  122. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +532 -0
  123. package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +10 -18
  124. package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +36 -22
  125. package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +2 -2
  126. package/packages/dd-trace/src/opentelemetry/span.js +1 -1
  127. package/packages/dd-trace/src/opentelemetry/tracer.js +1 -1
  128. package/packages/dd-trace/src/opentelemetry/tracer_provider.js +1 -1
  129. package/packages/dd-trace/src/payload-tagging/index.js +2 -2
  130. package/packages/dd-trace/src/plugin_manager.js +4 -2
  131. package/packages/dd-trace/src/plugins/database.js +1 -0
  132. package/packages/dd-trace/src/plugins/index.js +1 -0
  133. package/packages/dd-trace/src/plugins/plugin.js +7 -9
  134. package/packages/dd-trace/src/plugins/util/test.js +3 -3
  135. package/packages/dd-trace/src/plugins/util/url.js +119 -1
  136. package/packages/dd-trace/src/plugins/util/web.js +10 -41
  137. package/packages/dd-trace/src/process-tags/index.js +81 -0
  138. package/packages/dd-trace/src/profiling/config.js +1 -1
  139. package/packages/dd-trace/src/profiling/exporter_cli.js +7 -6
  140. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  141. package/packages/dd-trace/src/profiling/profilers/events.js +10 -1
  142. package/packages/dd-trace/src/proxy.js +5 -0
  143. package/packages/dd-trace/src/rate_limiter.js +1 -1
  144. package/packages/dd-trace/src/remote_config/manager.js +1 -1
  145. package/packages/dd-trace/src/require-package-json.js +1 -1
  146. package/packages/dd-trace/src/ritm.js +1 -1
  147. package/packages/dd-trace/src/service-naming/index.js +31 -4
  148. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
  149. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
  150. package/packages/dd-trace/src/{format.js → span_format.js} +9 -4
  151. package/packages/dd-trace/src/span_processor.js +16 -11
  152. package/packages/dd-trace/src/span_stats.js +15 -4
  153. package/packages/dd-trace/src/spanleak.js +1 -1
  154. package/packages/dd-trace/src/supported-configurations.json +13 -0
  155. package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
  156. package/packages/dd-trace/src/telemetry/telemetry.js +11 -2
  157. package/vendor/dist/@datadog/sketches-js/LICENSE +39 -0
  158. package/vendor/dist/@datadog/sketches-js/index.js +1 -0
  159. package/vendor/dist/@datadog/source-map/LICENSE +28 -0
  160. package/vendor/dist/@datadog/source-map/index.js +1 -0
  161. package/vendor/dist/@isaacs/ttlcache/LICENSE +55 -0
  162. package/vendor/dist/@isaacs/ttlcache/index.js +1 -0
  163. package/vendor/dist/@opentelemetry/core/LICENSE +201 -0
  164. package/vendor/dist/@opentelemetry/core/index.js +1 -0
  165. package/vendor/dist/@opentelemetry/resources/LICENSE +201 -0
  166. package/vendor/dist/@opentelemetry/resources/index.js +1 -0
  167. package/vendor/dist/astring/LICENSE +19 -0
  168. package/vendor/dist/astring/index.js +1 -0
  169. package/vendor/dist/crypto-randomuuid/index.js +1 -0
  170. package/vendor/dist/escape-string-regexp/LICENSE +9 -0
  171. package/vendor/dist/escape-string-regexp/index.js +1 -0
  172. package/vendor/dist/esquery/LICENSE +24 -0
  173. package/vendor/dist/esquery/index.js +1 -0
  174. package/vendor/dist/ignore/LICENSE +21 -0
  175. package/vendor/dist/ignore/index.js +1 -0
  176. package/vendor/dist/istanbul-lib-coverage/LICENSE +24 -0
  177. package/vendor/dist/istanbul-lib-coverage/index.js +1 -0
  178. package/vendor/dist/jest-docblock/LICENSE +21 -0
  179. package/vendor/dist/jest-docblock/index.js +1 -0
  180. package/vendor/dist/jsonpath-plus/LICENSE +22 -0
  181. package/vendor/dist/jsonpath-plus/index.js +1 -0
  182. package/vendor/dist/limiter/LICENSE +19 -0
  183. package/vendor/dist/limiter/index.js +1 -0
  184. package/vendor/dist/lodash.sortby/LICENSE +47 -0
  185. package/vendor/dist/lodash.sortby/index.js +1 -0
  186. package/vendor/dist/lru-cache/LICENSE +15 -0
  187. package/vendor/dist/lru-cache/index.js +1 -0
  188. package/vendor/dist/meriyah/LICENSE +7 -0
  189. package/vendor/dist/meriyah/index.js +1 -0
  190. package/vendor/dist/module-details-from-path/LICENSE +21 -0
  191. package/vendor/dist/module-details-from-path/index.js +1 -0
  192. package/vendor/dist/mutexify/promise/LICENSE +21 -0
  193. package/vendor/dist/mutexify/promise/index.js +1 -0
  194. package/vendor/dist/opentracing/LICENSE +201 -0
  195. package/vendor/dist/opentracing/binary_carrier.d.ts +11 -0
  196. package/vendor/dist/opentracing/constants.d.ts +61 -0
  197. package/vendor/dist/opentracing/examples/demo/demo.d.ts +2 -0
  198. package/vendor/dist/opentracing/ext/tags.d.ts +90 -0
  199. package/vendor/dist/opentracing/functions.d.ts +20 -0
  200. package/vendor/dist/opentracing/global_tracer.d.ts +14 -0
  201. package/vendor/dist/opentracing/index.d.ts +12 -0
  202. package/vendor/dist/opentracing/index.js +1 -0
  203. package/vendor/dist/opentracing/mock_tracer/index.d.ts +5 -0
  204. package/vendor/dist/opentracing/mock_tracer/mock_context.d.ts +13 -0
  205. package/vendor/dist/opentracing/mock_tracer/mock_report.d.ts +16 -0
  206. package/vendor/dist/opentracing/mock_tracer/mock_span.d.ts +50 -0
  207. package/vendor/dist/opentracing/mock_tracer/mock_tracer.d.ts +26 -0
  208. package/vendor/dist/opentracing/noop.d.ts +8 -0
  209. package/vendor/dist/opentracing/reference.d.ts +33 -0
  210. package/vendor/dist/opentracing/span.d.ts +147 -0
  211. package/vendor/dist/opentracing/span_context.d.ts +26 -0
  212. package/vendor/dist/opentracing/test/api_compatibility.d.ts +16 -0
  213. package/vendor/dist/opentracing/test/mocktracer_implemenation.d.ts +3 -0
  214. package/vendor/dist/opentracing/test/noop_implementation.d.ts +4 -0
  215. package/vendor/dist/opentracing/test/opentracing_api.d.ts +3 -0
  216. package/vendor/dist/opentracing/test/unittest.d.ts +2 -0
  217. package/vendor/dist/opentracing/tracer.d.ts +127 -0
  218. package/vendor/dist/path-to-regexp/LICENSE +21 -0
  219. package/vendor/dist/path-to-regexp/index.js +1 -0
  220. package/vendor/dist/pprof-format/LICENSE +8 -0
  221. package/vendor/dist/pprof-format/index.js +1 -0
  222. package/vendor/dist/protobufjs/LICENSE +39 -0
  223. package/vendor/dist/protobufjs/index.js +1 -0
  224. package/vendor/dist/protobufjs/minimal/LICENSE +39 -0
  225. package/vendor/dist/protobufjs/minimal/index.js +1 -0
  226. package/vendor/dist/retry/LICENSE +21 -0
  227. package/vendor/dist/retry/index.js +1 -0
  228. package/vendor/dist/rfdc/LICENSE +15 -0
  229. package/vendor/dist/rfdc/index.js +1 -0
  230. package/vendor/dist/semifies/LICENSE +201 -0
  231. package/vendor/dist/semifies/index.js +1 -0
  232. package/vendor/dist/shell-quote/LICENSE +24 -0
  233. package/vendor/dist/shell-quote/index.js +1 -0
  234. package/vendor/dist/source-map/LICENSE +28 -0
  235. package/vendor/dist/source-map/index.js +1 -0
  236. package/vendor/dist/source-map/lib/util/LICENSE +28 -0
  237. package/vendor/dist/source-map/lib/util/index.js +1 -0
  238. package/vendor/dist/source-map/mappings.wasm +0 -0
  239. package/vendor/dist/tlhunter-sorted-set/LICENSE +21 -0
  240. package/vendor/dist/tlhunter-sorted-set/index.js +1 -0
  241. package/vendor/dist/ttl-set/LICENSE +21 -0
  242. package/vendor/dist/ttl-set/index.js +1 -0
@@ -0,0 +1,404 @@
1
+ 'use strict'
2
+
3
+ /**
4
+ * This module provides functionality to intelligently prune oversized JSON snapshots by selectively removing the
5
+ * largest and deepest leaf nodes while preserving the schema structure.
6
+ */
7
+
8
+ // The RFC specifies that we should prune nodes at level 5 or deeper, but the Node.js implementation has an extra level
9
+ // of depth because it doesn't use the compound key `debugger.snapshot`, but individual `debugger` and `snapshot` keys,
10
+ // so we prune at level 6 or deeper. This level contains the `locals` key.
11
+ const MIN_PRUNE_LEVEL = 6
12
+ const PRUNED_JSON = '{"pruned":true}'
13
+ const PRUNED_JSON_BYTES = Buffer.byteLength(PRUNED_JSON)
14
+
15
+ module.exports = { pruneSnapshot }
16
+
17
+ /**
18
+ * Tree node representing a JSON object in the parsed structure
19
+ */
20
+ class TreeNode {
21
+ /** @type {number} End position in JSON string (set when object closes) */
22
+ end = -1
23
+ /** @type {TreeNode[]} Child nodes */
24
+ children = []
25
+ /** @type {boolean} Has notCapturedReason: "depth" */
26
+ notCapturedDepth = false
27
+ /** @type {boolean} Has any notCapturedReason */
28
+ notCaptured = false
29
+ /** @type {number} Cached byte size */
30
+ #sizeCache = -1
31
+ /** @type {[number, number, number, number]|null} Cached priority key */
32
+ #priorityKeyCache = null
33
+
34
+ /**
35
+ * @param {number} start - Start position in JSON string
36
+ * @param {number} level - Depth in tree (root = 0)
37
+ * @param {string} json - Reference to original JSON string
38
+ * @param {TreeNode|null} [parent] - Parent node reference
39
+ */
40
+ constructor (start, level, json, parent = null) {
41
+ /** @type {number} Start position in JSON string */
42
+ this.start = start
43
+ /** @type {number} Depth in tree (root = 0) */
44
+ this.level = level
45
+ /** @type {string} Reference to original JSON string */
46
+ this.json = json
47
+ /** @type {TreeNode|null} Parent node reference */
48
+ this.parent = parent
49
+ }
50
+
51
+ get size () {
52
+ if (this.#sizeCache === -1) {
53
+ if (this.end === -1) {
54
+ throw new Error('Cannot get size: node.end has not been set yet')
55
+ }
56
+ this.#sizeCache = Buffer.byteLength(this.json.slice(this.start, this.end + 1))
57
+ }
58
+ return this.#sizeCache
59
+ }
60
+
61
+ get isLeaf () {
62
+ return this.children.length === 0
63
+ }
64
+
65
+ /**
66
+ * Priority key for sorting in queue (higher values = higher priority for pruning).
67
+ * Cached to avoid repeated computation during heap operations.
68
+ *
69
+ * @returns {[number, number, number, number]} Priority key tuple: [not_captured_depth, level, not_captured, size]
70
+ */
71
+ get priorityKey () {
72
+ if (this.#priorityKeyCache === null) {
73
+ this.#priorityKeyCache = [
74
+ this.notCapturedDepth ? 1 : 0,
75
+ this.level,
76
+ this.notCaptured ? 1 : 0,
77
+ this.size
78
+ ]
79
+ }
80
+ return this.#priorityKeyCache
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Priority queue implementation using a binary heap.
86
+ * Items with higher priority (by priorityKey) are popped first.
87
+ */
88
+ class PriorityQueue {
89
+ /** @type {TreeNode[]} Binary heap of nodes */
90
+ #heap = []
91
+
92
+ push (node) {
93
+ this.#heap.push(node)
94
+ this.#bubbleUp(this.#heap.length - 1)
95
+ }
96
+
97
+ pop () {
98
+ if (this.#heap.length === 0) return
99
+ if (this.#heap.length === 1) return /** @type {TreeNode} */ (this.#heap.pop())
100
+
101
+ const top = this.#heap[0]
102
+ this.#heap[0] = /** @type {TreeNode} */ (this.#heap.pop())
103
+ this.#bubbleDown(0)
104
+ return top
105
+ }
106
+
107
+ get size () {
108
+ return this.#heap.length
109
+ }
110
+
111
+ #bubbleUp (index) {
112
+ while (index > 0) {
113
+ const parentIndex = Math.floor((index - 1) / 2)
114
+ if (this.#compare(this.#heap[index], this.#heap[parentIndex]) <= 0) break
115
+
116
+ [this.#heap[index], this.#heap[parentIndex]] = [this.#heap[parentIndex], this.#heap[index]]
117
+ index = parentIndex
118
+ }
119
+ }
120
+
121
+ #bubbleDown (index) {
122
+ while (true) {
123
+ let largest = index
124
+ const leftChild = 2 * index + 1
125
+ const rightChild = 2 * index + 2
126
+
127
+ if (leftChild < this.#heap.length && this.#compare(this.#heap[leftChild], this.#heap[largest]) > 0) {
128
+ largest = leftChild
129
+ }
130
+ if (rightChild < this.#heap.length && this.#compare(this.#heap[rightChild], this.#heap[largest]) > 0) {
131
+ largest = rightChild
132
+ }
133
+
134
+ if (largest === index) break
135
+
136
+ [this.#heap[index], this.#heap[largest]] = [this.#heap[largest], this.#heap[index]]
137
+ index = largest
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Compare two nodes by their priority keys.
143
+ *
144
+ * @param {TreeNode} a - First node to compare
145
+ * @param {TreeNode} b - Second node to compare
146
+ * @returns {number} - > 0 if a has higher priority, < 0 if b has higher priority, 0 if equal
147
+ */
148
+ #compare (a, b) {
149
+ const keyA = a.priorityKey
150
+ const keyB = b.priorityKey
151
+ for (let i = 0; i < 4; i++) {
152
+ if (keyA[i] !== keyB[i]) {
153
+ return keyA[i] - keyB[i]
154
+ }
155
+ }
156
+ return 0
157
+ }
158
+ }
159
+
160
+ /**
161
+ * Parse JSON string and build a tree of objects with position tracking.
162
+ * Also detects notCapturedReason properties to set node flags.
163
+ *
164
+ * @param {string} json - The JSON string to parse
165
+ * @returns {TreeNode|null} The root node of the tree, or null if parsing fails
166
+ */
167
+ function parseJsonToTree (json) {
168
+ /** @type {TreeNode[]} Stack of nodes */
169
+ const stack = []
170
+ /** @type {TreeNode|null} The root node of the tree, or null if parsing fails */
171
+ let root = null
172
+ let depth = 0
173
+
174
+ for (let index = 0; index < json.length; index++) {
175
+ switch (json.charCodeAt(index)) {
176
+ case 34: { // 34: double quote
177
+ const stringStart = index + 1
178
+ index = skipString(json, index)
179
+ const stringLength = index - stringStart
180
+
181
+ // Check if this is "notCapturedReason" property (check length first for performance)
182
+ if (stringLength === 17 && json.startsWith('notCapturedReason', stringStart)) {
183
+ // Look ahead for colon and value
184
+ let ahead = index + 1
185
+
186
+ // Skip whitespace and colon
187
+ while (ahead < json.length) {
188
+ const code = json.charCodeAt(ahead)
189
+ // 32: space, 9: tab, 10: newline, 13: carriage return, 58: colon
190
+ if (code === 32 || code === 9 || code === 10 || code === 13 || code === 58) {
191
+ ahead++
192
+ } else {
193
+ break
194
+ }
195
+ }
196
+
197
+ // Check if value is a string (34: double quote)
198
+ if (ahead < json.length && json.charCodeAt(ahead) === 34) {
199
+ const valueStart = ahead + 1
200
+ ahead = skipString(json, ahead)
201
+ const reason = json.slice(valueStart, ahead)
202
+
203
+ const currentNode = /** @type {TreeNode} */ (stack.at(-1))
204
+ currentNode.notCaptured = true
205
+ if (reason === 'depth') {
206
+ currentNode.notCapturedDepth = true
207
+ }
208
+ }
209
+ }
210
+ break
211
+ }
212
+ case 123: { // 123: opening brace
213
+ const parentNode = stack.at(-1)
214
+ const level = depth
215
+ const node = new TreeNode(index, level, json, parentNode)
216
+
217
+ if (parentNode) {
218
+ parentNode.children.push(node)
219
+ } else {
220
+ root = node
221
+ }
222
+
223
+ stack.push(node)
224
+ depth++
225
+ break
226
+ }
227
+ case 125: { // 125: closing brace
228
+ const node = stack.pop()
229
+ if (node === undefined) throw new SyntaxError('Invalid JSON: unexpected closing brace')
230
+ node.end = index
231
+ depth--
232
+ break
233
+ }
234
+ }
235
+ }
236
+
237
+ return root
238
+ }
239
+
240
+ /**
241
+ * Skip to the end of a JSON string, properly handling escape sequences.
242
+ *
243
+ * @param {string} json - The JSON string to skip
244
+ * @param {number} startIndex - The index to start skipping from
245
+ * @returns {number} The index of the closing quote
246
+ */
247
+ function skipString (json, startIndex) {
248
+ let index = startIndex + 1 // Skip opening quote
249
+
250
+ while (index < json.length) {
251
+ const code = json.charCodeAt(index)
252
+
253
+ if (code === 92) { // 92: backslash
254
+ // Skip the backslash and the next character (whatever it is)
255
+ index += 2
256
+ continue
257
+ }
258
+
259
+ if (code === 34) { // 34: double quote
260
+ // Found unescaped closing quote
261
+ return index
262
+ }
263
+
264
+ index++
265
+ }
266
+
267
+ return index
268
+ }
269
+
270
+ /**
271
+ * Collect all leaf nodes at MIN_PRUNE_LEVEL or deeper.
272
+ *
273
+ * @param {TreeNode} root - The root node of the tree
274
+ * @returns {TreeNode[]} The array of leaf nodes
275
+ */
276
+ function collectPrunableLeaves (root) {
277
+ const leaves = []
278
+
279
+ function traverse (node) {
280
+ if (!node) return
281
+
282
+ if (node.isLeaf && node.level >= MIN_PRUNE_LEVEL) {
283
+ leaves.push(node)
284
+ }
285
+
286
+ for (const child of node.children) {
287
+ traverse(child)
288
+ }
289
+ }
290
+
291
+ traverse(root)
292
+ return leaves
293
+ }
294
+
295
+ /**
296
+ * Select nodes to prune using the priority queue algorithm.
297
+ *
298
+ * @param {TreeNode} root - The root node of the tree
299
+ * @param {number} bytesToRemove - The number of bytes to remove
300
+ * @returns {Set<TreeNode>} The set of nodes marked for pruning
301
+ */
302
+ function selectNodesToPrune (root, bytesToRemove) {
303
+ const queue = new PriorityQueue()
304
+ const prunedNodes = new Set()
305
+ const promotedParents = new Set()
306
+
307
+ // Collect initial leaf nodes
308
+ const leaves = collectPrunableLeaves(root)
309
+ for (const leaf of leaves) {
310
+ queue.push(leaf)
311
+ }
312
+
313
+ let bytesRemoved = 0
314
+
315
+ while (queue.size > 0 && bytesRemoved < bytesToRemove) {
316
+ const node = /** @type {TreeNode} */ (queue.pop())
317
+
318
+ if (prunedNodes.has(node)) continue
319
+ prunedNodes.add(node)
320
+
321
+ bytesRemoved += node.size - PRUNED_JSON_BYTES
322
+
323
+ // Check if parent should be promoted to leaf
324
+ const parent = node.parent
325
+ if (parent && parent.level >= MIN_PRUNE_LEVEL && !promotedParents.has(parent)) {
326
+ // Check if all children are now pruned
327
+ const allChildrenPruned = parent.children.every(child => prunedNodes.has(child))
328
+
329
+ if (allChildrenPruned) {
330
+ // Unmark all children as pruned (parent will represent them)
331
+ for (const child of parent.children) {
332
+ prunedNodes.delete(child)
333
+ bytesRemoved -= child.size - PRUNED_JSON_BYTES
334
+ }
335
+
336
+ // Promote parent to leaf by marking it with notCapturedDepth flag
337
+ parent.notCaptured = true
338
+ parent.notCapturedDepth = true
339
+ promotedParents.add(parent)
340
+
341
+ // Add parent to queue for potential pruning
342
+ queue.push(parent)
343
+ }
344
+ }
345
+ }
346
+
347
+ return prunedNodes
348
+ }
349
+
350
+ /**
351
+ * Rebuild JSON string with pruned nodes replaced by {"pruned":true}
352
+ *
353
+ * @param {string} json - The JSON string to rebuild
354
+ * @param {Set<TreeNode>} prunedNodes - The set of nodes to replace with {"pruned":true}
355
+ * @returns {string} The rebuilt JSON string
356
+ */
357
+ function rebuildJson (json, prunedNodes) {
358
+ // Convert set to array and sort by start position (descending)
359
+ const sortedNodes = [...prunedNodes].sort((a, b) => b.start - a.start)
360
+
361
+ // Replace from end to start to maintain position indices
362
+ for (const node of sortedNodes) {
363
+ const before = json.slice(0, node.start)
364
+ const after = json.slice(node.end + 1)
365
+ json = before + PRUNED_JSON + after
366
+ }
367
+
368
+ return json
369
+ }
370
+
371
+ /**
372
+ * Main pruning function
373
+ *
374
+ * @param {string} json - The JSON string to prune
375
+ * @param {number} originalSize - Size of the original JSON string in bytes
376
+ * @param {number} maxSize - Maximum allowed size in bytes
377
+ * @returns {string|undefined} - Pruned JSON string, or undefined if pruning fails
378
+ */
379
+ function pruneSnapshot (json, originalSize, maxSize) {
380
+ const bytesToRemove = originalSize - maxSize
381
+
382
+ if (bytesToRemove <= 0) return json // No pruning needed
383
+
384
+ let prunedSize = originalSize
385
+ let attempts = 0
386
+ const maxAttempts = 6
387
+
388
+ while (prunedSize > maxSize && attempts < maxAttempts) {
389
+ attempts++
390
+
391
+ const root = parseJsonToTree(json)
392
+ if (!root) break
393
+
394
+ const targetBytesToRemove = prunedSize - maxSize
395
+ const prunedNodes = selectNodesToPrune(root, targetBytesToRemove)
396
+ if (prunedNodes.size === 0) break
397
+
398
+ json = rebuildJson(json, prunedNodes)
399
+ prunedSize = Buffer.byteLength(json)
400
+ }
401
+
402
+ // If pruning didn't help, return undefined
403
+ return prunedSize >= originalSize ? undefined : json
404
+ }
@@ -3,7 +3,7 @@
3
3
  const { join, dirname } = require('path')
4
4
  const { readFileSync } = require('fs')
5
5
  const { readFile } = require('fs/promises')
6
- const { SourceMapConsumer } = require('source-map')
6
+ const { SourceMapConsumer } = require('../../../../../vendor/dist/source-map')
7
7
 
8
8
  const cache = new Map()
9
9
  let cacheTimer = null
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const { join, dirname } = require('path')
4
- const { normalize } = require('source-map/lib/util')
4
+ const { normalize } = require('../../../../../vendor/dist/source-map/lib/util')
5
5
  const { loadSourceMapSync } = require('./source-maps')
6
6
  const session = require('./session')
7
7
  const log = require('./log')
@@ -81,9 +81,14 @@ module.exports = {
81
81
  }
82
82
 
83
83
  // If we found a valid match and it's better than our previous best
84
+ // Note: bestMatch.url cannot be null when comparing lengths because:
85
+ // - The first time we enter this block, lastBoundaryPos > maxMatchLength is always true
86
+ // - We set bestMatch.url before we could evaluate the second condition
87
+ // - Subsequent evaluations have bestMatch.url already set
84
88
  if (atBoundary && (
85
89
  lastBoundaryPos > maxMatchLength ||
86
- (lastBoundaryPos === maxMatchLength && url.length < bestMatch.url.length) // Prefer shorter paths
90
+ (lastBoundaryPos === maxMatchLength &&
91
+ url.length < /** @type {string} */ (/** @type {unknown} */ (bestMatch.url)).length) // Prefer shorter paths
87
92
  )) {
88
93
  maxMatchLength = lastBoundaryPos
89
94
  bestMatch.url = sourceUrl || url
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const TTLSet = require('ttl-set')
3
+ const TTLSet = require('../../../../../vendor/dist/ttl-set')
4
4
  const config = require('./config')
5
5
  const JSONBuffer = require('./json-buffer')
6
6
  const request = require('../../exporters/common/request')
@@ -89,7 +89,7 @@ function start (config, rc) {
89
89
 
90
90
  log.error('[debugger] worker thread exited unexpectedly', error)
91
91
 
92
- // Be nice, clean up now that the worker thread encounted an issue and we can't continue
92
+ // Be nice, clean up now that the worker thread encountered an issue and we can't continue
93
93
  rc.removeProductHandler('LIVE_DEBUGGING')
94
94
  worker.removeAllListeners()
95
95
  configChannel = null
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const { truncateSpan, normalizeSpan } = require('./tags-processors')
4
- const { Chunk, MsgpackEncoder } = require('../msgpack')
4
+ const { MsgpackChunk, MsgpackEncoder } = require('../msgpack')
5
5
  const log = require('../log')
6
6
  const { isTrue } = require('../util')
7
7
  const { memoize } = require('../log/utils')
@@ -27,8 +27,8 @@ class AgentEncoder {
27
27
  constructor (writer, limit = SOFT_LIMIT) {
28
28
  this._msgpack = new MsgpackEncoder()
29
29
  this._limit = limit
30
- this._traceBytes = new Chunk()
31
- this._stringBytes = new Chunk()
30
+ this._traceBytes = new MsgpackChunk()
31
+ this._stringBytes = new MsgpackChunk()
32
32
  this._writer = writer
33
33
  this._reset()
34
34
  this._debugEncoding = isTrue(getEnvironmentVariable('DD_TRACE_ENCODING_DEBUG'))
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
  const { AgentEncoder } = require('./0.4')
3
- const { Chunk } = require('../msgpack')
3
+ const { MsgpackChunk } = require('../msgpack')
4
4
 
5
5
  const {
6
6
  distributionMetric,
@@ -15,7 +15,7 @@ const COVERAGE_KEYS_LENGTH = 2
15
15
  class CoverageCIVisibilityEncoder extends AgentEncoder {
16
16
  constructor () {
17
17
  super(...arguments)
18
- this._coverageBytes = new Chunk()
18
+ this._coverageBytes = new MsgpackChunk()
19
19
  this.form = new FormData()
20
20
  this._coveragesCount = 0
21
21
  this.reset()
@@ -31,7 +31,7 @@ class SpanStatsEncoder extends AgentEncoder {
31
31
  }
32
32
 
33
33
  _encodeStat (bytes, stat) {
34
- this._encodeMapPrefix(bytes, 12)
34
+ this._encodeMapPrefix(bytes, 14)
35
35
 
36
36
  this._encodeString(bytes, 'Service')
37
37
  const service = stat.Service || DEFAULT_SERVICE_NAME
@@ -70,6 +70,12 @@ class SpanStatsEncoder extends AgentEncoder {
70
70
 
71
71
  this._encodeString(bytes, 'TopLevelHits')
72
72
  this._encodeLong(bytes, stat.TopLevelHits)
73
+
74
+ this._encodeString(bytes, 'HTTPMethod')
75
+ this._encodeString(bytes, stat.HTTPMethod)
76
+
77
+ this._encodeString(bytes, 'HTTPEndpoint')
78
+ this._encodeString(bytes, stat.HTTPEndpoint)
73
79
  }
74
80
 
75
81
  _encodeBucket (bytes, bucket) {
@@ -9,7 +9,7 @@ const BaseWriter = require('../common/writer')
9
9
 
10
10
  const METRIC_PREFIX = 'datadog.tracer.node.exporter.agent'
11
11
 
12
- class Writer extends BaseWriter {
12
+ class AgentWriter extends BaseWriter {
13
13
  constructor ({ prioritySampler, lookup, protocolVersion, headers, config = {} }) {
14
14
  super(...arguments)
15
15
  const AgentEncoder = getEncoder(protocolVersion)
@@ -62,12 +62,6 @@ class Writer extends BaseWriter {
62
62
  }
63
63
  }
64
64
 
65
- function setHeader (headers, key, value) {
66
- if (value) {
67
- headers[key] = value
68
- }
69
- }
70
-
71
65
  function getEncoder (protocolVersion) {
72
66
  return protocolVersion === '0.5'
73
67
  ? require('../../encode/0.5').AgentEncoder
@@ -82,16 +76,15 @@ function makeRequest (version, data, count, url, headers, lookup, needsStartupLo
82
76
  ...headers,
83
77
  'Content-Type': 'application/msgpack',
84
78
  'Datadog-Meta-Tracer-Version': tracerVersion,
85
- 'X-Datadog-Trace-Count': String(count)
79
+ 'X-Datadog-Trace-Count': String(count),
80
+ 'Datadog-Meta-Lang': 'nodejs',
81
+ 'Datadog-Meta-Lang-Version': process.version,
82
+ 'Datadog-Meta-Lang-Interpreter': process.jsEngine || 'v8'
86
83
  },
87
84
  lookup,
88
85
  url
89
86
  }
90
87
 
91
- setHeader(options.headers, 'Datadog-Meta-Lang', 'nodejs')
92
- setHeader(options.headers, 'Datadog-Meta-Lang-Version', process.version)
93
- setHeader(options.headers, 'Datadog-Meta-Lang-Interpreter', process.jsEngine || 'v8')
94
-
95
88
  log.debug('Request to the agent: %j', options)
96
89
 
97
90
  request(data, options, (err, res, status) => {
@@ -105,4 +98,4 @@ function makeRequest (version, data, count, url, headers, lookup, needsStartupLo
105
98
  })
106
99
  }
107
100
 
108
- module.exports = Writer
101
+ module.exports = AgentWriter
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { DDSketch } = require('@datadog/sketches-js')
3
+ const { DDSketch } = require('../../../vendor/dist/@datadog/sketches-js')
4
4
 
5
5
  class Histogram {
6
6
  constructor () {