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.
- package/LICENSE-3rdparty.csv +79 -87
- package/ext/tags.d.ts +1 -0
- package/ext/tags.js +1 -0
- package/index.d.ts +46 -39
- package/initialize.mjs +10 -10
- package/loader-hook.mjs +10 -3
- package/package.json +23 -40
- package/packages/datadog-core/src/storage.js +4 -4
- package/packages/datadog-esbuild/index.js +36 -19
- package/packages/datadog-esbuild/src/utils.js +5 -1
- package/packages/datadog-instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/anthropic.js +12 -0
- package/packages/datadog-instrumentations/src/aws-sdk.js +13 -2
- package/packages/datadog-instrumentations/src/azure-service-bus.js +43 -36
- package/packages/datadog-instrumentations/src/cucumber.js +2 -2
- package/packages/datadog-instrumentations/src/find-my-way.js +6 -5
- package/packages/datadog-instrumentations/src/google-genai.js +120 -0
- package/packages/datadog-instrumentations/src/graphql.js +20 -0
- package/packages/datadog-instrumentations/src/helpers/hook.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +12 -1
- package/packages/datadog-instrumentations/src/helpers/register.js +6 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +27 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +152 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +5 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/langchain.js +237 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/loader.js +9 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +11 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +139 -0
- package/packages/datadog-instrumentations/src/jest.js +1 -1
- package/packages/datadog-instrumentations/src/langchain.js +3 -109
- package/packages/datadog-instrumentations/src/mocha/main.js +1 -1
- package/packages/datadog-instrumentations/src/mysql2.js +1 -1
- package/packages/datadog-instrumentations/src/playwright.js +65 -16
- package/packages/datadog-instrumentations/src/router.js +1 -1
- package/packages/datadog-instrumentations/src/selenium.js +3 -1
- package/packages/datadog-instrumentations/src/ws.js +35 -17
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +3 -2
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +14 -5
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +1 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +23 -2
- package/packages/datadog-plugin-cypress/src/plugin.js +1 -1
- package/packages/datadog-plugin-cypress/src/support.js +73 -31
- package/packages/datadog-plugin-google-genai/src/index.js +17 -0
- package/packages/datadog-plugin-google-genai/src/tracing.js +41 -0
- package/packages/datadog-plugin-graphql/src/tools/transforms.js +5 -4
- package/packages/datadog-plugin-jest/src/util.js +4 -3
- package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +3 -1
- package/packages/datadog-plugin-langchain/src/tracing.js +7 -3
- package/packages/datadog-plugin-next/src/index.js +11 -3
- package/packages/datadog-plugin-openai/src/stream-helpers.js +1 -1
- package/packages/datadog-shimmer/src/shimmer.js +2 -2
- package/packages/dd-trace/src/aiguard/sdk.js +29 -14
- package/packages/dd-trace/src/appsec/api_security_sampler.js +1 -1
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +1 -2
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
- package/packages/dd-trace/src/appsec/reporter.js +0 -4
- package/packages/dd-trace/src/baggage.js +11 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +4 -8
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +1 -1
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +4 -2
- package/packages/dd-trace/src/config.js +81 -7
- package/packages/dd-trace/src/config_defaults.js +15 -2
- package/packages/dd-trace/src/datastreams/encoding.js +23 -6
- package/packages/dd-trace/src/datastreams/pathway.js +40 -1
- package/packages/dd-trace/src/datastreams/processor.js +1 -1
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +15 -5
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +30 -15
- package/packages/dd-trace/src/debugger/devtools_client/inspector_promises_polyfill.js +2 -0
- package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +24 -18
- package/packages/dd-trace/src/debugger/devtools_client/send.js +18 -8
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +103 -15
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/constants.js +25 -0
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +56 -25
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +64 -23
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +3 -1
- package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +404 -0
- package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/state.js +7 -2
- package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
- package/packages/dd-trace/src/debugger/index.js +1 -1
- package/packages/dd-trace/src/encode/0.4.js +3 -3
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +2 -2
- package/packages/dd-trace/src/encode/span-stats.js +7 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +6 -13
- package/packages/dd-trace/src/histogram.js +1 -1
- package/packages/dd-trace/src/id.js +60 -0
- package/packages/dd-trace/src/lambda/runtime/ritm.js +2 -3
- package/packages/dd-trace/src/llmobs/constants/tags.js +1 -0
- package/packages/dd-trace/src/llmobs/index.js +5 -5
- package/packages/dd-trace/src/llmobs/noop.js +6 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/index.js +1 -0
- package/packages/dd-trace/src/llmobs/plugins/genai/index.js +104 -0
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +486 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +2 -2
- package/packages/dd-trace/src/llmobs/plugins/{openai.js → openai/index.js} +87 -39
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +114 -0
- package/packages/dd-trace/src/llmobs/sdk.js +10 -1
- package/packages/dd-trace/src/llmobs/span_processor.js +11 -6
- package/packages/dd-trace/src/llmobs/tagger.js +35 -17
- package/packages/dd-trace/src/msgpack/chunk.js +2 -2
- package/packages/dd-trace/src/msgpack/encoder.js +2 -3
- package/packages/dd-trace/src/msgpack/index.js +2 -2
- package/packages/dd-trace/src/openfeature/flagging_provider.js +5 -3
- package/packages/dd-trace/src/opentelemetry/logs/index.js +3 -3
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +14 -8
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +6 -4
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +9 -17
- package/packages/dd-trace/src/opentelemetry/metrics/constants.js +34 -0
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +81 -0
- package/packages/dd-trace/src/opentelemetry/metrics/instruments.js +225 -0
- package/packages/dd-trace/src/opentelemetry/metrics/meter.js +171 -0
- package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +54 -0
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +62 -0
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +251 -0
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +532 -0
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +10 -18
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +36 -22
- package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +2 -2
- package/packages/dd-trace/src/opentelemetry/span.js +1 -1
- package/packages/dd-trace/src/opentelemetry/tracer.js +1 -1
- package/packages/dd-trace/src/opentelemetry/tracer_provider.js +1 -1
- package/packages/dd-trace/src/payload-tagging/index.js +2 -2
- package/packages/dd-trace/src/plugin_manager.js +4 -2
- package/packages/dd-trace/src/plugins/database.js +1 -0
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/plugin.js +7 -9
- package/packages/dd-trace/src/plugins/util/test.js +3 -3
- package/packages/dd-trace/src/plugins/util/url.js +119 -1
- package/packages/dd-trace/src/plugins/util/web.js +10 -41
- package/packages/dd-trace/src/process-tags/index.js +81 -0
- package/packages/dd-trace/src/profiling/config.js +1 -1
- package/packages/dd-trace/src/profiling/exporter_cli.js +7 -6
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +10 -1
- package/packages/dd-trace/src/proxy.js +5 -0
- package/packages/dd-trace/src/rate_limiter.js +1 -1
- package/packages/dd-trace/src/remote_config/manager.js +1 -1
- package/packages/dd-trace/src/require-package-json.js +1 -1
- package/packages/dd-trace/src/ritm.js +1 -1
- package/packages/dd-trace/src/service-naming/index.js +31 -4
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
- package/packages/dd-trace/src/{format.js → span_format.js} +9 -4
- package/packages/dd-trace/src/span_processor.js +16 -11
- package/packages/dd-trace/src/span_stats.js +15 -4
- package/packages/dd-trace/src/spanleak.js +1 -1
- package/packages/dd-trace/src/supported-configurations.json +13 -0
- package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +11 -2
- package/vendor/dist/@datadog/sketches-js/LICENSE +39 -0
- package/vendor/dist/@datadog/sketches-js/index.js +1 -0
- package/vendor/dist/@datadog/source-map/LICENSE +28 -0
- package/vendor/dist/@datadog/source-map/index.js +1 -0
- package/vendor/dist/@isaacs/ttlcache/LICENSE +55 -0
- package/vendor/dist/@isaacs/ttlcache/index.js +1 -0
- package/vendor/dist/@opentelemetry/core/LICENSE +201 -0
- package/vendor/dist/@opentelemetry/core/index.js +1 -0
- package/vendor/dist/@opentelemetry/resources/LICENSE +201 -0
- package/vendor/dist/@opentelemetry/resources/index.js +1 -0
- package/vendor/dist/astring/LICENSE +19 -0
- package/vendor/dist/astring/index.js +1 -0
- package/vendor/dist/crypto-randomuuid/index.js +1 -0
- package/vendor/dist/escape-string-regexp/LICENSE +9 -0
- package/vendor/dist/escape-string-regexp/index.js +1 -0
- package/vendor/dist/esquery/LICENSE +24 -0
- package/vendor/dist/esquery/index.js +1 -0
- package/vendor/dist/ignore/LICENSE +21 -0
- package/vendor/dist/ignore/index.js +1 -0
- package/vendor/dist/istanbul-lib-coverage/LICENSE +24 -0
- package/vendor/dist/istanbul-lib-coverage/index.js +1 -0
- package/vendor/dist/jest-docblock/LICENSE +21 -0
- package/vendor/dist/jest-docblock/index.js +1 -0
- package/vendor/dist/jsonpath-plus/LICENSE +22 -0
- package/vendor/dist/jsonpath-plus/index.js +1 -0
- package/vendor/dist/limiter/LICENSE +19 -0
- package/vendor/dist/limiter/index.js +1 -0
- package/vendor/dist/lodash.sortby/LICENSE +47 -0
- package/vendor/dist/lodash.sortby/index.js +1 -0
- package/vendor/dist/lru-cache/LICENSE +15 -0
- package/vendor/dist/lru-cache/index.js +1 -0
- package/vendor/dist/meriyah/LICENSE +7 -0
- package/vendor/dist/meriyah/index.js +1 -0
- package/vendor/dist/module-details-from-path/LICENSE +21 -0
- package/vendor/dist/module-details-from-path/index.js +1 -0
- package/vendor/dist/mutexify/promise/LICENSE +21 -0
- package/vendor/dist/mutexify/promise/index.js +1 -0
- package/vendor/dist/opentracing/LICENSE +201 -0
- package/vendor/dist/opentracing/binary_carrier.d.ts +11 -0
- package/vendor/dist/opentracing/constants.d.ts +61 -0
- package/vendor/dist/opentracing/examples/demo/demo.d.ts +2 -0
- package/vendor/dist/opentracing/ext/tags.d.ts +90 -0
- package/vendor/dist/opentracing/functions.d.ts +20 -0
- package/vendor/dist/opentracing/global_tracer.d.ts +14 -0
- package/vendor/dist/opentracing/index.d.ts +12 -0
- package/vendor/dist/opentracing/index.js +1 -0
- package/vendor/dist/opentracing/mock_tracer/index.d.ts +5 -0
- package/vendor/dist/opentracing/mock_tracer/mock_context.d.ts +13 -0
- package/vendor/dist/opentracing/mock_tracer/mock_report.d.ts +16 -0
- package/vendor/dist/opentracing/mock_tracer/mock_span.d.ts +50 -0
- package/vendor/dist/opentracing/mock_tracer/mock_tracer.d.ts +26 -0
- package/vendor/dist/opentracing/noop.d.ts +8 -0
- package/vendor/dist/opentracing/reference.d.ts +33 -0
- package/vendor/dist/opentracing/span.d.ts +147 -0
- package/vendor/dist/opentracing/span_context.d.ts +26 -0
- package/vendor/dist/opentracing/test/api_compatibility.d.ts +16 -0
- package/vendor/dist/opentracing/test/mocktracer_implemenation.d.ts +3 -0
- package/vendor/dist/opentracing/test/noop_implementation.d.ts +4 -0
- package/vendor/dist/opentracing/test/opentracing_api.d.ts +3 -0
- package/vendor/dist/opentracing/test/unittest.d.ts +2 -0
- package/vendor/dist/opentracing/tracer.d.ts +127 -0
- package/vendor/dist/path-to-regexp/LICENSE +21 -0
- package/vendor/dist/path-to-regexp/index.js +1 -0
- package/vendor/dist/pprof-format/LICENSE +8 -0
- package/vendor/dist/pprof-format/index.js +1 -0
- package/vendor/dist/protobufjs/LICENSE +39 -0
- package/vendor/dist/protobufjs/index.js +1 -0
- package/vendor/dist/protobufjs/minimal/LICENSE +39 -0
- package/vendor/dist/protobufjs/minimal/index.js +1 -0
- package/vendor/dist/retry/LICENSE +21 -0
- package/vendor/dist/retry/index.js +1 -0
- package/vendor/dist/rfdc/LICENSE +15 -0
- package/vendor/dist/rfdc/index.js +1 -0
- package/vendor/dist/semifies/LICENSE +201 -0
- package/vendor/dist/semifies/index.js +1 -0
- package/vendor/dist/shell-quote/LICENSE +24 -0
- package/vendor/dist/shell-quote/index.js +1 -0
- package/vendor/dist/source-map/LICENSE +28 -0
- package/vendor/dist/source-map/index.js +1 -0
- package/vendor/dist/source-map/lib/util/LICENSE +28 -0
- package/vendor/dist/source-map/lib/util/index.js +1 -0
- package/vendor/dist/source-map/mappings.wasm +0 -0
- package/vendor/dist/tlhunter-sorted-set/LICENSE +21 -0
- package/vendor/dist/tlhunter-sorted-set/index.js +1 -0
- package/vendor/dist/ttl-set/LICENSE +21 -0
- 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 &&
|
|
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
|
|
@@ -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
|
|
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 {
|
|
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
|
|
31
|
-
this._stringBytes = new
|
|
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 {
|
|
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
|
|
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,
|
|
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
|
|
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 =
|
|
101
|
+
module.exports = AgentWriter
|