dd-trace 6.9.0 → 6.11.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/README.md +0 -17
- package/ci/vitest-no-worker-init-setup.mjs +112 -10
- package/index.d.ts +150 -3
- package/initialize.mjs +28 -17
- package/openfeature.js +2 -2
- package/package.json +14 -10
- package/packages/datadog-esbuild/index.js +0 -34
- package/packages/datadog-instrumentations/src/anthropic.js +210 -15
- package/packages/datadog-instrumentations/src/aws-sdk.js +9 -1
- package/packages/datadog-instrumentations/src/browser-bunyan.js +11 -0
- package/packages/datadog-instrumentations/src/bunyan.js +3 -16
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +111 -6
- package/packages/datadog-instrumentations/src/cucumber.js +26 -11
- package/packages/datadog-instrumentations/src/cypress-config.js +182 -16
- package/packages/datadog-instrumentations/src/cypress-legacy-finalizers.js +30 -0
- package/packages/datadog-instrumentations/src/cypress.js +2 -0
- package/packages/datadog-instrumentations/src/fastify.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/bunyan.js +22 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +634 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +10 -8
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +81 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +83 -1
- package/packages/datadog-instrumentations/src/jest.js +26 -18
- package/packages/datadog-instrumentations/src/mariadb.js +278 -21
- package/packages/datadog-instrumentations/src/mocha/main.js +540 -56
- package/packages/datadog-instrumentations/src/mocha/utils.js +132 -25
- package/packages/datadog-instrumentations/src/mysql.js +45 -15
- package/packages/datadog-instrumentations/src/mysql2.js +119 -18
- package/packages/datadog-instrumentations/src/path-to-regexp.js +67 -1
- package/packages/datadog-instrumentations/src/pg.js +116 -92
- package/packages/datadog-instrumentations/src/playwright-reporter.js +99 -0
- package/packages/datadog-instrumentations/src/playwright.js +149 -2
- package/packages/datadog-instrumentations/src/router.js +2 -0
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +43 -4
- package/packages/datadog-instrumentations/src/vitest-main.js +180 -20
- package/packages/datadog-instrumentations/src/vitest-util.js +64 -5
- package/packages/datadog-instrumentations/src/vitest-worker.js +150 -25
- package/packages/datadog-instrumentations/src/webdriverio.js +31 -17
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +12 -6
- package/packages/datadog-plugin-aws-sdk/src/base.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +163 -44
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -13
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -5
- package/packages/datadog-plugin-azure-functions/src/index.js +1 -1
- package/packages/datadog-plugin-browser-bunyan/src/index.js +9 -0
- package/packages/datadog-plugin-bunyan/src/index.js +5 -8
- package/packages/datadog-plugin-cucumber/src/index.js +11 -0
- package/packages/datadog-plugin-cypress/src/after-run.js +5 -1
- package/packages/datadog-plugin-cypress/src/after-spec.js +5 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +82 -30
- package/packages/datadog-plugin-cypress/src/finalization.js +76 -0
- package/packages/datadog-plugin-cypress/src/index.js +12 -6
- package/packages/datadog-plugin-cypress/src/plugin.js +16 -3
- package/packages/datadog-plugin-dd-trace-api/src/index.js +4 -0
- package/packages/datadog-plugin-electron/src/index.js +2 -0
- package/packages/datadog-plugin-fs/src/index.js +1 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +31 -17
- package/packages/datadog-plugin-jest/src/index.js +11 -4
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -3
- package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -3
- package/packages/datadog-plugin-kafkajs/src/producer.js +3 -2
- package/packages/datadog-plugin-kafkajs/src/utils.js +65 -7
- package/packages/datadog-plugin-mocha/src/index.js +606 -40
- package/packages/datadog-plugin-mysql/src/index.js +37 -0
- package/packages/datadog-plugin-nats/src/index.js +1 -1
- package/packages/datadog-plugin-next/src/index.js +1 -19
- package/packages/datadog-plugin-openai/src/tracing.js +41 -30
- package/packages/datadog-plugin-openai-agents/src/integration.js +279 -69
- package/packages/datadog-plugin-openai-agents/src/processor.js +16 -4
- package/packages/datadog-plugin-pg/src/index.js +1 -0
- package/packages/datadog-plugin-playwright/src/index.js +42 -13
- package/packages/datadog-plugin-vitest/src/index.js +14 -20
- package/packages/datadog-plugin-ws/src/util.js +2 -1
- package/packages/datadog-webpack/index.js +0 -11
- package/packages/dd-trace/index.js +0 -1
- package/packages/dd-trace/src/agent/info.js +6 -5
- package/packages/dd-trace/src/aiguard/client.js +100 -1
- package/packages/dd-trace/src/aiguard/errors.js +41 -0
- package/packages/dd-trace/src/aiguard/evaluation.js +357 -0
- package/packages/dd-trace/src/aiguard/integrations/anthropic.js +70 -0
- package/packages/dd-trace/src/aiguard/integrations/index.js +4 -0
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +423 -0
- package/packages/dd-trace/src/aiguard/messages/openai.js +1 -24
- package/packages/dd-trace/src/aiguard/messages/utils.js +28 -0
- package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +1 -11
- package/packages/dd-trace/src/aiguard/sdk.js +22 -278
- package/packages/dd-trace/src/appsec/api_security/normalized-route.js +453 -0
- package/packages/dd-trace/src/appsec/handlers/http-request.js +13 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +9 -12
- package/packages/dd-trace/src/carrier.js +356 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +1 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +27 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +22 -6
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +21 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/request-tracker.js +164 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +22 -6
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +365 -32
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +201 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +5 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +9 -5
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -1
- package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +39 -0
- package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -6
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +6 -2
- package/packages/dd-trace/src/config/generated-config-types.d.ts +7 -0
- package/packages/dd-trace/src/config/index.js +13 -2
- package/packages/dd-trace/src/config/major-overrides.js +7 -0
- package/packages/dd-trace/src/config/supported-configurations.json +24 -0
- package/packages/dd-trace/src/datastreams/context.js +6 -1
- package/packages/dd-trace/src/datastreams/index.js +2 -0
- package/packages/dd-trace/src/datastreams/manager.js +14 -3
- package/packages/dd-trace/src/datastreams/pathway.js +23 -22
- package/packages/dd-trace/src/datastreams/processor.js +16 -13
- package/packages/dd-trace/src/datastreams/size.js +5 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +3 -2
- package/packages/dd-trace/src/exporters/agent/writer.js +49 -9
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +6 -4
- package/packages/dd-trace/src/exporters/common/writer.js +11 -6
- package/packages/dd-trace/src/llmobs/constants/tags.js +5 -0
- package/packages/dd-trace/src/llmobs/experiments/client.js +163 -5
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +241 -87
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +280 -20
- package/packages/dd-trace/src/llmobs/experiments/index.js +58 -59
- package/packages/dd-trace/src/llmobs/experiments/noop.js +71 -3
- package/packages/dd-trace/src/llmobs/experiments/result.js +1 -0
- package/packages/dd-trace/src/llmobs/experiments/util.js +41 -5
- package/packages/dd-trace/src/llmobs/index.js +34 -2
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +12 -3
- package/packages/dd-trace/src/llmobs/plugins/base.js +4 -2
- package/packages/dd-trace/src/llmobs/span_processor.js +16 -0
- package/packages/dd-trace/src/llmobs/tagger.js +96 -0
- package/packages/dd-trace/src/llmobs/util.js +78 -0
- package/packages/dd-trace/src/noop/proxy.js +3 -4
- package/packages/dd-trace/src/openfeature/flagging_provider.js +18 -2
- package/packages/dd-trace/src/openfeature/remote_config.js +1 -1
- package/packages/dd-trace/src/opentelemetry/context_manager.js +7 -7
- package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +2 -1
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +67 -11
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +14 -3
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +25 -12
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +2 -5
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +96 -43
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +126 -120
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +4 -8
- package/packages/dd-trace/src/opentracing/tracer.js +5 -2
- package/packages/dd-trace/src/otel-thread-ctx.js +387 -0
- package/packages/dd-trace/src/plugin_manager.js +5 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +6 -1
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/{datadog-plugin-jest/src/util.js → dd-trace/src/plugins/util/jest.js} +5 -65
- package/packages/dd-trace/src/plugins/util/test.js +93 -14
- package/packages/dd-trace/src/plugins/util/web.js +56 -2
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/space.js +1 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +37 -90
- package/packages/dd-trace/src/profiling/webspan-utils.js +45 -0
- package/packages/dd-trace/src/proxy.js +38 -29
- package/packages/dd-trace/src/ritm.js +9 -2
- package/packages/dd-trace/src/serverless.js +37 -0
- package/packages/dd-trace/src/span_format.js +1 -0
- package/packages/dd-trace/src/span_stats.js +30 -3
- package/packages/dd-trace/src/storage-channels.js +86 -0
- package/packages/dd-trace/src/tracer.js +9 -2
- package/packages/dd-trace/src/tracer_metadata.js +14 -1
- package/packages/dd-trace/src/web-tags-cache.js +132 -0
- package/vendor/dist/@datadog/openfeature-node-server/LICENSE +201 -0
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +0 -65
- package/packages/datadog-webpack/src/optional-peer-loader.js +0 -17
- package/packages/dd-trace/src/feature-registry.js +0 -29
- package/packages/dd-trace/src/openfeature/register.js +0 -35
- package/packages/dd-trace/src/openfeature/require-provider.js +0 -18
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
/** @typedef {Record<string, unknown>} Carrier */
|
|
4
|
+
/** @typedef {string | Buffer} PathwayValue */
|
|
5
|
+
|
|
6
|
+
const FIELD_READ = 1
|
|
7
|
+
const FIELD_WRITE = 2
|
|
8
|
+
const FIELD_HAS = 4
|
|
9
|
+
const FIELD_DELETE = 8
|
|
10
|
+
const FIELD_NAME_LENGTH = 16
|
|
11
|
+
|
|
12
|
+
/** @type {Record<string, unknown>} */
|
|
13
|
+
const carrierOperations = {}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {object} CarrierCapability
|
|
17
|
+
* @property {unknown} [read]
|
|
18
|
+
* @property {unknown} [write]
|
|
19
|
+
* @property {unknown} [has]
|
|
20
|
+
* @property {unknown} [delete]
|
|
21
|
+
* @property {unknown} [nameLength]
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @template Value
|
|
26
|
+
* @typedef {object} CarrierField
|
|
27
|
+
* @property {(carrier: Carrier) => Value | undefined} read
|
|
28
|
+
* @property {(carrier: Carrier, value: Value) => void} write
|
|
29
|
+
* @property {(carrier: Carrier) => boolean} has
|
|
30
|
+
* @property {(carrier: Carrier) => void} delete
|
|
31
|
+
* @property {(carrier: Carrier, target: Carrier) => void} copy
|
|
32
|
+
* @property {number} nameLength
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @template {CarrierCapability} Capability
|
|
37
|
+
* @param {string} name
|
|
38
|
+
* @param {number} operations
|
|
39
|
+
* @param {Capability} capability
|
|
40
|
+
* @returns {Capability}
|
|
41
|
+
*/
|
|
42
|
+
function defineCapability (name, operations, capability) {
|
|
43
|
+
const suffix = name[0].toUpperCase() + name.slice(1)
|
|
44
|
+
if (operations & FIELD_READ) carrierOperations[`read${suffix}`] = capability.read
|
|
45
|
+
if (operations & FIELD_WRITE) carrierOperations[`write${suffix}`] = capability.write
|
|
46
|
+
if (operations & FIELD_HAS) carrierOperations[`has${suffix}`] = capability.has
|
|
47
|
+
if (operations & FIELD_DELETE) carrierOperations[`delete${suffix}`] = capability.delete
|
|
48
|
+
if (operations & FIELD_NAME_LENGTH) carrierOperations[`${name}NameLength`] = capability.nameLength
|
|
49
|
+
return capability
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @template Value
|
|
54
|
+
* @param {string} fieldName
|
|
55
|
+
* @param {string} headerName
|
|
56
|
+
* @param {(value: unknown) => Value | undefined} resolve
|
|
57
|
+
* @param {number} operations
|
|
58
|
+
* @returns {CarrierField<Value>}
|
|
59
|
+
*/
|
|
60
|
+
function defineField (fieldName, headerName, resolve, operations) {
|
|
61
|
+
return defineCapability(fieldName, operations, {
|
|
62
|
+
/**
|
|
63
|
+
* @param {Carrier} carrier
|
|
64
|
+
* @returns {Value | undefined}
|
|
65
|
+
*/
|
|
66
|
+
read (carrier) {
|
|
67
|
+
return resolve(carrier[headerName])
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @param {Carrier} carrier
|
|
72
|
+
* @param {Value} value
|
|
73
|
+
* @returns {void}
|
|
74
|
+
*/
|
|
75
|
+
write (carrier, value) {
|
|
76
|
+
carrier[headerName] = value
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @param {Carrier} carrier
|
|
81
|
+
* @returns {boolean}
|
|
82
|
+
*/
|
|
83
|
+
has (carrier) {
|
|
84
|
+
return headerName in carrier
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @param {Carrier} carrier
|
|
89
|
+
* @returns {void}
|
|
90
|
+
*/
|
|
91
|
+
delete (carrier) {
|
|
92
|
+
delete carrier[headerName]
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @param {Carrier} carrier
|
|
97
|
+
* @param {Carrier} target
|
|
98
|
+
* @returns {void}
|
|
99
|
+
*/
|
|
100
|
+
copy (carrier, target) {
|
|
101
|
+
if (Object.hasOwn(carrier, headerName)) target[headerName] = carrier[headerName]
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
nameLength: headerName.length,
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Skipping non-strings keeps a Symbol or a throwing `toString` from aborting
|
|
110
|
+
* extraction, which discards the whole context rather than one field.
|
|
111
|
+
*
|
|
112
|
+
* @param {unknown} value
|
|
113
|
+
* @returns {string | undefined}
|
|
114
|
+
*/
|
|
115
|
+
function readListText (value) {
|
|
116
|
+
if (typeof value === 'string') return value
|
|
117
|
+
if (!Array.isArray(value)) return
|
|
118
|
+
|
|
119
|
+
let joined = ''
|
|
120
|
+
let first = true
|
|
121
|
+
|
|
122
|
+
for (const item of value) {
|
|
123
|
+
if (typeof item !== 'string') continue
|
|
124
|
+
if (first) {
|
|
125
|
+
joined = item
|
|
126
|
+
first = false
|
|
127
|
+
} else {
|
|
128
|
+
joined += `,${item}`
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return joined
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @param {unknown} value
|
|
137
|
+
* @returns {string | undefined}
|
|
138
|
+
*/
|
|
139
|
+
function readLastText (value) {
|
|
140
|
+
if (typeof value === 'string') return value
|
|
141
|
+
if (!Array.isArray(value)) return
|
|
142
|
+
|
|
143
|
+
let result
|
|
144
|
+
for (let i = value.length - 1; i >= 0; i--) {
|
|
145
|
+
if (typeof value[i] === 'string') {
|
|
146
|
+
result = value[i]
|
|
147
|
+
break
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return result
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @param {unknown} value
|
|
155
|
+
* @returns {string | undefined}
|
|
156
|
+
*/
|
|
157
|
+
function readUniqueText (value) {
|
|
158
|
+
let result
|
|
159
|
+
if (typeof value === 'string') {
|
|
160
|
+
result = value
|
|
161
|
+
} else if (Array.isArray(value) && value.length === 1 && typeof value[0] === 'string') {
|
|
162
|
+
result = value[0]
|
|
163
|
+
}
|
|
164
|
+
return result
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @param {unknown} value
|
|
169
|
+
* @returns {PathwayValue | undefined}
|
|
170
|
+
*/
|
|
171
|
+
function readLastPathway (value) {
|
|
172
|
+
if (typeof value === 'string' || Buffer.isBuffer(value)) return value
|
|
173
|
+
if (!Array.isArray(value)) return
|
|
174
|
+
|
|
175
|
+
let result
|
|
176
|
+
for (let i = value.length - 1; i >= 0; i--) {
|
|
177
|
+
const item = value[i]
|
|
178
|
+
if (typeof item === 'string' || Buffer.isBuffer(item)) {
|
|
179
|
+
result = item
|
|
180
|
+
break
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return result
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const datadogTraceId = defineField(
|
|
187
|
+
'datadogTraceId',
|
|
188
|
+
'x-datadog-trace-id',
|
|
189
|
+
readLastText,
|
|
190
|
+
FIELD_READ | FIELD_WRITE
|
|
191
|
+
)
|
|
192
|
+
const datadogParentId = defineField(
|
|
193
|
+
'datadogParentId',
|
|
194
|
+
'x-datadog-parent-id',
|
|
195
|
+
readLastText,
|
|
196
|
+
FIELD_READ | FIELD_WRITE | FIELD_DELETE
|
|
197
|
+
)
|
|
198
|
+
const datadogOrigin = defineField(
|
|
199
|
+
'datadogOrigin',
|
|
200
|
+
'x-datadog-origin',
|
|
201
|
+
readLastText,
|
|
202
|
+
FIELD_READ | FIELD_WRITE
|
|
203
|
+
)
|
|
204
|
+
const datadogSamplingPriority = defineField(
|
|
205
|
+
'datadogSamplingPriority',
|
|
206
|
+
'x-datadog-sampling-priority',
|
|
207
|
+
readLastText,
|
|
208
|
+
FIELD_READ | FIELD_WRITE
|
|
209
|
+
)
|
|
210
|
+
defineField('datadogTags', 'x-datadog-tags', readListText, FIELD_READ | FIELD_WRITE)
|
|
211
|
+
defineField('baggage', 'baggage', readListText, FIELD_READ | FIELD_WRITE)
|
|
212
|
+
const b3TraceId = defineField('b3TraceId', 'x-b3-traceid', readLastText, FIELD_READ | FIELD_WRITE)
|
|
213
|
+
const b3SpanId = defineField('b3SpanId', 'x-b3-spanid', readLastText, FIELD_READ | FIELD_WRITE)
|
|
214
|
+
const b3ParentId = defineField('b3ParentId', 'x-b3-parentspanid', readLastText, FIELD_WRITE)
|
|
215
|
+
const b3Sampled = defineField('b3Sampled', 'x-b3-sampled', readLastText, FIELD_READ | FIELD_WRITE)
|
|
216
|
+
const b3Flags = defineField('b3Flags', 'x-b3-flags', readLastText, FIELD_READ | FIELD_WRITE)
|
|
217
|
+
const b3 = defineField('b3', 'b3', readLastText, FIELD_READ | FIELD_WRITE)
|
|
218
|
+
defineField('sqsd', 'x-aws-sqsd-attr-_datadog', readLastText, FIELD_READ)
|
|
219
|
+
const traceparent = defineField('traceparent', 'traceparent', readUniqueText, FIELD_READ | FIELD_WRITE)
|
|
220
|
+
const tracestate = defineField('tracestate', 'tracestate', readListText, FIELD_READ | FIELD_WRITE)
|
|
221
|
+
const dsmBase64 = defineField(
|
|
222
|
+
'dsmBase64',
|
|
223
|
+
'dd-pathway-ctx-base64',
|
|
224
|
+
readLastPathway,
|
|
225
|
+
FIELD_READ | FIELD_WRITE | FIELD_HAS | FIELD_NAME_LENGTH
|
|
226
|
+
)
|
|
227
|
+
const dsmBinary = defineField('dsmBinary', 'dd-pathway-ctx', readLastPathway, FIELD_READ | FIELD_HAS)
|
|
228
|
+
|
|
229
|
+
const legacyBaggagePrefix = 'ot-baggage-'
|
|
230
|
+
// RFC 7230 `token`, compatible with Node.js header-name validation.
|
|
231
|
+
const httpHeaderNameExpr = /^[0-9A-Za-z!#$%&'*+\-.^_`|~]+$/
|
|
232
|
+
|
|
233
|
+
defineCapability('legacyBaggage', FIELD_READ | FIELD_WRITE, {
|
|
234
|
+
/**
|
|
235
|
+
* @param {Record<string, string> | undefined} carrier
|
|
236
|
+
* @param {string} key
|
|
237
|
+
* @param {string} value
|
|
238
|
+
* @returns {Record<string, string> | undefined}
|
|
239
|
+
*/
|
|
240
|
+
write (carrier, key, value) {
|
|
241
|
+
const name = legacyBaggagePrefix + key
|
|
242
|
+
if (!httpHeaderNameExpr.test(name)) return
|
|
243
|
+
|
|
244
|
+
carrier ??= {}
|
|
245
|
+
carrier[name] = value
|
|
246
|
+
return carrier
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* @param {Carrier} carrier
|
|
251
|
+
* @param {Record<string, string>} target
|
|
252
|
+
* @returns {void}
|
|
253
|
+
*/
|
|
254
|
+
read (carrier, target) {
|
|
255
|
+
for (const name of Object.keys(carrier)) {
|
|
256
|
+
if (!name.startsWith(legacyBaggagePrefix)) continue
|
|
257
|
+
const key = name.slice(legacyBaggagePrefix.length)
|
|
258
|
+
if (!key) continue
|
|
259
|
+
const value = readLastText(carrier[name])
|
|
260
|
+
if (value !== undefined) target[key] = value
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
const textMapLogFields = [
|
|
266
|
+
datadogTraceId,
|
|
267
|
+
datadogParentId,
|
|
268
|
+
datadogSamplingPriority,
|
|
269
|
+
datadogOrigin,
|
|
270
|
+
b3TraceId,
|
|
271
|
+
b3SpanId,
|
|
272
|
+
b3ParentId,
|
|
273
|
+
b3Sampled,
|
|
274
|
+
b3Flags,
|
|
275
|
+
b3,
|
|
276
|
+
traceparent,
|
|
277
|
+
tracestate,
|
|
278
|
+
]
|
|
279
|
+
const dsmLogFields = [dsmBinary, dsmBase64]
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* @param {Carrier} carrier
|
|
283
|
+
* @param {Array<Pick<CarrierField<unknown>, 'copy'>>} selectedFields
|
|
284
|
+
* @returns {Carrier}
|
|
285
|
+
*/
|
|
286
|
+
function pick (carrier, selectedFields) {
|
|
287
|
+
/** @type {Carrier} */
|
|
288
|
+
const result = {}
|
|
289
|
+
for (const field of selectedFields) field.copy(carrier, result)
|
|
290
|
+
return result
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* @param {Carrier} carrier
|
|
295
|
+
* @returns {Carrier}
|
|
296
|
+
*/
|
|
297
|
+
function pickTextMap (carrier) {
|
|
298
|
+
return pick(carrier, textMapLogFields)
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* @param {Carrier} carrier
|
|
303
|
+
* @returns {Carrier}
|
|
304
|
+
*/
|
|
305
|
+
function pickDsm (carrier) {
|
|
306
|
+
return pick(carrier, dsmLogFields)
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* @typedef {object} CarrierOperations
|
|
311
|
+
* @property {typeof datadogParentId.delete} deleteDatadogParentId
|
|
312
|
+
* @property {typeof dsmBase64.nameLength} dsmBase64NameLength
|
|
313
|
+
* @property {typeof dsmBase64.has} hasDsmBase64
|
|
314
|
+
* @property {typeof dsmBinary.has} hasDsmBinary
|
|
315
|
+
* @property {typeof pickDsm} pickDsm
|
|
316
|
+
* @property {typeof pickTextMap} pickTextMap
|
|
317
|
+
* @property {(carrier: Carrier) => string | undefined} readBaggage
|
|
318
|
+
* @property {typeof b3.read} readB3
|
|
319
|
+
* @property {typeof b3Flags.read} readB3Flags
|
|
320
|
+
* @property {typeof b3Sampled.read} readB3Sampled
|
|
321
|
+
* @property {typeof b3SpanId.read} readB3SpanId
|
|
322
|
+
* @property {typeof b3TraceId.read} readB3TraceId
|
|
323
|
+
* @property {typeof datadogOrigin.read} readDatadogOrigin
|
|
324
|
+
* @property {typeof datadogParentId.read} readDatadogParentId
|
|
325
|
+
* @property {typeof datadogSamplingPriority.read} readDatadogSamplingPriority
|
|
326
|
+
* @property {(carrier: Carrier) => string | undefined} readDatadogTags
|
|
327
|
+
* @property {typeof datadogTraceId.read} readDatadogTraceId
|
|
328
|
+
* @property {typeof dsmBase64.read} readDsmBase64
|
|
329
|
+
* @property {typeof dsmBinary.read} readDsmBinary
|
|
330
|
+
* @property {(carrier: Carrier, target: Record<string, string>) => void} readLegacyBaggage
|
|
331
|
+
* @property {(carrier: Carrier) => string | undefined} readSqsd
|
|
332
|
+
* @property {typeof traceparent.read} readTraceparent
|
|
333
|
+
* @property {typeof tracestate.read} readTracestate
|
|
334
|
+
* @property {(carrier: Carrier, value: string) => void} writeBaggage
|
|
335
|
+
* @property {typeof b3.write} writeB3
|
|
336
|
+
* @property {typeof b3Flags.write} writeB3Flags
|
|
337
|
+
* @property {typeof b3ParentId.write} writeB3ParentId
|
|
338
|
+
* @property {typeof b3Sampled.write} writeB3Sampled
|
|
339
|
+
* @property {typeof b3SpanId.write} writeB3SpanId
|
|
340
|
+
* @property {typeof b3TraceId.write} writeB3TraceId
|
|
341
|
+
* @property {typeof datadogOrigin.write} writeDatadogOrigin
|
|
342
|
+
* @property {typeof datadogParentId.write} writeDatadogParentId
|
|
343
|
+
* @property {typeof datadogSamplingPriority.write} writeDatadogSamplingPriority
|
|
344
|
+
* @property {(carrier: Carrier, value: string) => void} writeDatadogTags
|
|
345
|
+
* @property {typeof datadogTraceId.write} writeDatadogTraceId
|
|
346
|
+
* @property {typeof dsmBase64.write} writeDsmBase64
|
|
347
|
+
* @property {(carrier: Record<string, string> | undefined, key: string, value: string) =>
|
|
348
|
+
* Record<string, string> | undefined} writeLegacyBaggage
|
|
349
|
+
* @property {typeof traceparent.write} writeTraceparent
|
|
350
|
+
* @property {typeof tracestate.write} writeTracestate
|
|
351
|
+
*/
|
|
352
|
+
|
|
353
|
+
carrierOperations.pickDsm = pickDsm
|
|
354
|
+
carrierOperations.pickTextMap = pickTextMap
|
|
355
|
+
|
|
356
|
+
module.exports = /** @type {CarrierOperations} */ (carrierOperations)
|
|
@@ -92,6 +92,7 @@ function removeEmptyCaptureProperties (value) {
|
|
|
92
92
|
if (current.fields === null || (
|
|
93
93
|
current.fields &&
|
|
94
94
|
typeof current.fields === 'object' &&
|
|
95
|
+
// eslint-disable-next-line no-restricted-syntax -- snapshot field names are user variables; no key to probe
|
|
95
96
|
Object.keys(current.fields).length === 0
|
|
96
97
|
)) {
|
|
97
98
|
delete current.fields
|
|
@@ -4,6 +4,7 @@ const AgentWriter = require('../../../exporters/agent/writer')
|
|
|
4
4
|
const AgentlessWriter = require('../agentless/writer')
|
|
5
5
|
const CoverageWriter = require('../agentless/coverage-writer')
|
|
6
6
|
const CiVisibilityExporter = require('../ci-visibility-exporter')
|
|
7
|
+
const request = require('../request')
|
|
7
8
|
const { fetchAgentInfo } = require('../../../agent/info')
|
|
8
9
|
const { DEBUGGER_INPUT_V1 } = require('../../../debugger/constants')
|
|
9
10
|
|
|
@@ -43,9 +44,21 @@ class AgentProxyCiVisibilityExporter extends CiVisibilityExporter {
|
|
|
43
44
|
testOptimization,
|
|
44
45
|
} = config
|
|
45
46
|
|
|
47
|
+
const initializationController = new AbortController()
|
|
48
|
+
const initializationOptions = { signal: initializationController.signal }
|
|
49
|
+
this._initializationRequest = {
|
|
50
|
+
controller: initializationController,
|
|
51
|
+
options: initializationOptions,
|
|
52
|
+
}
|
|
53
|
+
|
|
46
54
|
fetchAgentInfo(this._url, (err, agentInfo) => {
|
|
55
|
+
const initializationFinalFlush = this._initializationRequest?.finalFlush
|
|
56
|
+
this._initializationRequest = undefined
|
|
57
|
+
const initializationAborted = initializationController.signal.aborted
|
|
58
|
+
const agentInfoError = err || (initializationAborted ? initializationController.signal.reason : undefined)
|
|
59
|
+
|
|
47
60
|
this._isInitialized = true
|
|
48
|
-
let latestEvpProxyVersion = getLatestEvpProxyVersion(
|
|
61
|
+
let latestEvpProxyVersion = getLatestEvpProxyVersion(agentInfoError, agentInfo)
|
|
49
62
|
const isEvpCompatible = latestEvpProxyVersion >= 2
|
|
50
63
|
this._isGzipCompatible = latestEvpProxyVersion >= 4
|
|
51
64
|
|
|
@@ -72,7 +85,7 @@ class AgentProxyCiVisibilityExporter extends CiVisibilityExporter {
|
|
|
72
85
|
// path with evpProxyPrefix and sets X-Datadog-EVP-Subdomain: api (see uploadTestScreenshot).
|
|
73
86
|
this._testScreenshotUploadUrl = this._url
|
|
74
87
|
if (testOptimization.DD_TEST_FAILED_TEST_REPLAY_ENABLED) {
|
|
75
|
-
const canFowardLogs = getCanForwardDebuggerLogs(
|
|
88
|
+
const canFowardLogs = getCanForwardDebuggerLogs(agentInfoError, agentInfo)
|
|
76
89
|
if (canFowardLogs) {
|
|
77
90
|
const DynamicInstrumentationLogsWriter = require('../agentless/di-logs-writer')
|
|
78
91
|
this._logsWriter = new DynamicInstrumentationLogsWriter({
|
|
@@ -89,14 +102,25 @@ class AgentProxyCiVisibilityExporter extends CiVisibilityExporter {
|
|
|
89
102
|
lookup,
|
|
90
103
|
protocolVersion,
|
|
91
104
|
headers,
|
|
105
|
+
isTestOptimization: true,
|
|
92
106
|
})
|
|
93
107
|
// coverages will never be used, so we discard them
|
|
94
108
|
this._coverageBuffer = []
|
|
95
109
|
}
|
|
96
110
|
this._resolveCanUseCiVisProtocol(isEvpCompatible)
|
|
111
|
+
if (initializationAborted) {
|
|
112
|
+
this.resetUncodedTraces()
|
|
113
|
+
this.resetDeferredTestSuiteSpans()
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
if (isEvpCompatible) {
|
|
117
|
+
if (initializationFinalFlush) this.exportDeferredTestSuiteSpans()
|
|
118
|
+
} else {
|
|
119
|
+
this.resetDeferredTestSuiteSpans()
|
|
120
|
+
}
|
|
97
121
|
this.exportUncodedTraces()
|
|
98
122
|
this.exportUncodedCoverages()
|
|
99
|
-
})
|
|
123
|
+
}, initializationOptions, request)
|
|
100
124
|
}
|
|
101
125
|
|
|
102
126
|
setUrl (url, coverageUrl) {
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
const getConfig = require('../../../config')
|
|
3
|
-
const request = require('../../../exporters/common/request')
|
|
4
3
|
const log = require('../../../log')
|
|
5
4
|
const { safeJSONStringify } = require('../../../exporters/common/util')
|
|
6
5
|
|
|
7
|
-
const { CoverageCIVisibilityEncoder } = require('../../../encode/coverage-ci-visibility')
|
|
8
|
-
const BaseWriter = require('../../../exporters/common/writer')
|
|
9
6
|
const {
|
|
10
7
|
incrementCountMetric,
|
|
11
8
|
distributionMetric,
|
|
@@ -15,16 +12,34 @@ const {
|
|
|
15
12
|
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
|
|
16
13
|
TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
|
|
17
14
|
} = require('../../../ci-visibility/telemetry')
|
|
15
|
+
const { CoverageCIVisibilityEncoder } = require('../../../encode/coverage-ci-visibility')
|
|
16
|
+
const BaseWriter = require('../../../exporters/common/writer')
|
|
17
|
+
const request = require('../request')
|
|
18
|
+
const TestOptimizationRequestTracker = require('./request-tracker')
|
|
18
19
|
|
|
19
20
|
class Writer extends BaseWriter {
|
|
21
|
+
#requestTracker
|
|
22
|
+
|
|
20
23
|
constructor ({ url, evpProxyPrefix = '' }) {
|
|
21
24
|
super(...arguments)
|
|
25
|
+
this.#requestTracker = new TestOptimizationRequestTracker(this)
|
|
22
26
|
this._url = url
|
|
23
27
|
this._encoder = new CoverageCIVisibilityEncoder(this)
|
|
24
28
|
this._evpProxyPrefix = evpProxyPrefix
|
|
25
29
|
}
|
|
26
30
|
|
|
27
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Flushes buffered coverage, waiting for tracked requests during finalization.
|
|
33
|
+
*
|
|
34
|
+
* @param {(error?: Error) => void} [done]
|
|
35
|
+
* @param {{ deadline?: number }} [options]
|
|
36
|
+
* @returns {void}
|
|
37
|
+
*/
|
|
38
|
+
flush (done, options) {
|
|
39
|
+
this.#requestTracker.flush(done, options)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
_sendPayload (form, _, done, flushOptions) {
|
|
28
43
|
const options = {
|
|
29
44
|
path: '/api/v2/citestcov',
|
|
30
45
|
method: 'POST',
|
|
@@ -34,6 +49,7 @@ class Writer extends BaseWriter {
|
|
|
34
49
|
},
|
|
35
50
|
timeout: 15_000,
|
|
36
51
|
url: this._url,
|
|
52
|
+
deadline: flushOptions?.deadline,
|
|
37
53
|
}
|
|
38
54
|
|
|
39
55
|
if (this._evpProxyPrefix) {
|
|
@@ -50,7 +66,7 @@ class Writer extends BaseWriter {
|
|
|
50
66
|
incrementCountMetric(TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS, { endpoint: 'code_coverage' })
|
|
51
67
|
distributionMetric(TELEMETRY_ENDPOINT_PAYLOAD_BYTES, { endpoint: 'code_coverage' }, form.size())
|
|
52
68
|
|
|
53
|
-
request
|
|
69
|
+
this.#requestTracker.send(request, form, options, (err, res, statusCode) => {
|
|
54
70
|
distributionMetric(
|
|
55
71
|
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_MS,
|
|
56
72
|
{ endpoint: 'code_coverage' },
|
|
@@ -66,7 +82,7 @@ class Writer extends BaseWriter {
|
|
|
66
82
|
{ endpoint: 'code_coverage' }
|
|
67
83
|
)
|
|
68
84
|
log.error('Error sending CI coverage payload', err)
|
|
69
|
-
done()
|
|
85
|
+
done(err)
|
|
70
86
|
return
|
|
71
87
|
}
|
|
72
88
|
log.debug('Response from the intake:', res)
|
|
@@ -1,27 +1,42 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
const getConfig = require('../../../config')
|
|
3
|
-
const request = require('../../../exporters/common/request')
|
|
4
3
|
const log = require('../../../log')
|
|
5
4
|
const { safeJSONStringify } = require('../../../exporters/common/util')
|
|
6
5
|
const { JSONEncoder } = require('../../encode/json-encoder')
|
|
7
6
|
const { DEBUGGER_INPUT_V1 } = require('../../../debugger/constants')
|
|
8
|
-
|
|
9
7
|
const BaseWriter = require('../../../exporters/common/writer')
|
|
10
8
|
|
|
9
|
+
const request = require('../request')
|
|
10
|
+
const TestOptimizationRequestTracker = require('./request-tracker')
|
|
11
|
+
|
|
11
12
|
// Writer used by the integration between Dynamic Instrumentation and Test Visibility
|
|
12
13
|
// It is used to encode and send logs to both the logs intake directly and the
|
|
13
14
|
// `/debugger/v1/input` endpoint in the agent, which is a proxy to the logs intake.
|
|
14
15
|
class DynamicInstrumentationLogsWriter extends BaseWriter {
|
|
16
|
+
#requestTracker
|
|
17
|
+
|
|
15
18
|
// TODO: what's a good value for timeout for the logs intake?
|
|
16
19
|
constructor ({ url, timeout = 15_000, isAgentProxy = false }) {
|
|
17
20
|
super(...arguments)
|
|
21
|
+
this.#requestTracker = new TestOptimizationRequestTracker(this)
|
|
18
22
|
this._url = url
|
|
19
23
|
this._encoder = new JSONEncoder()
|
|
20
24
|
this._isAgentProxy = isAgentProxy
|
|
21
25
|
this.timeout = timeout
|
|
22
26
|
}
|
|
23
27
|
|
|
24
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Flushes buffered logs, waiting for tracked requests during finalization.
|
|
30
|
+
*
|
|
31
|
+
* @param {(error?: Error) => void} [done]
|
|
32
|
+
* @param {{ deadline?: number }} [options]
|
|
33
|
+
* @returns {void}
|
|
34
|
+
*/
|
|
35
|
+
flush (done, options) {
|
|
36
|
+
this.#requestTracker.flush(done, options)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
_sendPayload (data, _, done, flushOptions) {
|
|
25
40
|
const options = {
|
|
26
41
|
path: '/api/v2/logs',
|
|
27
42
|
method: 'POST',
|
|
@@ -31,6 +46,7 @@ class DynamicInstrumentationLogsWriter extends BaseWriter {
|
|
|
31
46
|
},
|
|
32
47
|
timeout: this.timeout,
|
|
33
48
|
url: this._url,
|
|
49
|
+
deadline: flushOptions?.deadline,
|
|
34
50
|
}
|
|
35
51
|
|
|
36
52
|
if (this._isAgentProxy) {
|
|
@@ -41,10 +57,10 @@ class DynamicInstrumentationLogsWriter extends BaseWriter {
|
|
|
41
57
|
// eslint-disable-next-line eslint-rules/eslint-log-printf-style
|
|
42
58
|
log.debug(() => `Request to the logs intake: ${safeJSONStringify(options)}`)
|
|
43
59
|
|
|
44
|
-
request
|
|
60
|
+
this.#requestTracker.send(request, data, options, (err, res) => {
|
|
45
61
|
if (err) {
|
|
46
62
|
log.error('Error sending DI logs payload', err)
|
|
47
|
-
done()
|
|
63
|
+
done(err)
|
|
48
64
|
return
|
|
49
65
|
}
|
|
50
66
|
log.debug('Response from the logs intake:', res)
|