dd-trace 5.99.0 → 5.100.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 +0 -1
- package/package.json +24 -5
- package/packages/datadog-instrumentations/src/cucumber.js +69 -5
- package/packages/datadog-instrumentations/src/express.js +3 -2
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/hono.js +15 -4
- package/packages/datadog-instrumentations/src/jest.js +89 -63
- package/packages/datadog-instrumentations/src/mocha/main.js +18 -22
- package/packages/datadog-instrumentations/src/mocha/utils.js +114 -96
- package/packages/datadog-instrumentations/src/mocha/worker.js +2 -2
- package/packages/datadog-instrumentations/src/path-to-regexp.js +44 -0
- package/packages/datadog-instrumentations/src/playwright.js +108 -18
- package/packages/datadog-instrumentations/src/router.js +53 -33
- package/packages/datadog-instrumentations/src/vitest.js +76 -30
- package/packages/datadog-plugin-aws-sdk/src/base.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +1 -1
- package/packages/datadog-plugin-bullmq/src/consumer.js +3 -2
- package/packages/datadog-plugin-bullmq/src/producer.js +25 -11
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +32 -9
- package/packages/datadog-plugin-cypress/src/support.js +22 -21
- package/packages/datadog-plugin-dd-trace-api/src/index.js +1 -1
- package/packages/datadog-plugin-graphql/src/utils.js +2 -2
- package/packages/datadog-plugin-grpc/src/client.js +1 -1
- package/packages/datadog-plugin-grpc/src/server.js +1 -1
- package/packages/datadog-plugin-memcached/src/index.js +1 -1
- package/packages/datadog-plugin-mongodb-core/src/index.js +2 -3
- package/packages/datadog-plugin-playwright/src/index.js +6 -0
- package/packages/datadog-plugin-router/src/index.js +13 -0
- package/packages/dd-trace/index.js +4 -3
- package/packages/dd-trace/src/aiguard/sdk.js +2 -2
- package/packages/dd-trace/src/appsec/blocking.js +18 -6
- package/packages/dd-trace/src/appsec/graphql.js +1 -1
- package/packages/dd-trace/src/baggage.js +26 -13
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +1 -1
- package/packages/dd-trace/src/config/generated-config-types.d.ts +45 -69
- package/packages/dd-trace/src/config/index.js +13 -12
- package/packages/dd-trace/src/config/normalize-service.js +31 -0
- package/packages/dd-trace/src/config/supported-configurations.json +31 -76
- package/packages/dd-trace/src/debugger/config.js +1 -1
- package/packages/dd-trace/src/dogstatsd.js +5 -8
- package/packages/dd-trace/src/encode/0.4.js +1 -1
- package/packages/dd-trace/src/encode/tags-processors.js +3 -3
- package/packages/dd-trace/src/exporter.js +1 -1
- package/packages/dd-trace/src/git_metadata_tagger.js +1 -1
- package/packages/dd-trace/src/heap_snapshots.js +4 -4
- package/packages/dd-trace/src/llmobs/constants/tags.js +3 -0
- package/packages/dd-trace/src/llmobs/sdk.js +21 -1
- package/packages/dd-trace/src/llmobs/span_processor.js +14 -1
- package/packages/dd-trace/src/llmobs/writers/base.js +7 -1
- package/packages/dd-trace/src/llmobs/writers/spans.js +1 -1
- package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +2 -2
- package/packages/dd-trace/src/opentelemetry/context_manager.js +11 -8
- package/packages/dd-trace/src/opentelemetry/logs/index.js +5 -5
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +6 -6
- package/packages/dd-trace/src/opentelemetry/span-helpers.js +170 -0
- package/packages/dd-trace/src/opentelemetry/span.js +14 -42
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +1 -1
- package/packages/dd-trace/src/opentelemetry/tracer.js +11 -36
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +44 -23
- package/packages/dd-trace/src/opentracing/propagation/tracestate.js +42 -12
- package/packages/dd-trace/src/opentracing/span.js +4 -3
- package/packages/dd-trace/src/plugin_manager.js +6 -6
- package/packages/dd-trace/src/plugins/log_plugin.js +1 -1
- package/packages/dd-trace/src/plugins/util/ci.js +119 -32
- package/packages/dd-trace/src/plugins/util/test.js +295 -29
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +2 -2
- package/packages/dd-trace/src/propagation-hash/index.js +1 -1
- package/packages/dd-trace/src/proxy.js +9 -9
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +1 -1
- package/packages/dd-trace/src/span_processor.js +1 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +7 -5
- package/packages/dd-trace/src/tracer_metadata.js +1 -1
- package/vendor/dist/path-to-regexp/LICENSE +0 -21
- package/vendor/dist/path-to-regexp/index.js +0 -1
|
@@ -1,19 +1,49 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
// W3C Trace Context §3.3.1.2: max 32 list-members.
|
|
4
|
+
// https://www.w3.org/TR/trace-context/#tracestate-header-field-values
|
|
5
|
+
const MAX_LIST_MEMBERS = 32
|
|
6
|
+
const WHITESPACE = /[ \t]/
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Parse a separator-delimited string into key/value entries.
|
|
10
|
+
*
|
|
11
|
+
* @param {string} value
|
|
12
|
+
* @param {string} fieldSeparator Between entries.
|
|
13
|
+
* @param {string} pairSeparator Between key and value within an entry.
|
|
14
|
+
* @param {boolean} rejectValueTabs Drop entries whose value contains an internal tab.
|
|
15
|
+
* @returns {[string, string][]} Entries in reverse of wire order.
|
|
16
|
+
*/
|
|
17
|
+
function parseEntries (value, fieldSeparator, pairSeparator, rejectValueTabs) {
|
|
18
|
+
const segments = value.split(fieldSeparator)
|
|
19
|
+
segments.length = Math.min(segments.length, MAX_LIST_MEMBERS)
|
|
20
|
+
|
|
21
|
+
// TODO: We should extract dd no matter at what position and move it to the front of the list.
|
|
22
|
+
// Extract up 31 additional entries.
|
|
23
|
+
const entries = []
|
|
24
|
+
for (let index = 0; index < segments.length; index++) {
|
|
25
|
+
const segment = segments[index]
|
|
26
|
+
const splitIndex = segment.indexOf(pairSeparator)
|
|
27
|
+
if (splitIndex === -1) continue
|
|
28
|
+
const key = segment.slice(0, splitIndex).trim()
|
|
29
|
+
if (!key || WHITESPACE.test(key)) continue
|
|
30
|
+
// W3C §3.3.1.3.2: value = 0*255(chr) nblk-chr; chr = %x20 / nblk-chr (no tab).
|
|
31
|
+
// Leading 0x20 is part of value; trailing whitespace is OWS.
|
|
32
|
+
const entryValue = segment.slice(splitIndex + 1).trimEnd()
|
|
33
|
+
if (!entryValue || rejectValueTabs && entryValue.includes('\t')) continue
|
|
34
|
+
entries.push([key, entryValue])
|
|
9
35
|
}
|
|
36
|
+
// Reverse so the Map's insertion order is reverse of wire order. `toString`
|
|
37
|
+
// prepends as it iterates, which yields the original wire order back.
|
|
38
|
+
entries.reverse()
|
|
39
|
+
return entries
|
|
40
|
+
}
|
|
10
41
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
42
|
+
function fromString (Type, value, fieldSeparator, pairSeparator, rejectValueTabs) {
|
|
43
|
+
if (typeof value !== 'string' || !value.length) {
|
|
44
|
+
return new Type()
|
|
14
45
|
}
|
|
15
|
-
|
|
16
|
-
return new Type(values)
|
|
46
|
+
return new Type(parseEntries(value, fieldSeparator, pairSeparator, rejectValueTabs))
|
|
17
47
|
}
|
|
18
48
|
|
|
19
49
|
function toString (map, pairSeparator, fieldSeparator) {
|
|
@@ -52,7 +82,7 @@ class TraceStateData extends Map {
|
|
|
52
82
|
}
|
|
53
83
|
|
|
54
84
|
static fromString (value) {
|
|
55
|
-
return fromString(TraceStateData,
|
|
85
|
+
return fromString(TraceStateData, value, ';', ':', false)
|
|
56
86
|
}
|
|
57
87
|
|
|
58
88
|
toString () {
|
|
@@ -92,7 +122,7 @@ class TraceState extends Map {
|
|
|
92
122
|
}
|
|
93
123
|
|
|
94
124
|
static fromString (value) {
|
|
95
|
-
return fromString(TraceState,
|
|
125
|
+
return fromString(TraceState, value, ',', '=', true)
|
|
96
126
|
}
|
|
97
127
|
|
|
98
128
|
toString () {
|
|
@@ -112,7 +112,7 @@ class DatadogSpan {
|
|
|
112
112
|
// even `Span` itself in this case.
|
|
113
113
|
//
|
|
114
114
|
// TODO: Refactor Tracer/Span + tests to avoid having to do nullish checks.
|
|
115
|
-
if (tracer?._config?.
|
|
115
|
+
if (tracer?._config?.DD_TRACE_SPAN_LEAK_DEBUG > 0) {
|
|
116
116
|
require('../spanleak').addSpan(this, operationName)
|
|
117
117
|
}
|
|
118
118
|
|
|
@@ -336,7 +336,8 @@ class DatadogSpan {
|
|
|
336
336
|
let startTime
|
|
337
337
|
|
|
338
338
|
let baggage = {}
|
|
339
|
-
|
|
339
|
+
const propagationBehavior = this._parentTracer?._config?.DD_TRACE_PROPAGATION_BEHAVIOR_EXTRACT
|
|
340
|
+
if (parent && parent._isRemote && propagationBehavior !== 'continue') {
|
|
340
341
|
baggage = parent._baggageItems
|
|
341
342
|
parent = null
|
|
342
343
|
}
|
|
@@ -375,7 +376,7 @@ class DatadogSpan {
|
|
|
375
376
|
.padEnd(16, '0')
|
|
376
377
|
}
|
|
377
378
|
|
|
378
|
-
if (
|
|
379
|
+
if (propagationBehavior === 'restart') {
|
|
379
380
|
spanContext._baggageItems = baggage
|
|
380
381
|
}
|
|
381
382
|
}
|
|
@@ -163,9 +163,9 @@ module.exports = class PluginManager {
|
|
|
163
163
|
dsmEnabled,
|
|
164
164
|
clientIpEnabled,
|
|
165
165
|
clientIpHeader,
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
DD_TRACE_MEMCACHED_COMMAND_ENABLED,
|
|
167
|
+
DD_TEST_SESSION_NAME,
|
|
168
|
+
DD_AGENTLESS_LOG_SUBMISSION_ENABLED,
|
|
169
169
|
isTestDynamicInstrumentationEnabled,
|
|
170
170
|
isServiceUserProvided,
|
|
171
171
|
middlewareTracingEnabled,
|
|
@@ -180,13 +180,13 @@ module.exports = class PluginManager {
|
|
|
180
180
|
codeOriginForSpans,
|
|
181
181
|
dbmPropagationMode,
|
|
182
182
|
dsmEnabled,
|
|
183
|
-
|
|
183
|
+
DD_TRACE_MEMCACHED_COMMAND_ENABLED,
|
|
184
184
|
site,
|
|
185
185
|
url,
|
|
186
186
|
headers: headerTags || [],
|
|
187
187
|
clientIpHeader,
|
|
188
|
-
|
|
189
|
-
|
|
188
|
+
DD_TEST_SESSION_NAME,
|
|
189
|
+
DD_AGENTLESS_LOG_SUBMISSION_ENABLED,
|
|
190
190
|
isTestDynamicInstrumentationEnabled,
|
|
191
191
|
isServiceUserProvided,
|
|
192
192
|
traceWebsocketMessagesEnabled,
|
|
@@ -51,7 +51,7 @@ module.exports = class LogPlugin extends Plugin {
|
|
|
51
51
|
configure (config) {
|
|
52
52
|
return super.configure({
|
|
53
53
|
...config,
|
|
54
|
-
enabled: config.enabled && (config.logInjection || config.
|
|
54
|
+
enabled: config.enabled && (config.logInjection || config.DD_AGENTLESS_LOG_SUBMISSION_ENABLED),
|
|
55
55
|
})
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -103,42 +103,129 @@ function getGitHubEventPayload () {
|
|
|
103
103
|
return JSON.parse(readFileSync(path, 'utf8'))
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
const uniq = (items) => [...new Set(items)]
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* GitHub runner diagnostic logs live under the runner installation directory in `_diag`.
|
|
110
|
+
* On many runners, we can derive the installation directory from RUNNER_TEMP:
|
|
111
|
+
* <runnerRoot>/_work/_temp -> <runnerRoot>/_diag
|
|
112
|
+
*
|
|
113
|
+
* This is much more robust than relying on hardcoded paths, especially on self-hosted runners
|
|
114
|
+
* and GHES environments where the runner may be installed under arbitrary directories/users.
|
|
115
|
+
*/
|
|
116
|
+
function getGithubDiagnosticDirsFromEnv (runnerTemp) {
|
|
117
|
+
const dirs = []
|
|
118
|
+
|
|
119
|
+
if (runnerTemp) {
|
|
120
|
+
// RUNNER_TEMP is typically: <runnerRoot>/_work/_temp
|
|
121
|
+
const runnerRoot = path.resolve(runnerTemp, '..', '..').replaceAll(path.sep, '/')
|
|
122
|
+
// Bounded-depth patterns cover every runner layout we've observed
|
|
123
|
+
// (including cached/<version>/_diag) without assuming a `cached` wrapper
|
|
124
|
+
// and without walking the whole tree.
|
|
125
|
+
dirs.push(
|
|
126
|
+
path.posix.join(runnerRoot, 'actions-runner', '_diag'),
|
|
127
|
+
`${runnerRoot}/actions-runner/*/_diag`,
|
|
128
|
+
`${runnerRoot}/actions-runner/*/*/_diag`,
|
|
129
|
+
path.posix.join(runnerRoot, '_diag'),
|
|
130
|
+
`${runnerRoot}/*/_diag`,
|
|
131
|
+
`${runnerRoot}/*/*/_diag`
|
|
132
|
+
)
|
|
133
|
+
}
|
|
108
134
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
// Windows hosted: C:\actions-runner\_work\_temp
|
|
112
|
-
// Self-hosted (unix): /opt/actions-runner/_work/_temp
|
|
135
|
+
return uniq(dirs.filter(Boolean))
|
|
136
|
+
}
|
|
113
137
|
|
|
114
|
-
|
|
115
|
-
|
|
138
|
+
function hasMagicChars (str) {
|
|
139
|
+
return str.includes('*') || str.includes('?')
|
|
140
|
+
}
|
|
116
141
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
]
|
|
142
|
+
// Expands a glob pattern with only `*`/`?` at path-segment boundaries (no `**`)
|
|
143
|
+
// into matching concrete paths using readdirSync — no external dependency needed.
|
|
144
|
+
function expandGlobPattern (pattern) {
|
|
145
|
+
const parts = pattern.split(/[/\\]/)
|
|
146
|
+
const wildcardIdx = parts.findIndex(p => hasMagicChars(p))
|
|
147
|
+
if (wildcardIdx === -1) return [pattern]
|
|
123
148
|
|
|
124
|
-
const
|
|
149
|
+
const prefix = parts.slice(0, wildcardIdx).join('/')
|
|
150
|
+
const results = []
|
|
125
151
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
152
|
+
function walk (dir, segIdx) {
|
|
153
|
+
if (segIdx === parts.length) {
|
|
154
|
+
results.push(dir)
|
|
155
|
+
return
|
|
156
|
+
}
|
|
157
|
+
const seg = parts[segIdx]
|
|
158
|
+
if (!hasMagicChars(seg)) {
|
|
159
|
+
walk(`${dir}/${seg}`, segIdx + 1)
|
|
160
|
+
return
|
|
161
|
+
}
|
|
162
|
+
try {
|
|
163
|
+
const re = new RegExp(
|
|
164
|
+
'^' + seg.replaceAll(/[.+^${}()|[\]\\]/g, String.raw`\$&`).replaceAll('*', String.raw`[^/\\]*`).replaceAll('?', String.raw`[^/\\]`) + '$'
|
|
165
|
+
)
|
|
166
|
+
for (const entry of readdirSync(dir)) {
|
|
167
|
+
if (re.test(entry)) {
|
|
168
|
+
walk(`${dir}/${entry}`, segIdx + 1)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
} catch {
|
|
172
|
+
// directory doesn't exist or isn't accessible
|
|
173
|
+
}
|
|
138
174
|
}
|
|
139
175
|
|
|
140
|
-
|
|
141
|
-
|
|
176
|
+
walk(prefix, wildcardIdx)
|
|
177
|
+
return results
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Expands a mixed list of literal directories and glob patterns into concrete
|
|
182
|
+
* directories. Literals pass through unchanged (existence is checked later).
|
|
183
|
+
*/
|
|
184
|
+
function expandDiagnosticDirCandidates (candidates) {
|
|
185
|
+
const expanded = []
|
|
186
|
+
for (const candidate of candidates) {
|
|
187
|
+
if (hasMagicChars(candidate)) {
|
|
188
|
+
expanded.push(...expandGlobPattern(candidate))
|
|
189
|
+
} else {
|
|
190
|
+
expanded.push(candidate)
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return uniq(expanded)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const githubWellKnownDiagnosticDirsUnix = [
|
|
198
|
+
'/home/runner/actions-runner/_diag',
|
|
199
|
+
'/opt/actions-runner/_diag',
|
|
200
|
+
]
|
|
201
|
+
const githubWellKnownDiagnosticDirsWin = [
|
|
202
|
+
'C:/actions-runner/_diag',
|
|
203
|
+
]
|
|
204
|
+
|
|
205
|
+
// Glob patterns covering layouts that namespace `_diag` under one or two
|
|
206
|
+
// intermediate directories. This includes both observed SaaS layouts
|
|
207
|
+
// (<runnerRoot>/cached/_diag pre-2.334.0, <runnerRoot>/cached/<version>/_diag
|
|
208
|
+
// since v2.334.0) and hypothetical future layouts that follow the same shape
|
|
209
|
+
// without a `cached` wrapper (e.g. <runnerRoot>/<version>/_diag). Depth is
|
|
210
|
+
// bounded on purpose: `*` matches a single segment, so no filesystem walk.
|
|
211
|
+
const githubWellKnownDiagnosticDirPatternsUnix = [
|
|
212
|
+
'/home/runner/actions-runner/*/_diag',
|
|
213
|
+
'/home/runner/actions-runner/*/*/_diag',
|
|
214
|
+
]
|
|
215
|
+
const githubWellKnownDiagnosticDirPatternsWin = ['C:/actions-runner/*/_diag', 'C:/actions-runner/*/*/_diag']
|
|
216
|
+
|
|
217
|
+
const githubJobIDRegex = /"job":\s*{[\s\S]*?"v"\s*:\s*(\d+)(?:\.0)?/
|
|
218
|
+
|
|
219
|
+
function getJobIDFromDiagFile () {
|
|
220
|
+
const runnerTemp = getValueFromEnvSources('RUNNER_TEMP')
|
|
221
|
+
if (!runnerTemp || !existsSync(runnerTemp)) { return null }
|
|
222
|
+
|
|
223
|
+
const isWin = process.platform === 'win32'
|
|
224
|
+
const patterns = isWin ? githubWellKnownDiagnosticDirPatternsWin : githubWellKnownDiagnosticDirPatternsUnix
|
|
225
|
+
const literals = isWin ? githubWellKnownDiagnosticDirsWin : githubWellKnownDiagnosticDirsUnix
|
|
226
|
+
const possibleDiagsPaths = expandDiagnosticDirCandidates([
|
|
227
|
+
...getGithubDiagnosticDirsFromEnv(runnerTemp), ...patterns, ...literals,
|
|
228
|
+
])
|
|
142
229
|
|
|
143
230
|
// This will hold the names of the worker log files that (potentially) contain the Job ID
|
|
144
231
|
let workerLogFiles = []
|
|
@@ -177,7 +264,7 @@ function getJobIDFromDiagFile (runnerTemp) {
|
|
|
177
264
|
const filePath = path.posix.join(chosenDiagPath, logFile)
|
|
178
265
|
const content = readFileSync(filePath, 'utf8')
|
|
179
266
|
|
|
180
|
-
const match = content.match(
|
|
267
|
+
const match = content.match(githubJobIDRegex)
|
|
181
268
|
|
|
182
269
|
// match[1] is the captured group with the display name
|
|
183
270
|
if (match && match[1]) { return match[1] }
|
|
@@ -188,6 +275,7 @@ function getJobIDFromDiagFile (runnerTemp) {
|
|
|
188
275
|
|
|
189
276
|
module.exports = {
|
|
190
277
|
normalizeRef,
|
|
278
|
+
expandGlobPattern,
|
|
191
279
|
getJobIDFromDiagFile,
|
|
192
280
|
getCIMetadata () {
|
|
193
281
|
const env = getEnvironmentVariables()
|
|
@@ -366,7 +454,6 @@ module.exports = {
|
|
|
366
454
|
GITHUB_RUN_ATTEMPT,
|
|
367
455
|
GITHUB_JOB,
|
|
368
456
|
GITHUB_BASE_REF,
|
|
369
|
-
RUNNER_TEMP,
|
|
370
457
|
JOB_CHECK_RUN_ID,
|
|
371
458
|
} = env
|
|
372
459
|
|
|
@@ -378,7 +465,7 @@ module.exports = {
|
|
|
378
465
|
}
|
|
379
466
|
|
|
380
467
|
// Build the job url extracting the job ID. If extraction fails, job url is constructed as a generalized url
|
|
381
|
-
const GITHUB_JOB_ID = JOB_CHECK_RUN_ID ?? getJobIDFromDiagFile(
|
|
468
|
+
const GITHUB_JOB_ID = JOB_CHECK_RUN_ID ?? getJobIDFromDiagFile()
|
|
382
469
|
const jobUrl =
|
|
383
470
|
GITHUB_JOB_ID === null
|
|
384
471
|
? `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/commit/${GITHUB_SHA}/checks`
|