dd-trace 5.105.0 → 5.106.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/package.json +1 -1
- package/packages/datadog-instrumentations/src/aws-sdk.js +3 -2
- package/packages/datadog-instrumentations/src/cucumber-worker-threads.js +19 -0
- package/packages/datadog-instrumentations/src/cucumber.js +312 -152
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +218 -4
- package/packages/dd-trace/src/id.js +15 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +91 -5
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +43 -21
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +22 -3
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +2 -10
- package/packages/dd-trace/src/opentracing/span_context.js +1 -3
- package/packages/dd-trace/src/profiling/config.js +10 -23
- package/packages/dd-trace/src/profiling/exporters/agent.js +11 -10
- package/packages/dd-trace/src/profiling/profiler.js +19 -9
- package/packages/dd-trace/src/profiling/profilers/wall.js +2 -3
|
@@ -5,6 +5,7 @@ const { pathToFileURL } = require('url')
|
|
|
5
5
|
|
|
6
6
|
const satisfies = require('../../../../vendor/dist/semifies')
|
|
7
7
|
const getGitMetadata = require('../git_metadata')
|
|
8
|
+
const log = require('../log')
|
|
8
9
|
const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../plugins/util/tags')
|
|
9
10
|
const { getIsAzureFunction } = require('../serverless')
|
|
10
11
|
const { getAzureTagsFromMetadata, getAzureAppMetadata, getAzureFunctionMetadata } = require('../azure_metadata')
|
|
@@ -14,7 +15,6 @@ const { isACFActive } = require('../../../datadog-core/src/storage')
|
|
|
14
15
|
|
|
15
16
|
const { AgentExporter } = require('./exporters/agent')
|
|
16
17
|
const { FileExporter } = require('./exporters/file')
|
|
17
|
-
const { ConsoleLogger } = require('./loggers/console')
|
|
18
18
|
const WallProfiler = require('./profilers/wall')
|
|
19
19
|
const SpaceProfiler = require('./profilers/space')
|
|
20
20
|
const EventsProfiler = require('./profilers/events')
|
|
@@ -54,7 +54,6 @@ class Config {
|
|
|
54
54
|
this.pprofPrefix = options.DD_PROFILING_PPROF_PREFIX
|
|
55
55
|
this.v8ProfilerBugWorkaroundEnabled = options.DD_PROFILING_V8_PROFILER_BUG_WORKAROUND
|
|
56
56
|
|
|
57
|
-
this.logger = ensureLogger(options.logger)
|
|
58
57
|
this.url = getAgentUrl(options)
|
|
59
58
|
|
|
60
59
|
this.libraryInjected = !!options.DD_INJECTION_ENABLED
|
|
@@ -73,7 +72,7 @@ class Config {
|
|
|
73
72
|
const heapLimitExtensionSize = options.DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE
|
|
74
73
|
const maxHeapExtensionCount = options.DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT
|
|
75
74
|
const exportStrategies = oomMonitoringEnabled
|
|
76
|
-
? ensureOOMExportStrategies(options.DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES
|
|
75
|
+
? ensureOOMExportStrategies(options.DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES)
|
|
77
76
|
: []
|
|
78
77
|
const exportCommand = oomMonitoringEnabled ? buildExportCommand(this) : undefined
|
|
79
78
|
this.oomMonitoring = {
|
|
@@ -102,7 +101,7 @@ class Config {
|
|
|
102
101
|
if (level !== undefined) {
|
|
103
102
|
const maxLevel = { gzip: 9, zstd: 22 }[uploadCompression]
|
|
104
103
|
if (level > maxLevel) {
|
|
105
|
-
|
|
104
|
+
log.warn('Invalid compression level %d. Will use %d.', level, maxLevel)
|
|
106
105
|
level = maxLevel
|
|
107
106
|
}
|
|
108
107
|
}
|
|
@@ -119,8 +118,7 @@ class Config {
|
|
|
119
118
|
|
|
120
119
|
const that = this
|
|
121
120
|
function turnOffAsyncContextFrame (msg) {
|
|
122
|
-
|
|
123
|
-
`DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED was set ${msg}, it will have no effect.`)
|
|
121
|
+
log.warn('DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED was set %s, it will have no effect.', msg)
|
|
124
122
|
that.asyncContextFrameEnabled = false
|
|
125
123
|
}
|
|
126
124
|
|
|
@@ -215,18 +213,18 @@ function getProfilers ({
|
|
|
215
213
|
return profilersArray
|
|
216
214
|
}
|
|
217
215
|
|
|
218
|
-
function getExportStrategy (name
|
|
216
|
+
function getExportStrategy (name) {
|
|
219
217
|
const strategy = Object.values(oomExportStrategies).find(value => value === name)
|
|
220
218
|
if (strategy === undefined) {
|
|
221
|
-
|
|
219
|
+
log.error('Unknown oom export strategy "%s"', name)
|
|
222
220
|
}
|
|
223
221
|
return strategy
|
|
224
222
|
}
|
|
225
223
|
|
|
226
|
-
function ensureOOMExportStrategies (strategies
|
|
224
|
+
function ensureOOMExportStrategies (strategies) {
|
|
227
225
|
const set = new Set()
|
|
228
226
|
for (const strategy of strategies) {
|
|
229
|
-
set.add(getExportStrategy(strategy
|
|
227
|
+
set.add(getExportStrategy(strategy))
|
|
230
228
|
}
|
|
231
229
|
|
|
232
230
|
return [...set]
|
|
@@ -239,7 +237,7 @@ function getExporter (name, options) {
|
|
|
239
237
|
case 'file':
|
|
240
238
|
return new FileExporter(options)
|
|
241
239
|
default:
|
|
242
|
-
|
|
240
|
+
log.error('Unknown exporter "%s"', name)
|
|
243
241
|
}
|
|
244
242
|
}
|
|
245
243
|
|
|
@@ -255,7 +253,7 @@ function getProfiler (name, options) {
|
|
|
255
253
|
case 'space':
|
|
256
254
|
return new SpaceProfiler(options)
|
|
257
255
|
default:
|
|
258
|
-
|
|
256
|
+
log.error('Unknown profiler "%s"', name)
|
|
259
257
|
}
|
|
260
258
|
}
|
|
261
259
|
|
|
@@ -278,17 +276,6 @@ function ensureProfilers (profilers, options) {
|
|
|
278
276
|
return filteredProfilers
|
|
279
277
|
}
|
|
280
278
|
|
|
281
|
-
function ensureLogger (logger) {
|
|
282
|
-
if (typeof logger?.debug !== 'function' ||
|
|
283
|
-
typeof logger.info !== 'function' ||
|
|
284
|
-
typeof logger.warn !== 'function' ||
|
|
285
|
-
typeof logger.error !== 'function') {
|
|
286
|
-
return new ConsoleLogger()
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
return logger
|
|
290
|
-
}
|
|
291
|
-
|
|
292
279
|
function buildExportCommand (options) {
|
|
293
280
|
const tags = [...Object.entries(options.tags),
|
|
294
281
|
['snapshot', snapshotKinds.ON_OUT_OF_MEMORY]].map(([key, value]) => `${key}:${value}`).join(',')
|
|
@@ -9,6 +9,7 @@ const retry = require('../../../../../vendor/dist/retry')
|
|
|
9
9
|
// TODO: avoid using dd-trace internals. Make this a separate module?
|
|
10
10
|
const docker = require('../../exporters/common/docker')
|
|
11
11
|
const FormData = require('../../exporters/common/form-data')
|
|
12
|
+
const log = require('../../log')
|
|
12
13
|
const { storage } = require('../../../../datadog-core')
|
|
13
14
|
const version = require('../../../../../package.json').version
|
|
14
15
|
const telemetryMetrics = require('../../telemetry/metrics')
|
|
@@ -89,9 +90,8 @@ function computeRetries (uploadTimeout) {
|
|
|
89
90
|
class AgentExporter extends EventSerializer {
|
|
90
91
|
constructor (config = {}) {
|
|
91
92
|
super(config)
|
|
92
|
-
const { url,
|
|
93
|
+
const { url, uploadTimeout } = config
|
|
93
94
|
this._url = url
|
|
94
|
-
this._logger = logger
|
|
95
95
|
|
|
96
96
|
const [backoffTries, backoffTime] = computeRetries(uploadTimeout)
|
|
97
97
|
|
|
@@ -109,12 +109,11 @@ class AgentExporter extends EventSerializer {
|
|
|
109
109
|
contentType: 'application/json',
|
|
110
110
|
}])
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
return `Building agent export report:\n${event}`
|
|
114
|
-
})
|
|
112
|
+
log.debug('Building agent export report:\n%s', event)
|
|
115
113
|
|
|
116
114
|
for (const [type, buffer] of Object.entries(profiles)) {
|
|
117
|
-
|
|
115
|
+
// eslint-disable-next-line eslint-rules/eslint-log-printf-style
|
|
116
|
+
log.debug(() => {
|
|
118
117
|
const bytes = buffer.toString('hex').match(/../g).join(' ')
|
|
119
118
|
return `Adding ${type} profile to agent export: ` + bytes
|
|
120
119
|
})
|
|
@@ -163,7 +162,8 @@ class AgentExporter extends EventSerializer {
|
|
|
163
162
|
options.port = httpOptions.port
|
|
164
163
|
}
|
|
165
164
|
|
|
166
|
-
|
|
165
|
+
// eslint-disable-next-line eslint-rules/eslint-log-printf-style
|
|
166
|
+
log.debug(() => {
|
|
167
167
|
return `Submitting profiler agent report attempt #${attempt} to: ${JSON.stringify(options)}`
|
|
168
168
|
})
|
|
169
169
|
|
|
@@ -171,7 +171,7 @@ class AgentExporter extends EventSerializer {
|
|
|
171
171
|
if (err) {
|
|
172
172
|
const { status } = err
|
|
173
173
|
if ((typeof status !== 'number' || status >= 500 || status === 429) && operation.retry(err)) {
|
|
174
|
-
|
|
174
|
+
log.warn('Error from the agent: %s', err.message)
|
|
175
175
|
} else {
|
|
176
176
|
reject(err)
|
|
177
177
|
}
|
|
@@ -180,9 +180,10 @@ class AgentExporter extends EventSerializer {
|
|
|
180
180
|
|
|
181
181
|
getBody(response, (err, body) => {
|
|
182
182
|
if (err) {
|
|
183
|
-
|
|
183
|
+
log.warn('Error reading agent response: %s', err.message)
|
|
184
184
|
} else {
|
|
185
|
-
|
|
185
|
+
// eslint-disable-next-line eslint-rules/eslint-log-printf-style
|
|
186
|
+
log.debug(() => {
|
|
186
187
|
const bytes = (body.toString('hex').match(/../g) || []).join(' ')
|
|
187
188
|
return `Agent export response: ${bytes}`
|
|
188
189
|
})
|
|
@@ -40,6 +40,16 @@ function processInfo (infos, info, type) {
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
// Route pprof through the central log module so logLevel applies.
|
|
44
|
+
const pprofLogger = {
|
|
45
|
+
trace: (...args) => log.trace(...args),
|
|
46
|
+
debug: (...args) => log.debug(...args),
|
|
47
|
+
info: (...args) => log.info(...args),
|
|
48
|
+
warn: (...args) => log.warn(...args),
|
|
49
|
+
error: (...args) => log.error(...args),
|
|
50
|
+
fatal: (...args) => log.error(...args),
|
|
51
|
+
}
|
|
52
|
+
|
|
43
53
|
class Profiler extends EventEmitter {
|
|
44
54
|
#compressionFn
|
|
45
55
|
#compressionFnInitialized = false
|
|
@@ -49,7 +59,6 @@ class Profiler extends EventEmitter {
|
|
|
49
59
|
#enabled = false
|
|
50
60
|
#endpointCounts = new Map()
|
|
51
61
|
#lastStart
|
|
52
|
-
#logger
|
|
53
62
|
#profileSeq = 0
|
|
54
63
|
#spanFinishListener
|
|
55
64
|
#timer
|
|
@@ -159,14 +168,13 @@ class Profiler extends EventEmitter {
|
|
|
159
168
|
this.#enabled = true
|
|
160
169
|
|
|
161
170
|
const config = this.#config = new Config(options)
|
|
162
|
-
this.#logger = config.logger
|
|
163
171
|
|
|
164
172
|
this._setInterval()
|
|
165
173
|
// Log errors if the source map finder fails, but don't prevent the rest
|
|
166
174
|
// of the profiler from running without source maps.
|
|
167
175
|
let mapper
|
|
168
176
|
const { setLogger, SourceMapper } = require('@datadog/pprof')
|
|
169
|
-
setLogger(
|
|
177
|
+
setLogger(pprofLogger)
|
|
170
178
|
|
|
171
179
|
if (config.sourceMap) {
|
|
172
180
|
mapper = new SourceMapper(config.debugSourceMaps)
|
|
@@ -174,7 +182,8 @@ class Profiler extends EventEmitter {
|
|
|
174
182
|
.then(() => {
|
|
175
183
|
if (config.debugSourceMaps) {
|
|
176
184
|
const count = mapper.infoMap.size
|
|
177
|
-
|
|
185
|
+
// eslint-disable-next-line eslint-rules/eslint-log-printf-style
|
|
186
|
+
log.debug(() => {
|
|
178
187
|
return count === 0
|
|
179
188
|
? 'Found no source maps'
|
|
180
189
|
: `Found source maps for following files: [${[...mapper.infoMap.keys()].join(', ')}]`
|
|
@@ -195,7 +204,7 @@ class Profiler extends EventEmitter {
|
|
|
195
204
|
mapper,
|
|
196
205
|
nearOOMCallback,
|
|
197
206
|
})
|
|
198
|
-
|
|
207
|
+
log.debug('Started %s profiler in %s thread', profiler.type, threadNamePrefix)
|
|
199
208
|
}
|
|
200
209
|
|
|
201
210
|
if (config.endpointCollectionEnabled) {
|
|
@@ -248,7 +257,7 @@ class Profiler extends EventEmitter {
|
|
|
248
257
|
|
|
249
258
|
for (const profiler of this.#config.profilers) {
|
|
250
259
|
profiler.stop()
|
|
251
|
-
|
|
260
|
+
log.debug('Stopped %s profiler in %s thread', profiler.type, threadNamePrefix)
|
|
252
261
|
}
|
|
253
262
|
|
|
254
263
|
clearTimeout(this.#timer)
|
|
@@ -312,7 +321,7 @@ class Profiler extends EventEmitter {
|
|
|
312
321
|
const info = profiler.getInfo()
|
|
313
322
|
const profile = profiler.profile(restart, startDate, endDate)
|
|
314
323
|
if (!restart) {
|
|
315
|
-
|
|
324
|
+
log.debug('Stopped %s profiler in %s thread', profiler.type, threadNamePrefix)
|
|
316
325
|
}
|
|
317
326
|
if (!profile) continue
|
|
318
327
|
profiles.push({ profiler, profile, info })
|
|
@@ -341,7 +350,8 @@ class Profiler extends EventEmitter {
|
|
|
341
350
|
infos.hasMissingSourceMaps = true
|
|
342
351
|
}
|
|
343
352
|
processInfo(infos, info, profiler.type)
|
|
344
|
-
|
|
353
|
+
// eslint-disable-next-line eslint-rules/eslint-log-printf-style
|
|
354
|
+
log.debug(() => {
|
|
345
355
|
const profileJson = JSON.stringify(profile, (_, value) => {
|
|
346
356
|
return typeof value === 'bigint' ? value.toString() : value
|
|
347
357
|
})
|
|
@@ -358,7 +368,7 @@ class Profiler extends EventEmitter {
|
|
|
358
368
|
if (hasEncoded) {
|
|
359
369
|
await this.#submit(encodedProfiles, infos, startDate, endDate, snapshotKind)
|
|
360
370
|
profileSubmittedChannel.publish()
|
|
361
|
-
|
|
371
|
+
log.debug('Submitted profiles')
|
|
362
372
|
}
|
|
363
373
|
} catch (error) {
|
|
364
374
|
log.error(error)
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const dc = require('dc-polyfill')
|
|
4
4
|
|
|
5
5
|
const { storage } = require('../../../../datadog-core')
|
|
6
|
+
const log = require('../../log')
|
|
6
7
|
const runtimeMetrics = require('../../runtime_metrics')
|
|
7
8
|
const telemetryMetrics = require('../../telemetry/metrics')
|
|
8
9
|
const { isWebServerSpan, endpointNameFromTags, getStartedSpans } = require('../webspan-utils')
|
|
@@ -112,7 +113,6 @@ class NativeWallProfiler {
|
|
|
112
113
|
#customLabelKeys
|
|
113
114
|
#endpointCollectionEnabled = false
|
|
114
115
|
#flushIntervalMillis = 0
|
|
115
|
-
#logger
|
|
116
116
|
#mapper
|
|
117
117
|
#pprof
|
|
118
118
|
#samplingIntervalMicros = 0
|
|
@@ -136,7 +136,6 @@ class NativeWallProfiler {
|
|
|
136
136
|
this.#cpuProfilingEnabled = !!options.cpuProfilingEnabled
|
|
137
137
|
this.#endpointCollectionEnabled = !!options.endpointCollectionEnabled
|
|
138
138
|
this.#flushIntervalMillis = options.flushInterval || 60 * 1e3 // 60 seconds
|
|
139
|
-
this.#logger = options.logger
|
|
140
139
|
// TODO: Remove default value. It is only used in testing.
|
|
141
140
|
this.#samplingIntervalMicros = (options.samplingInterval || 1e3 / 99) * 1000
|
|
142
141
|
this.#telemetryHeartbeatIntervalMillis = options.heartbeatInterval || 60 * 1e3 // 60 seconds
|
|
@@ -348,7 +347,7 @@ class NativeWallProfiler {
|
|
|
348
347
|
#reportV8bug (maybeBug) {
|
|
349
348
|
const tag = `v8_profiler_bug_workaround_enabled:${this.#v8ProfilerBugWorkaroundEnabled}`
|
|
350
349
|
const metric = `v8_cpu_profiler${maybeBug ? '_maybe' : ''}_stuck_event_loop`
|
|
351
|
-
|
|
350
|
+
log.warn('Wall profiler: %sv8 profiler stuck event loop detected.', maybeBug ? 'possible ' : '')
|
|
352
351
|
// report as runtime metric (can be removed in the future when telemetry is mature)
|
|
353
352
|
runtimeMetrics.increment(`runtime.node.profiler.${metric}`, tag, true)
|
|
354
353
|
// report as telemetry metric
|