dd-trace 5.82.0 → 5.83.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 +78 -79
- package/ci/init.js +6 -6
- package/index.d.ts +152 -3
- package/loader-hook.mjs +1 -1
- package/package.json +58 -55
- package/packages/datadog-core/src/storage.js +7 -7
- package/packages/datadog-esbuild/index.js +6 -0
- package/packages/datadog-instrumentations/src/ai.js +7 -3
- package/packages/datadog-instrumentations/src/child_process.js +1 -1
- package/packages/datadog-instrumentations/src/cucumber.js +1 -1
- package/packages/datadog-instrumentations/src/graphql.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/instrumentations.js +4 -3
- package/packages/datadog-instrumentations/src/helpers/register.js +3 -7
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +1 -1
- package/packages/datadog-instrumentations/src/http/client.js +2 -2
- package/packages/datadog-instrumentations/src/jest.js +35 -14
- package/packages/datadog-instrumentations/src/koa.js +2 -1
- package/packages/datadog-instrumentations/src/light-my-request.js +2 -2
- package/packages/datadog-instrumentations/src/mocha/main.js +2 -2
- package/packages/datadog-instrumentations/src/mocha/worker.js +1 -1
- package/packages/datadog-instrumentations/src/mocha.js +1 -1
- package/packages/datadog-instrumentations/src/mysql.js +1 -1
- package/packages/datadog-instrumentations/src/mysql2.js +2 -2
- package/packages/datadog-instrumentations/src/net.js +13 -5
- package/packages/datadog-instrumentations/src/nyc.js +1 -1
- package/packages/datadog-instrumentations/src/otel-sdk-trace.js +4 -4
- package/packages/datadog-instrumentations/src/pg.js +4 -2
- package/packages/datadog-instrumentations/src/playwright.js +3 -3
- package/packages/datadog-instrumentations/src/selenium.js +2 -2
- package/packages/datadog-instrumentations/src/undici.js +12 -1
- package/packages/datadog-plugin-aws-sdk/src/base.js +4 -4
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +2 -2
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +2 -2
- package/packages/datadog-plugin-cucumber/src/index.js +2 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +2 -2
- package/packages/datadog-plugin-dd-trace-api/src/index.js +2 -2
- package/packages/datadog-plugin-express/src/code_origin.js +21 -15
- package/packages/datadog-plugin-fastify/src/code_origin.js +17 -4
- package/packages/datadog-plugin-jest/src/index.js +2 -2
- package/packages/datadog-plugin-mocha/src/index.js +2 -2
- package/packages/datadog-plugin-mongodb-core/src/index.js +2 -2
- package/packages/datadog-plugin-playwright/src/index.js +3 -3
- package/packages/datadog-plugin-undici/src/index.js +305 -2
- package/packages/datadog-plugin-vitest/src/index.js +5 -5
- package/packages/dd-trace/index.js +19 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +1 -1
- package/packages/dd-trace/src/appsec/rasp/index.js +2 -4
- package/packages/dd-trace/src/azure_metadata.js +8 -3
- package/packages/dd-trace/src/baggage.js +36 -11
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +5 -1
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +3 -2
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +3 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +4 -4
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -2
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +4 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -4
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +2 -2
- package/packages/dd-trace/src/{config_defaults.js → config/defaults.js} +3 -3
- package/packages/dd-trace/src/{config-helper.js → config/helper.js} +88 -15
- package/packages/dd-trace/src/{config.js → config/index.js} +92 -45
- package/packages/dd-trace/src/config/remote_config.js +187 -19
- package/packages/dd-trace/src/{config_stable.js → config/stable.js} +20 -32
- package/packages/dd-trace/src/{supported-configurations.json → config/supported-configurations.json} +2 -0
- package/packages/dd-trace/src/crashtracking/crashtracker.js +1 -1
- package/packages/dd-trace/src/datastreams/processor.js +1 -1
- package/packages/dd-trace/src/datastreams/writer.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/config.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/send.js +3 -3
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/constants.js +1 -1
- package/packages/dd-trace/src/debugger/index.js +83 -15
- package/packages/dd-trace/src/dogstatsd.js +2 -2
- package/packages/dd-trace/src/encode/0.4.js +2 -2
- package/packages/dd-trace/src/exporter.js +1 -1
- package/packages/dd-trace/src/exporters/agent/index.js +2 -4
- package/packages/dd-trace/src/exporters/agent/writer.js +9 -14
- package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +1 -1
- package/packages/dd-trace/src/exporters/common/docker.js +2 -2
- package/packages/dd-trace/src/exporters/common/request.js +1 -1
- package/packages/dd-trace/src/exporters/common/util.js +2 -2
- package/packages/dd-trace/src/exporters/span-stats/index.js +1 -1
- package/packages/dd-trace/src/flare/index.js +1 -1
- package/packages/dd-trace/src/guardrails/telemetry.js +1 -1
- package/packages/dd-trace/src/index.js +4 -4
- package/packages/dd-trace/src/lambda/handler.js +2 -2
- package/packages/dd-trace/src/lambda/index.js +2 -2
- package/packages/dd-trace/src/lambda/runtime/patch.js +2 -2
- package/packages/dd-trace/src/lambda/runtime/ritm.js +2 -2
- package/packages/dd-trace/src/llmobs/constants/tags.js +8 -1
- package/packages/dd-trace/src/llmobs/index.js +2 -2
- package/packages/dd-trace/src/llmobs/noop.js +2 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +3 -4
- package/packages/dd-trace/src/llmobs/sdk.js +33 -6
- package/packages/dd-trace/src/llmobs/span_processor.js +17 -7
- package/packages/dd-trace/src/llmobs/tagger.js +175 -1
- package/packages/dd-trace/src/llmobs/writers/base.js +116 -37
- package/packages/dd-trace/src/llmobs/writers/spans.js +4 -3
- package/packages/dd-trace/src/log/index.js +5 -5
- package/packages/dd-trace/src/noop/proxy.js +3 -3
- package/packages/dd-trace/src/openfeature/writers/base.js +7 -8
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +2 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +48 -6
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +45 -21
- package/packages/dd-trace/src/opentracing/span.js +4 -4
- package/packages/dd-trace/src/plugin_manager.js +8 -6
- package/packages/dd-trace/src/plugins/util/ci.js +5 -8
- package/packages/dd-trace/src/plugins/util/git-cache.js +3 -3
- package/packages/dd-trace/src/plugins/util/test.js +1 -1
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +41 -43
- package/packages/dd-trace/src/profiler.js +4 -39
- package/packages/dd-trace/src/profiling/config.js +74 -31
- package/packages/dd-trace/src/profiling/exporter_cli.js +5 -5
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +9 -2
- package/packages/dd-trace/src/profiling/index.js +1 -1
- package/packages/dd-trace/src/profiling/libuv-size.js +1 -1
- package/packages/dd-trace/src/profiling/profiler.js +57 -2
- package/packages/dd-trace/src/proxy.js +34 -5
- package/packages/dd-trace/src/remote_config/capabilities.js +3 -0
- package/packages/dd-trace/src/remote_config/index.js +1 -1
- package/packages/dd-trace/src/ritm.js +8 -4
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +2 -2
- package/packages/dd-trace/src/serverless.js +2 -2
- package/packages/dd-trace/src/span_processor.js +2 -2
- package/packages/dd-trace/src/startup-log.js +6 -15
- package/packages/dd-trace/src/telemetry/endpoints.js +67 -5
- package/packages/dd-trace/src/telemetry/send-data.js +103 -4
- package/packages/dd-trace/src/telemetry/telemetry.js +229 -110
- /package/packages/dd-trace/src/{git_properties.js → config/git_properties.js} +0 -0
|
@@ -1,10 +1,313 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const HttpClientPlugin = require('../../datadog-plugin-http/src/client')
|
|
4
|
+
const { storage } = require('../../datadog-core')
|
|
5
|
+
const tags = require('../../../ext/tags')
|
|
6
|
+
const formats = require('../../../ext/formats')
|
|
7
|
+
const HTTP_HEADERS = formats.HTTP_HEADERS
|
|
8
|
+
const log = require('../../dd-trace/src/log')
|
|
9
|
+
const { CLIENT_PORT_KEY } = require('../../dd-trace/src/constants')
|
|
4
10
|
|
|
5
|
-
|
|
11
|
+
const {
|
|
12
|
+
HTTP_STATUS_CODE,
|
|
13
|
+
HTTP_REQUEST_HEADERS,
|
|
14
|
+
HTTP_RESPONSE_HEADERS,
|
|
15
|
+
} = tags
|
|
16
|
+
|
|
17
|
+
// WeakMap to store span context for native undici request objects
|
|
18
|
+
const requestContexts = new WeakMap()
|
|
19
|
+
|
|
20
|
+
class UndiciPlugin extends HttpClientPlugin {
|
|
6
21
|
static id = 'undici'
|
|
7
22
|
static prefix = 'tracing:apm:undici:fetch'
|
|
23
|
+
|
|
24
|
+
constructor (...args) {
|
|
25
|
+
super(...args)
|
|
26
|
+
|
|
27
|
+
// Subscribe to native undici diagnostic channels for undici >= 4.7.0
|
|
28
|
+
// These channels fire for ALL undici requests (fetch, request, stream, etc.)
|
|
29
|
+
this.addSub('undici:request:create', this.#onNativeRequestCreate.bind(this))
|
|
30
|
+
this.addSub('undici:request:headers', this.#onNativeRequestHeaders.bind(this))
|
|
31
|
+
this.addSub('undici:request:trailers', this.#onNativeRequestTrailers.bind(this))
|
|
32
|
+
this.addSub('undici:request:error', this.#onNativeRequestError.bind(this))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ===========================================
|
|
36
|
+
// Native undici diagnostic channel handlers
|
|
37
|
+
// These fire for undici >= 4.7.0 for ALL request types (fetch, request, stream, etc.)
|
|
38
|
+
// ===========================================
|
|
39
|
+
|
|
40
|
+
#onNativeRequestCreate ({ request }) {
|
|
41
|
+
if (!request) return
|
|
42
|
+
|
|
43
|
+
const store = storage('legacy').getStore()
|
|
44
|
+
const { origin = '', path = '/' } = request
|
|
45
|
+
const method = request.method?.toUpperCase() ?? 'GET'
|
|
46
|
+
|
|
47
|
+
// Parse origin to extract protocol, hostname, port
|
|
48
|
+
let protocol = 'http:'
|
|
49
|
+
let hostname = 'localhost'
|
|
50
|
+
let port = ''
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
const url = new URL(origin)
|
|
54
|
+
protocol = url.protocol
|
|
55
|
+
hostname = url.hostname
|
|
56
|
+
port = url.port
|
|
57
|
+
} catch {
|
|
58
|
+
// If origin is not a valid URL, use defaults
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const host = port ? `${hostname}:${port}` : hostname
|
|
62
|
+
const pathname = path.split(/[?#]/)[0]
|
|
63
|
+
const uri = `${protocol}//${host}${pathname}`
|
|
64
|
+
|
|
65
|
+
const allowed = this.config.filter(uri)
|
|
66
|
+
const childOf = store && allowed ? store.span : null
|
|
67
|
+
|
|
68
|
+
const span = this.startSpan(this.operationName(), {
|
|
69
|
+
childOf,
|
|
70
|
+
meta: {
|
|
71
|
+
'span.kind': 'client',
|
|
72
|
+
'http.method': method,
|
|
73
|
+
'http.url': uri,
|
|
74
|
+
'out.host': hostname
|
|
75
|
+
},
|
|
76
|
+
metrics: {
|
|
77
|
+
[CLIENT_PORT_KEY]: port ? Number.parseInt(port, 10) : undefined
|
|
78
|
+
},
|
|
79
|
+
service: this.serviceName({ pluginConfig: this.config, sessionDetails: { host: hostname, port } }),
|
|
80
|
+
resource: method,
|
|
81
|
+
type: 'http'
|
|
82
|
+
}, false)
|
|
83
|
+
|
|
84
|
+
// Disable recording if not allowed
|
|
85
|
+
if (!allowed) {
|
|
86
|
+
span._spanContext._trace.record = false
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Capture request headers if configured
|
|
90
|
+
if (request.headers && this.config.headers) {
|
|
91
|
+
addConfiguredHeaders(span, request.headers, this.config.headers, HTTP_REQUEST_HEADERS)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Inject trace headers if propagation is allowed
|
|
95
|
+
if (this.config.propagationFilter(uri)) {
|
|
96
|
+
const headers = {}
|
|
97
|
+
this.tracer.inject(span, HTTP_HEADERS, headers)
|
|
98
|
+
|
|
99
|
+
// Use addHeader if available (undici provides this on the request object)
|
|
100
|
+
if (typeof request.addHeader === 'function') {
|
|
101
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
102
|
+
request.addHeader(name, value)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Store span context for request for later retrieval
|
|
108
|
+
requestContexts.set(request, {
|
|
109
|
+
span,
|
|
110
|
+
store,
|
|
111
|
+
uri
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
// Enter the span context
|
|
115
|
+
storage('legacy').enterWith({ ...store, span })
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
#onNativeRequestHeaders ({ request, response }) {
|
|
119
|
+
const ctx = requestContexts.get(request)
|
|
120
|
+
if (!ctx) return
|
|
121
|
+
|
|
122
|
+
const { span } = ctx
|
|
123
|
+
const statusCode = response?.statusCode
|
|
124
|
+
|
|
125
|
+
if (statusCode) {
|
|
126
|
+
span.setTag(HTTP_STATUS_CODE, statusCode)
|
|
127
|
+
|
|
128
|
+
if (!this.config.validateStatus(statusCode)) {
|
|
129
|
+
span.setTag('error', 1)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Add response headers if configured
|
|
134
|
+
if (response?.headers && this.config.headers) {
|
|
135
|
+
addConfiguredHeaders(span, response.headers, this.config.headers, HTTP_RESPONSE_HEADERS)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
#onNativeRequestTrailers ({ request }) {
|
|
140
|
+
const ctx = requestContexts.get(request)
|
|
141
|
+
if (!ctx) return
|
|
142
|
+
|
|
143
|
+
const { span, store } = ctx
|
|
144
|
+
|
|
145
|
+
// Call the request hook if configured
|
|
146
|
+
this.config.hooks.request(span, null, null)
|
|
147
|
+
|
|
148
|
+
// Finish the span
|
|
149
|
+
span.finish()
|
|
150
|
+
|
|
151
|
+
// Clean up
|
|
152
|
+
requestContexts.delete(request)
|
|
153
|
+
|
|
154
|
+
// Restore parent store
|
|
155
|
+
if (store) {
|
|
156
|
+
storage('legacy').enterWith(store)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
#onNativeRequestError ({ request, error }) {
|
|
161
|
+
const ctx = requestContexts.get(request)
|
|
162
|
+
if (!ctx) return
|
|
163
|
+
|
|
164
|
+
const { span, store } = ctx
|
|
165
|
+
|
|
166
|
+
// Don't record AbortError as an error - it's user-initiated cancellation
|
|
167
|
+
if (error && error.name !== 'AbortError') {
|
|
168
|
+
span.setTag('error', error)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Call the request hook if configured
|
|
172
|
+
this.config.hooks.request(span, null, null)
|
|
173
|
+
|
|
174
|
+
// Finish the span
|
|
175
|
+
span.finish()
|
|
176
|
+
|
|
177
|
+
// Clean up
|
|
178
|
+
requestContexts.delete(request)
|
|
179
|
+
|
|
180
|
+
// Restore parent store
|
|
181
|
+
if (store) {
|
|
182
|
+
storage('legacy').enterWith(store)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ===========================================
|
|
187
|
+
// Fetch-based tracing channel handlers
|
|
188
|
+
// These handle fetch() for undici < 4.7.0 (before native DC was added)
|
|
189
|
+
// ===========================================
|
|
190
|
+
|
|
191
|
+
bindStart (ctx) {
|
|
192
|
+
const req = ctx.req
|
|
193
|
+
const options = new URL(req.url)
|
|
194
|
+
options.headers = Object.fromEntries(req.headers.entries())
|
|
195
|
+
options.method = req.method
|
|
196
|
+
|
|
197
|
+
ctx.args = { options }
|
|
198
|
+
|
|
199
|
+
const store = super.bindStart(ctx)
|
|
200
|
+
|
|
201
|
+
// Inject trace headers back into the request
|
|
202
|
+
for (const name of Object.keys(options.headers)) {
|
|
203
|
+
if (!req.headers.has(name)) {
|
|
204
|
+
req.headers.set(name, options.headers[name])
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return store
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
error (ctx) {
|
|
212
|
+
// Don't record AbortError as an error - it's user-initiated cancellation
|
|
213
|
+
if (!ctx.error || ctx.error.name !== 'AbortError') {
|
|
214
|
+
return super.error(ctx)
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
asyncEnd (ctx) {
|
|
219
|
+
ctx.res = ctx.result
|
|
220
|
+
return this.finish(ctx)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
configure (config) {
|
|
224
|
+
return super.configure(normalizeConfig(config))
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Add configured headers to span with appropriate tags
|
|
229
|
+
function addConfiguredHeaders (span, rawHeaders, configuredHeaders, headerType) {
|
|
230
|
+
const headers = normalizeHeaders(rawHeaders)
|
|
231
|
+
|
|
232
|
+
for (const [key, tag] of configuredHeaders) {
|
|
233
|
+
const value = headers[key]
|
|
234
|
+
if (value) {
|
|
235
|
+
span.setTag(tag || `${headerType}.${key}`, value)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
8
238
|
}
|
|
9
239
|
|
|
240
|
+
// Normalize headers to an object, handling different undici formats:
|
|
241
|
+
// - Array format: alternating key-value pairs (undici >= 6.0.0)
|
|
242
|
+
// - String format: HTTP header lines like "key: value\r\n" (undici 5.x)
|
|
243
|
+
// - Object format: already a headers object
|
|
244
|
+
function normalizeHeaders (headers) {
|
|
245
|
+
if (!headers) return {}
|
|
246
|
+
|
|
247
|
+
// String format (undici 5.x): "key: value\r\nkey2: value2\r\n"
|
|
248
|
+
if (typeof headers === 'string') {
|
|
249
|
+
const result = {}
|
|
250
|
+
const lines = headers.split('\r\n')
|
|
251
|
+
for (const line of lines) {
|
|
252
|
+
if (!line) continue
|
|
253
|
+
const colonIndex = line.indexOf(':')
|
|
254
|
+
if (colonIndex > 0) {
|
|
255
|
+
const key = line.slice(0, colonIndex).toLowerCase().trim()
|
|
256
|
+
const value = line.slice(colonIndex + 1).trim()
|
|
257
|
+
result[key] = value
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return result
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Array format (undici >= 6.0.0): alternating key-value pairs
|
|
264
|
+
if (Array.isArray(headers)) {
|
|
265
|
+
const result = {}
|
|
266
|
+
for (let i = 0; i < headers.length; i += 2) {
|
|
267
|
+
const key = headers[i]
|
|
268
|
+
if (typeof key === 'string') {
|
|
269
|
+
result[key.toLowerCase()] = headers[i + 1]
|
|
270
|
+
} else if (Buffer.isBuffer(key)) {
|
|
271
|
+
result[key.toString().toLowerCase()] = headers[i + 1]?.toString?.() || headers[i + 1]
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return result
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Object format: use as-is
|
|
278
|
+
return headers
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function normalizeConfig (config) {
|
|
282
|
+
const validateStatus = getStatusValidator(config)
|
|
283
|
+
const hooks = getHooks(config)
|
|
284
|
+
|
|
285
|
+
return {
|
|
286
|
+
...config,
|
|
287
|
+
validateStatus,
|
|
288
|
+
hooks
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function getStatusValidator (config) {
|
|
293
|
+
if (typeof config.validateStatus === 'function') {
|
|
294
|
+
return config.validateStatus
|
|
295
|
+
} else if (Object.hasOwn(config, 'validateStatus')) {
|
|
296
|
+
log.error('Expected `validateStatus` to be a function.')
|
|
297
|
+
}
|
|
298
|
+
return defaultValidateStatus
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function defaultValidateStatus (code) {
|
|
302
|
+
return code < 400 || code >= 500
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function getHooks (config) {
|
|
306
|
+
const request = config.hooks?.request ?? noop
|
|
307
|
+
|
|
308
|
+
return { request }
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function noop () {}
|
|
312
|
+
|
|
10
313
|
module.exports = UndiciPlugin
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
|
|
4
4
|
const { storage } = require('../../datadog-core')
|
|
5
|
-
const {
|
|
5
|
+
const { getValueFromEnvSources } = require('../../dd-trace/src/config/helper')
|
|
6
6
|
|
|
7
7
|
const {
|
|
8
8
|
TEST_STATUS,
|
|
@@ -281,11 +281,11 @@ class VitestPlugin extends CiPlugin {
|
|
|
281
281
|
this.addBind('ci:vitest:test-suite:start', (ctx) => {
|
|
282
282
|
const { testSuiteAbsolutePath, frameworkVersion } = ctx
|
|
283
283
|
|
|
284
|
-
this.command =
|
|
284
|
+
this.command = getValueFromEnvSources('DD_CIVISIBILITY_TEST_COMMAND')
|
|
285
285
|
this.frameworkVersion = frameworkVersion
|
|
286
286
|
const testSessionSpanContext = this.tracer.extract('text_map', {
|
|
287
|
-
'x-datadog-trace-id':
|
|
288
|
-
'x-datadog-parent-id':
|
|
287
|
+
'x-datadog-trace-id': getValueFromEnvSources('DD_CIVISIBILITY_TEST_SESSION_ID'),
|
|
288
|
+
'x-datadog-parent-id': getValueFromEnvSources('DD_CIVISIBILITY_TEST_MODULE_ID')
|
|
289
289
|
})
|
|
290
290
|
|
|
291
291
|
const trimmedCommand = DD_MAJOR < 6 ? this.command : 'vitest run'
|
|
@@ -405,7 +405,7 @@ class VitestPlugin extends CiPlugin {
|
|
|
405
405
|
finishAllTraceSpans(this.testSessionSpan)
|
|
406
406
|
this.telemetry.count(TELEMETRY_TEST_SESSION, {
|
|
407
407
|
provider: this.ciProviderName,
|
|
408
|
-
autoInjected: !!
|
|
408
|
+
autoInjected: !!getValueFromEnvSources('DD_CIVISIBILITY_AUTO_INSTRUMENTATION_PROVIDER')
|
|
409
409
|
})
|
|
410
410
|
this.tracer._exporter.flush(onFinish)
|
|
411
411
|
})
|
|
@@ -10,6 +10,25 @@ if (!global._ddtrace) {
|
|
|
10
10
|
writable: true
|
|
11
11
|
})
|
|
12
12
|
|
|
13
|
+
const ddTraceSymbol = Symbol.for('dd-trace')
|
|
14
|
+
|
|
15
|
+
Object.defineProperty(globalThis, ddTraceSymbol, {
|
|
16
|
+
value: {
|
|
17
|
+
beforeExitHandlers: new Set(),
|
|
18
|
+
},
|
|
19
|
+
enumerable: false,
|
|
20
|
+
configurable: true, // Allow this to be overridden by loading the tracer
|
|
21
|
+
writable: false
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
process.once('beforeExit', function mainBeforeExit () {
|
|
25
|
+
if (globalThis[ddTraceSymbol]?.beforeExitHandlers) {
|
|
26
|
+
for (const handler of globalThis[ddTraceSymbol].beforeExitHandlers) {
|
|
27
|
+
handler()
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
|
|
13
32
|
global._ddtrace.default = global._ddtrace
|
|
14
33
|
global._ddtrace.tracer = global._ddtrace
|
|
15
34
|
}
|
|
@@ -12,7 +12,7 @@ const { getName } = require('../telemetry/verbosity')
|
|
|
12
12
|
const telemetry = require('../telemetry')
|
|
13
13
|
const log = require('../../../log')
|
|
14
14
|
const orchestrionConfig = require('../../../../../datadog-instrumentations/src/orchestrion-config')
|
|
15
|
-
const { getEnvironmentVariable } = require('../../../config
|
|
15
|
+
const { getEnvironmentVariable } = require('../../../config/helper')
|
|
16
16
|
const { LOG_MESSAGE, REWRITTEN_MESSAGE } = require('./constants')
|
|
17
17
|
const { incrementTelemetryIfNeeded } = require('./rewriter-telemetry')
|
|
18
18
|
const { csiMethods } = require('./csi-methods')
|
|
@@ -73,16 +73,14 @@ function handleUncaughtExceptionMonitor (error) {
|
|
|
73
73
|
}
|
|
74
74
|
} else {
|
|
75
75
|
const cleanUp = removeAllListeners(process, 'uncaughtException')
|
|
76
|
-
const handler = () => {
|
|
77
|
-
process.removeListener('uncaughtException', handler)
|
|
78
|
-
}
|
|
76
|
+
const handler = () => {}
|
|
79
77
|
|
|
80
78
|
setTimeout(() => {
|
|
81
79
|
process.removeListener('uncaughtException', handler)
|
|
82
80
|
cleanUp()
|
|
83
81
|
})
|
|
84
82
|
|
|
85
|
-
process.
|
|
83
|
+
process.once('uncaughtException', handler)
|
|
86
84
|
}
|
|
87
85
|
}
|
|
88
86
|
|
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
// Modeled after https://github.com/DataDog/libdatadog/blob/f3994857a59bb5679a65967138c5a3aec418a65f/ddcommon/src/azure_app_services.rs
|
|
4
4
|
|
|
5
5
|
const os = require('os')
|
|
6
|
-
const {
|
|
6
|
+
const {
|
|
7
|
+
getEnvironmentVariable,
|
|
8
|
+
getEnvironmentVariables,
|
|
9
|
+
getValueFromEnvSources
|
|
10
|
+
} = require('./config/helper')
|
|
7
11
|
const { getIsAzureFunction, getIsFlexConsumptionAzureFunction } = require('./serverless')
|
|
8
12
|
|
|
9
13
|
function extractSubscriptionID (ownerName) {
|
|
@@ -37,8 +41,6 @@ function trimObject (obj) {
|
|
|
37
41
|
function buildMetadata () {
|
|
38
42
|
const {
|
|
39
43
|
COMPUTERNAME,
|
|
40
|
-
DD_AAS_DOTNET_EXTENSION_VERSION,
|
|
41
|
-
DD_AZURE_RESOURCE_GROUP,
|
|
42
44
|
FUNCTIONS_EXTENSION_VERSION,
|
|
43
45
|
FUNCTIONS_WORKER_RUNTIME,
|
|
44
46
|
FUNCTIONS_WORKER_RUNTIME_VERSION,
|
|
@@ -49,6 +51,9 @@ function buildMetadata () {
|
|
|
49
51
|
WEBSITE_SITE_NAME
|
|
50
52
|
} = getEnvironmentVariables()
|
|
51
53
|
|
|
54
|
+
const DD_AAS_DOTNET_EXTENSION_VERSION = getValueFromEnvSources('DD_AAS_DOTNET_EXTENSION_VERSION')
|
|
55
|
+
const DD_AZURE_RESOURCE_GROUP = getValueFromEnvSources('DD_AZURE_RESOURCE_GROUP')
|
|
56
|
+
|
|
52
57
|
const subscriptionID = extractSubscriptionID(WEBSITE_OWNER_NAME)
|
|
53
58
|
|
|
54
59
|
const siteName = WEBSITE_SITE_NAME
|
|
@@ -1,41 +1,66 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { storage } = require('../../datadog-core')
|
|
4
|
-
const baggageStorage = storage('baggage')
|
|
5
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Spec (API semantics):
|
|
7
|
+
* - OpenTelemetry Baggage API: https://opentelemetry.io/docs/specs/otel/baggage/api/
|
|
8
|
+
*
|
|
9
|
+
* In-process baggage is a string->string map stored in async local storage.
|
|
10
|
+
* @typedef {import('../../datadog-core/src/storage').Store<string>} BaggageStore
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @type {{ enterWith: (store?: BaggageStore) => void, getStore: () => (BaggageStore | undefined) }}
|
|
15
|
+
*/
|
|
16
|
+
const baggageStorage =
|
|
17
|
+
/** @type {{ enterWith: (store?: BaggageStore) => void, getStore: () => (BaggageStore | undefined) }} */ (
|
|
18
|
+
/** @type {unknown} */ (storage('baggage'))
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
// TODO: Implement metadata https://opentelemetry.io/docs/specs/otel/baggage/api/#set-value
|
|
6
22
|
/**
|
|
7
23
|
* @param {string} key
|
|
8
24
|
* @param {string} value
|
|
25
|
+
* @param {object} [metadata] Not used yet
|
|
9
26
|
*/
|
|
10
|
-
function setBaggageItem (key, value) {
|
|
11
|
-
|
|
12
|
-
|
|
27
|
+
function setBaggageItem (key, value, metadata) {
|
|
28
|
+
if (typeof key !== 'string' || typeof value !== 'string' || key === '') {
|
|
29
|
+
return baggageStorage.getStore() ?? {}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const store = baggageStorage.getStore()
|
|
33
|
+
const newStore = { ...store, [key]: value }
|
|
34
|
+
baggageStorage.enterWith(newStore)
|
|
35
|
+
return newStore
|
|
13
36
|
}
|
|
14
37
|
|
|
15
38
|
/**
|
|
16
39
|
* @param {string} key
|
|
40
|
+
* @returns {string | undefined}
|
|
17
41
|
*/
|
|
18
42
|
function getBaggageItem (key) {
|
|
19
|
-
return
|
|
43
|
+
return baggageStorage.getStore()?.[key]
|
|
20
44
|
}
|
|
21
45
|
|
|
22
46
|
function getAllBaggageItems () {
|
|
23
|
-
return
|
|
47
|
+
return baggageStorage.getStore() ?? {}
|
|
24
48
|
}
|
|
25
49
|
|
|
26
50
|
/**
|
|
27
51
|
* @param {string} keyToRemove
|
|
28
|
-
* @returns {Record<string, unknown>}
|
|
29
52
|
*/
|
|
30
53
|
function removeBaggageItem (keyToRemove) {
|
|
31
|
-
const
|
|
32
|
-
|
|
54
|
+
const store = baggageStorage.getStore() ?? {}
|
|
55
|
+
const { [keyToRemove]: _, ...newBaggage } = store
|
|
56
|
+
baggageStorage.enterWith(newBaggage)
|
|
33
57
|
return newBaggage
|
|
34
58
|
}
|
|
35
59
|
|
|
36
60
|
function removeAllBaggageItems () {
|
|
37
|
-
|
|
38
|
-
|
|
61
|
+
const newContext = /** @type {BaggageStore} */ ({})
|
|
62
|
+
baggageStorage.enterWith(newContext)
|
|
63
|
+
return newContext
|
|
39
64
|
}
|
|
40
65
|
|
|
41
66
|
module.exports = {
|
|
@@ -4,7 +4,7 @@ const { join } = require('path')
|
|
|
4
4
|
const { Worker, threadId: parentThreadId } = require('worker_threads')
|
|
5
5
|
const { randomUUID } = require('crypto')
|
|
6
6
|
const log = require('../../log')
|
|
7
|
-
const { getEnvironmentVariables } = require('../../config
|
|
7
|
+
const { getEnvironmentVariables } = require('../../config/helper')
|
|
8
8
|
const getDebuggerConfig = require('../../debugger/config')
|
|
9
9
|
|
|
10
10
|
const probeIdToResolveBreakpointSet = new Map()
|
|
@@ -74,6 +74,10 @@ class TestVisDynamicInstrumentation {
|
|
|
74
74
|
// for PnP support, hence why we deviate from the DI pattern here.
|
|
75
75
|
// To avoid infinite initialization loops, we're disabling DI and tracing in the worker.
|
|
76
76
|
env: {
|
|
77
|
+
// NOTE: We intentionally use `getEnvironmentVariables()` here (raw env)
|
|
78
|
+
// instead of stable-config resolution helpers. The DI worker is a forked
|
|
79
|
+
// process that should see exactly the parent process's environment, and
|
|
80
|
+
// we explicitly override a few DD_ vars below to disable tracing/DI there.
|
|
77
81
|
...getEnvironmentVariables(),
|
|
78
82
|
DD_CIVISIBILITY_ENABLED: 'false',
|
|
79
83
|
DD_TRACE_ENABLED: 'false',
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const request = require('../../exporters/common/request')
|
|
4
4
|
const id = require('../../id')
|
|
5
5
|
const log = require('../../log')
|
|
6
|
-
const {
|
|
6
|
+
const { getValueFromEnvSources } = require('../../config/helper')
|
|
7
7
|
|
|
8
8
|
const {
|
|
9
9
|
incrementCountMetric,
|
|
@@ -51,7 +51,7 @@ function getKnownTests ({
|
|
|
51
51
|
options.path = `${evpProxyPrefix}/api/v2/ci/libraries/tests`
|
|
52
52
|
options.headers['X-Datadog-EVP-Subdomain'] = 'api'
|
|
53
53
|
} else {
|
|
54
|
-
const apiKey =
|
|
54
|
+
const apiKey = getValueFromEnvSources('DD_API_KEY')
|
|
55
55
|
if (!apiKey) {
|
|
56
56
|
return done(new Error('Known tests were not fetched because Datadog API key is not defined.'))
|
|
57
57
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const request = require('../../../exporters/common/request')
|
|
3
3
|
const log = require('../../../log')
|
|
4
4
|
const { safeJSONStringify } = require('../../../exporters/common/util')
|
|
5
|
-
const {
|
|
5
|
+
const { getValueFromEnvSources } = require('../../../config/helper')
|
|
6
6
|
|
|
7
7
|
const { CoverageCIVisibilityEncoder } = require('../../../encode/coverage-ci-visibility')
|
|
8
8
|
const BaseWriter = require('../../../exporters/common/writer')
|
|
@@ -29,7 +29,7 @@ class Writer extends BaseWriter {
|
|
|
29
29
|
path: '/api/v2/citestcov',
|
|
30
30
|
method: 'POST',
|
|
31
31
|
headers: {
|
|
32
|
-
'dd-api-key':
|
|
32
|
+
'dd-api-key': getValueFromEnvSources('DD_API_KEY'),
|
|
33
33
|
...form.getHeaders()
|
|
34
34
|
},
|
|
35
35
|
timeout: 15_000,
|
|
@@ -3,7 +3,7 @@ const request = require('../../../exporters/common/request')
|
|
|
3
3
|
const log = require('../../../log')
|
|
4
4
|
const { safeJSONStringify } = require('../../../exporters/common/util')
|
|
5
5
|
const { JSONEncoder } = require('../../encode/json-encoder')
|
|
6
|
-
const {
|
|
6
|
+
const { getValueFromEnvSources } = require('../../../config/helper')
|
|
7
7
|
|
|
8
8
|
const BaseWriter = require('../../../exporters/common/writer')
|
|
9
9
|
|
|
@@ -24,7 +24,7 @@ class DynamicInstrumentationLogsWriter extends BaseWriter {
|
|
|
24
24
|
path: '/api/v2/logs',
|
|
25
25
|
method: 'POST',
|
|
26
26
|
headers: {
|
|
27
|
-
'dd-api-key':
|
|
27
|
+
'dd-api-key': getValueFromEnvSources('DD_API_KEY'),
|
|
28
28
|
'Content-Type': 'application/json'
|
|
29
29
|
},
|
|
30
30
|
// TODO: what's a good value for timeout for the logs intake?
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const request = require('../../../exporters/common/request')
|
|
3
3
|
const { safeJSONStringify } = require('../../../exporters/common/util')
|
|
4
4
|
const log = require('../../../log')
|
|
5
|
-
const {
|
|
5
|
+
const { getValueFromEnvSources } = require('../../../config/helper')
|
|
6
6
|
|
|
7
7
|
const { AgentlessCiVisibilityEncoder } = require('../../../encode/agentless-ci-visibility')
|
|
8
8
|
const BaseWriter = require('../../../exporters/common/writer')
|
|
@@ -30,7 +30,7 @@ class Writer extends BaseWriter {
|
|
|
30
30
|
path: '/api/v2/citestcycle',
|
|
31
31
|
method: 'POST',
|
|
32
32
|
headers: {
|
|
33
|
-
'dd-api-key':
|
|
33
|
+
'dd-api-key': getValueFromEnvSources('DD_API_KEY'),
|
|
34
34
|
'Content-Type': 'application/msgpack'
|
|
35
35
|
},
|
|
36
36
|
timeout: 15_000,
|
|
@@ -68,7 +68,7 @@ class CiVisibilityExporter extends AgentInfoExporter {
|
|
|
68
68
|
}
|
|
69
69
|
})
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
const flush = () => {
|
|
72
72
|
if (this._writer) {
|
|
73
73
|
this._writer.flush()
|
|
74
74
|
}
|
|
@@ -78,7 +78,8 @@ class CiVisibilityExporter extends AgentInfoExporter {
|
|
|
78
78
|
if (this._logsWriter) {
|
|
79
79
|
this._logsWriter.flush()
|
|
80
80
|
}
|
|
81
|
-
}
|
|
81
|
+
}
|
|
82
|
+
globalThis[Symbol.for('dd-trace')].beforeExitHandlers.add(flush.bind(this))
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
shouldRequestSkippableSuites () {
|
|
@@ -5,7 +5,7 @@ const path = require('path')
|
|
|
5
5
|
|
|
6
6
|
const FormData = require('../../../exporters/common/form-data')
|
|
7
7
|
const request = require('../../../exporters/common/request')
|
|
8
|
-
const {
|
|
8
|
+
const { getValueFromEnvSources } = require('../../../config/helper')
|
|
9
9
|
|
|
10
10
|
const log = require('../../../log')
|
|
11
11
|
const { isFalse } = require('../../../util')
|
|
@@ -51,7 +51,7 @@ function getCommonRequestOptions (url) {
|
|
|
51
51
|
return {
|
|
52
52
|
method: 'POST',
|
|
53
53
|
headers: {
|
|
54
|
-
'dd-api-key':
|
|
54
|
+
'dd-api-key': getValueFromEnvSources('DD_API_KEY')
|
|
55
55
|
},
|
|
56
56
|
timeout: 15_000,
|
|
57
57
|
url
|
|
@@ -288,7 +288,7 @@ function sendGitMetadata (url, { isEvpProxy, evpProxyPrefix }, configRepositoryU
|
|
|
288
288
|
}
|
|
289
289
|
// Otherwise we unshallow and get commits to upload again
|
|
290
290
|
log.debug('It is shallow clone, unshallowing...')
|
|
291
|
-
if (!isFalse(
|
|
291
|
+
if (!isFalse(getValueFromEnvSources('DD_CIVISIBILITY_GIT_UNSHALLOW_ENABLED'))) {
|
|
292
292
|
unshallowRepository(false)
|
|
293
293
|
}
|
|
294
294
|
|