dd-trace 5.31.0 → 5.33.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 +1 -0
- package/README.md +17 -14
- package/index.d.ts +11 -1
- package/package.json +6 -5
- package/packages/datadog-instrumentations/src/aws-sdk.js +4 -1
- package/packages/datadog-instrumentations/src/cucumber.js +31 -14
- package/packages/datadog-instrumentations/src/helpers/hooks.js +3 -0
- package/packages/datadog-instrumentations/src/jest.js +105 -56
- package/packages/datadog-instrumentations/src/mocha/main.js +9 -4
- package/packages/datadog-instrumentations/src/mocha/utils.js +27 -9
- package/packages/datadog-instrumentations/src/mocha/worker.js +4 -2
- package/packages/datadog-instrumentations/src/node-serialize.js +22 -0
- package/packages/datadog-instrumentations/src/openai.js +2 -0
- package/packages/datadog-instrumentations/src/playwright.js +8 -3
- package/packages/datadog-instrumentations/src/vitest.js +134 -62
- package/packages/datadog-instrumentations/src/vm.js +49 -0
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/index.js +16 -0
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +63 -0
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +287 -0
- package/packages/datadog-plugin-aws-sdk/src/services/index.js +1 -0
- package/packages/datadog-plugin-cucumber/src/index.js +31 -31
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +19 -8
- package/packages/datadog-plugin-cypress/src/support.js +6 -2
- package/packages/datadog-plugin-fetch/src/index.js +3 -3
- package/packages/datadog-plugin-http/src/client.js +5 -33
- package/packages/datadog-plugin-jest/src/index.js +37 -37
- package/packages/datadog-plugin-langchain/src/index.js +12 -80
- package/packages/datadog-plugin-langchain/src/tracing.js +89 -0
- package/packages/datadog-plugin-mocha/src/index.js +19 -35
- package/packages/datadog-plugin-playwright/src/index.js +3 -1
- package/packages/datadog-plugin-vitest/src/index.js +33 -35
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/code-injection-analyzer.js +2 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +3 -3
- package/packages/dd-trace/src/appsec/iast/analyzers/untrusted-deserialization-analyzer.js +16 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +41 -24
- package/packages/dd-trace/src/appsec/iast/iast-context.js +12 -0
- package/packages/dd-trace/src/appsec/iast/path-line.js +19 -23
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +9 -8
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +75 -24
- package/packages/dd-trace/src/appsec/rasp/utils.js +10 -5
- package/packages/dd-trace/src/appsec/stack_trace.js +38 -28
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +37 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +65 -28
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +57 -17
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +5 -4
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +18 -3
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +5 -3
- package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +20 -3
- package/packages/dd-trace/src/config.js +43 -3
- package/packages/dd-trace/src/crashtracking/crashtracker.js +9 -0
- package/packages/dd-trace/src/crashtracking/noop.js +3 -0
- package/packages/dd-trace/src/datastreams/fnv.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +2 -2
- package/packages/dd-trace/src/debugger/devtools_client/config.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/defaults.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +30 -13
- package/packages/dd-trace/src/debugger/devtools_client/send.js +4 -8
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +35 -1
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +112 -0
- package/packages/dd-trace/src/debugger/devtools_client/status.js +12 -10
- package/packages/dd-trace/src/debugger/index.js +2 -13
- package/packages/dd-trace/src/llmobs/plugins/base.js +40 -11
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +59 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +24 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +111 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/embedding.js +42 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +102 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/llm.js +32 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +131 -0
- package/packages/dd-trace/src/llmobs/plugins/openai.js +1 -1
- package/packages/dd-trace/src/llmobs/tagger.js +11 -3
- package/packages/dd-trace/src/llmobs/util.js +7 -1
- package/packages/dd-trace/src/llmobs/writers/spans/agentProxy.js +3 -3
- package/packages/dd-trace/src/opentelemetry/context_manager.js +43 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +58 -27
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +0 -2
- package/packages/dd-trace/src/plugins/util/test.js +44 -12
- package/packages/dd-trace/src/priority_sampler.js +4 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +21 -0
- package/packages/dd-trace/src/profiling/profiler.js +11 -8
- package/packages/dd-trace/src/profiling/profilers/events.js +17 -1
- package/packages/dd-trace/src/proxy.js +6 -3
|
@@ -23,7 +23,11 @@ const {
|
|
|
23
23
|
TEST_LEVEL_EVENT_TYPES,
|
|
24
24
|
TEST_SUITE,
|
|
25
25
|
getFileAndLineNumberFromError,
|
|
26
|
-
|
|
26
|
+
DI_ERROR_DEBUG_INFO_CAPTURED,
|
|
27
|
+
DI_DEBUG_ERROR_PREFIX,
|
|
28
|
+
DI_DEBUG_ERROR_SNAPSHOT_ID_SUFFIX,
|
|
29
|
+
DI_DEBUG_ERROR_FILE_SUFFIX,
|
|
30
|
+
DI_DEBUG_ERROR_LINE_SUFFIX
|
|
27
31
|
} = require('./util/test')
|
|
28
32
|
const Plugin = require('./plugin')
|
|
29
33
|
const { COMPONENT } = require('../constants')
|
|
@@ -154,6 +158,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
154
158
|
if (err) {
|
|
155
159
|
log.error('Known tests could not be fetched. %s', err.message)
|
|
156
160
|
this.libraryConfig.isEarlyFlakeDetectionEnabled = false
|
|
161
|
+
this.libraryConfig.isKnownTestsEnabled = false
|
|
157
162
|
}
|
|
158
163
|
onDone({ err, knownTests })
|
|
159
164
|
})
|
|
@@ -180,14 +185,18 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
180
185
|
}
|
|
181
186
|
}
|
|
182
187
|
|
|
183
|
-
configure (config) {
|
|
188
|
+
configure (config, shouldGetEnvironmentData = true) {
|
|
184
189
|
super.configure(config)
|
|
185
190
|
|
|
186
|
-
if (config.isTestDynamicInstrumentationEnabled) {
|
|
191
|
+
if (config.isTestDynamicInstrumentationEnabled && !this.di) {
|
|
187
192
|
const testVisibilityDynamicInstrumentation = require('../ci-visibility/dynamic-instrumentation')
|
|
188
193
|
this.di = testVisibilityDynamicInstrumentation
|
|
189
194
|
}
|
|
190
195
|
|
|
196
|
+
if (!shouldGetEnvironmentData) {
|
|
197
|
+
return
|
|
198
|
+
}
|
|
199
|
+
|
|
191
200
|
this.testEnvironmentMetadata = getTestEnvironmentMetadata(this.constructor.id, this.config)
|
|
192
201
|
|
|
193
202
|
const {
|
|
@@ -292,37 +301,59 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
292
301
|
return testSpan
|
|
293
302
|
}
|
|
294
303
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
304
|
+
onDiBreakpointHit ({ snapshot }) {
|
|
305
|
+
if (!this.activeTestSpan || this.activeTestSpan.context()._isFinished) {
|
|
306
|
+
// This is unexpected and is caused by a race condition.
|
|
307
|
+
log.warn('Breakpoint snapshot could not be attached to the active test span')
|
|
308
|
+
return
|
|
309
|
+
}
|
|
298
310
|
|
|
299
|
-
const
|
|
311
|
+
const stackIndex = this.testErrorStackIndex
|
|
312
|
+
|
|
313
|
+
this.activeTestSpan.setTag(DI_ERROR_DEBUG_INFO_CAPTURED, 'true')
|
|
314
|
+
this.activeTestSpan.setTag(
|
|
315
|
+
`${DI_DEBUG_ERROR_PREFIX}.${stackIndex}.${DI_DEBUG_ERROR_SNAPSHOT_ID_SUFFIX}`,
|
|
316
|
+
snapshot.id
|
|
317
|
+
)
|
|
318
|
+
this.activeTestSpan.setTag(
|
|
319
|
+
`${DI_DEBUG_ERROR_PREFIX}.${stackIndex}.${DI_DEBUG_ERROR_FILE_SUFFIX}`,
|
|
320
|
+
snapshot.probe.location.file
|
|
321
|
+
)
|
|
322
|
+
this.activeTestSpan.setTag(
|
|
323
|
+
`${DI_DEBUG_ERROR_PREFIX}.${stackIndex}.${DI_DEBUG_ERROR_LINE_SUFFIX}`,
|
|
324
|
+
Number(snapshot.probe.location.lines[0])
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
const activeTestSpanContext = this.activeTestSpan.context()
|
|
328
|
+
|
|
329
|
+
this.tracer._exporter.exportDiLogs(this.testEnvironmentMetadata, {
|
|
330
|
+
debugger: { snapshot },
|
|
331
|
+
dd: {
|
|
332
|
+
trace_id: activeTestSpanContext.toTraceId(),
|
|
333
|
+
span_id: activeTestSpanContext.toSpanId()
|
|
334
|
+
}
|
|
335
|
+
})
|
|
336
|
+
}
|
|
300
337
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
338
|
+
removeDiProbe (probeId) {
|
|
339
|
+
return this.di.removeProbe(probeId)
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
addDiProbe (err) {
|
|
343
|
+
const [file, line, stackIndex] = getFileAndLineNumberFromError(err, this.repositoryRoot)
|
|
306
344
|
|
|
307
|
-
if (
|
|
308
|
-
|
|
345
|
+
if (!file || !Number.isInteger(line)) {
|
|
346
|
+
log.warn('Could not add breakpoint for dynamic instrumentation')
|
|
347
|
+
return
|
|
309
348
|
}
|
|
310
349
|
|
|
311
|
-
|
|
312
|
-
// TODO: handle race conditions for this.retriedTestIds
|
|
313
|
-
const { traceId, spanId } = this.retriedTestIds
|
|
314
|
-
this.tracer._exporter.exportDiLogs(this.testEnvironmentMetadata, {
|
|
315
|
-
debugger: { snapshot },
|
|
316
|
-
dd: {
|
|
317
|
-
trace_id: traceId,
|
|
318
|
-
span_id: spanId
|
|
319
|
-
}
|
|
320
|
-
})
|
|
321
|
-
})
|
|
350
|
+
const [probeId, setProbePromise] = this.di.addLineProbe({ file, line }, this.onDiBreakpointHit.bind(this))
|
|
322
351
|
|
|
323
352
|
return {
|
|
324
|
-
|
|
325
|
-
|
|
353
|
+
probeId,
|
|
354
|
+
setProbePromise,
|
|
355
|
+
stackIndex,
|
|
356
|
+
file,
|
|
326
357
|
line
|
|
327
358
|
}
|
|
328
359
|
}
|
|
@@ -2,7 +2,6 @@ const log = require('../../log')
|
|
|
2
2
|
const tags = require('../../../../../ext/tags')
|
|
3
3
|
|
|
4
4
|
const RESOURCE_NAME = tags.RESOURCE_NAME
|
|
5
|
-
const HTTP_ROUTE = tags.HTTP_ROUTE
|
|
6
5
|
const SPAN_KIND = tags.SPAN_KIND
|
|
7
6
|
const SPAN_TYPE = tags.SPAN_TYPE
|
|
8
7
|
const HTTP_URL = tags.HTTP_URL
|
|
@@ -54,7 +53,6 @@ function createInferredProxySpan (headers, childOf, tracer, context) {
|
|
|
54
53
|
[SPAN_TYPE]: 'web',
|
|
55
54
|
[HTTP_METHOD]: proxyContext.method,
|
|
56
55
|
[HTTP_URL]: proxyContext.domainName + proxyContext.path,
|
|
57
|
-
[HTTP_ROUTE]: proxyContext.path,
|
|
58
56
|
stage: proxyContext.stage
|
|
59
57
|
}
|
|
60
58
|
}
|
|
@@ -59,6 +59,7 @@ const TEST_IS_NEW = 'test.is_new'
|
|
|
59
59
|
const TEST_IS_RETRY = 'test.is_retry'
|
|
60
60
|
const TEST_EARLY_FLAKE_ENABLED = 'test.early_flake.enabled'
|
|
61
61
|
const TEST_EARLY_FLAKE_ABORT_REASON = 'test.early_flake.abort_reason'
|
|
62
|
+
const TEST_RETRY_REASON = 'test.retry_reason'
|
|
62
63
|
|
|
63
64
|
const CI_APP_ORIGIN = 'ciapp-test'
|
|
64
65
|
|
|
@@ -88,6 +89,7 @@ const TEST_BROWSER_VERSION = 'test.browser.version'
|
|
|
88
89
|
// jest worker variables
|
|
89
90
|
const JEST_WORKER_TRACE_PAYLOAD_CODE = 60
|
|
90
91
|
const JEST_WORKER_COVERAGE_PAYLOAD_CODE = 61
|
|
92
|
+
const JEST_WORKER_LOGS_PAYLOAD_CODE = 62
|
|
91
93
|
|
|
92
94
|
// cucumber worker variables
|
|
93
95
|
const CUCUMBER_WORKER_TRACE_PAYLOAD_CODE = 70
|
|
@@ -108,10 +110,10 @@ const TEST_LEVEL_EVENT_TYPES = [
|
|
|
108
110
|
|
|
109
111
|
// Dynamic instrumentation - Test optimization integration tags
|
|
110
112
|
const DI_ERROR_DEBUG_INFO_CAPTURED = 'error.debug_info_captured'
|
|
111
|
-
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
const
|
|
113
|
+
const DI_DEBUG_ERROR_PREFIX = '_dd.debug.error'
|
|
114
|
+
const DI_DEBUG_ERROR_SNAPSHOT_ID_SUFFIX = 'snapshot_id'
|
|
115
|
+
const DI_DEBUG_ERROR_FILE_SUFFIX = 'file'
|
|
116
|
+
const DI_DEBUG_ERROR_LINE_SUFFIX = 'line'
|
|
115
117
|
|
|
116
118
|
module.exports = {
|
|
117
119
|
TEST_CODE_OWNERS,
|
|
@@ -134,6 +136,7 @@ module.exports = {
|
|
|
134
136
|
LIBRARY_VERSION,
|
|
135
137
|
JEST_WORKER_TRACE_PAYLOAD_CODE,
|
|
136
138
|
JEST_WORKER_COVERAGE_PAYLOAD_CODE,
|
|
139
|
+
JEST_WORKER_LOGS_PAYLOAD_CODE,
|
|
137
140
|
CUCUMBER_WORKER_TRACE_PAYLOAD_CODE,
|
|
138
141
|
MOCHA_WORKER_TRACE_PAYLOAD_CODE,
|
|
139
142
|
TEST_SOURCE_START,
|
|
@@ -143,6 +146,7 @@ module.exports = {
|
|
|
143
146
|
TEST_IS_RETRY,
|
|
144
147
|
TEST_EARLY_FLAKE_ENABLED,
|
|
145
148
|
TEST_EARLY_FLAKE_ABORT_REASON,
|
|
149
|
+
TEST_RETRY_REASON,
|
|
146
150
|
getTestEnvironmentMetadata,
|
|
147
151
|
getTestParametersString,
|
|
148
152
|
finishAllTraceSpans,
|
|
@@ -191,9 +195,11 @@ module.exports = {
|
|
|
191
195
|
getNumFromKnownTests,
|
|
192
196
|
getFileAndLineNumberFromError,
|
|
193
197
|
DI_ERROR_DEBUG_INFO_CAPTURED,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
198
|
+
DI_DEBUG_ERROR_PREFIX,
|
|
199
|
+
DI_DEBUG_ERROR_SNAPSHOT_ID_SUFFIX,
|
|
200
|
+
DI_DEBUG_ERROR_FILE_SUFFIX,
|
|
201
|
+
DI_DEBUG_ERROR_LINE_SUFFIX,
|
|
202
|
+
getFormattedError
|
|
197
203
|
}
|
|
198
204
|
|
|
199
205
|
// Returns pkg manager and its version, separated by '-', e.g. npm-8.15.0 or yarn-1.22.19
|
|
@@ -650,13 +656,30 @@ function getNumFromKnownTests (knownTests) {
|
|
|
650
656
|
return totalNumTests
|
|
651
657
|
}
|
|
652
658
|
|
|
653
|
-
|
|
659
|
+
const DEPENDENCY_FOLDERS = [
|
|
660
|
+
'node_modules',
|
|
661
|
+
'node:',
|
|
662
|
+
'.pnpm',
|
|
663
|
+
'.yarn',
|
|
664
|
+
'.pnp'
|
|
665
|
+
]
|
|
666
|
+
|
|
667
|
+
function getFileAndLineNumberFromError (error, repositoryRoot) {
|
|
654
668
|
// Split the stack trace into individual lines
|
|
655
669
|
const stackLines = error.stack.split('\n')
|
|
656
670
|
|
|
657
|
-
//
|
|
658
|
-
const
|
|
671
|
+
// Remove potential messages on top of the stack that are not frames
|
|
672
|
+
const frames = stackLines.filter(line => line.includes('at ') && line.includes(repositoryRoot))
|
|
673
|
+
|
|
674
|
+
const topRelevantFrameIndex = frames.findIndex(line =>
|
|
675
|
+
line.includes(repositoryRoot) && !DEPENDENCY_FOLDERS.some(pattern => line.includes(pattern))
|
|
676
|
+
)
|
|
677
|
+
|
|
678
|
+
if (topRelevantFrameIndex === -1) {
|
|
679
|
+
return []
|
|
680
|
+
}
|
|
659
681
|
|
|
682
|
+
const topFrame = frames[topRelevantFrameIndex]
|
|
660
683
|
// Regular expression to match the file path, line number, and column number
|
|
661
684
|
const regex = /\s*at\s+(?:.*\()?(.+):(\d+):(\d+)\)?/
|
|
662
685
|
const match = topFrame.match(regex)
|
|
@@ -664,9 +687,18 @@ function getFileAndLineNumberFromError (error) {
|
|
|
664
687
|
if (match) {
|
|
665
688
|
const filePath = match[1]
|
|
666
689
|
const lineNumber = Number(match[2])
|
|
667
|
-
const columnNumber = Number(match[3])
|
|
668
690
|
|
|
669
|
-
return [filePath, lineNumber,
|
|
691
|
+
return [filePath, lineNumber, topRelevantFrameIndex]
|
|
670
692
|
}
|
|
671
693
|
return []
|
|
672
694
|
}
|
|
695
|
+
|
|
696
|
+
function getFormattedError (error, repositoryRoot) {
|
|
697
|
+
const newError = new Error(error.message)
|
|
698
|
+
if (error.stack) {
|
|
699
|
+
newError.stack = error.stack.split('\n').filter(line => line.includes(repositoryRoot)).join('\n')
|
|
700
|
+
}
|
|
701
|
+
newError.name = error.name
|
|
702
|
+
|
|
703
|
+
return newError
|
|
704
|
+
}
|
|
@@ -122,7 +122,10 @@ class PrioritySampler {
|
|
|
122
122
|
const context = this._getContext(span)
|
|
123
123
|
const root = context._trace.started[0]
|
|
124
124
|
|
|
125
|
-
if (!root)
|
|
125
|
+
if (!root) {
|
|
126
|
+
log.error('Skipping the setPriority on noop span')
|
|
127
|
+
return // noop span
|
|
128
|
+
}
|
|
126
129
|
|
|
127
130
|
context._sampling.priority = samplingPriority
|
|
128
131
|
context._sampling.mechanism = mechanism
|
|
@@ -2,6 +2,22 @@ const os = require('os')
|
|
|
2
2
|
const perf = require('perf_hooks').performance
|
|
3
3
|
const version = require('../../../../../package.json').version
|
|
4
4
|
|
|
5
|
+
const libuvThreadPoolSize = (() => {
|
|
6
|
+
const ss = process.env.UV_THREADPOOL_SIZE
|
|
7
|
+
if (ss === undefined) {
|
|
8
|
+
// Backend will apply the default size based on Node version.
|
|
9
|
+
return undefined
|
|
10
|
+
}
|
|
11
|
+
// libuv uses atoi to parse the value, which is almost the same as parseInt, except that parseInt
|
|
12
|
+
// will return NaN on invalid input, while atoi will return 0. This is handled at return.
|
|
13
|
+
const s = parseInt(ss)
|
|
14
|
+
// We dont' interpret the value further here in the library. Backend will interpret the number
|
|
15
|
+
// based on Node version. In all currently known Node versions, 0 results in 1 worker thread,
|
|
16
|
+
// negative values (because they're assigned to an unsigned int) become very high positive values,
|
|
17
|
+
// and the value is finally capped at 1024.
|
|
18
|
+
return isNaN(s) ? 0 : s
|
|
19
|
+
})()
|
|
20
|
+
|
|
5
21
|
class EventSerializer {
|
|
6
22
|
constructor ({ env, host, service, version, libraryInjected, activation } = {}) {
|
|
7
23
|
this._env = env
|
|
@@ -56,11 +72,16 @@ class EventSerializer {
|
|
|
56
72
|
version
|
|
57
73
|
},
|
|
58
74
|
runtime: {
|
|
75
|
+
// os.availableParallelism only available in node 18.14.0/19.4.0 and above
|
|
76
|
+
available_processors: typeof os.availableParallelism === 'function'
|
|
77
|
+
? os.availableParallelism()
|
|
78
|
+
: os.cpus().length,
|
|
59
79
|
// Using `nodejs` for consistency with the existing `runtime` tag.
|
|
60
80
|
// Note that the event `family` property uses `node`, as that's what's
|
|
61
81
|
// proscribed by the Intake API, but that's an internal enum and is
|
|
62
82
|
// not customer visible.
|
|
63
83
|
engine: 'nodejs',
|
|
84
|
+
libuv_threadpool_size: libuvThreadPoolSize,
|
|
64
85
|
// strip off leading 'v'. This makes the format consistent with other
|
|
65
86
|
// runtimes (e.g. Ruby) but not with the existing `runtime_version` tag.
|
|
66
87
|
// We'll keep it like this as we want cross-engine consistency. We
|
|
@@ -6,6 +6,7 @@ const { snapshotKinds } = require('./constants')
|
|
|
6
6
|
const { threadNamePrefix } = require('./profilers/shared')
|
|
7
7
|
const { isWebServerSpan, endpointNameFromTags, getStartedSpans } = require('./webspan-utils')
|
|
8
8
|
const dc = require('dc-polyfill')
|
|
9
|
+
const crashtracker = require('../crashtracking')
|
|
9
10
|
|
|
10
11
|
const profileSubmittedChannel = dc.channel('datadog:profiling:profile-submitted')
|
|
11
12
|
const spanFinishedChannel = dc.channel('dd-trace:span:finish')
|
|
@@ -197,15 +198,17 @@ class Profiler extends EventEmitter {
|
|
|
197
198
|
throw new Error('No profile types configured.')
|
|
198
199
|
}
|
|
199
200
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
201
|
+
crashtracker.withProfilerSerializing(() => {
|
|
202
|
+
// collect profiles synchronously so that profilers can be safely stopped asynchronously
|
|
203
|
+
for (const profiler of this._config.profilers) {
|
|
204
|
+
const profile = profiler.profile(restart, startDate, endDate)
|
|
205
|
+
if (!restart) {
|
|
206
|
+
this._logger.debug(`Stopped ${profiler.type} profiler in ${threadNamePrefix} thread`)
|
|
207
|
+
}
|
|
208
|
+
if (!profile) continue
|
|
209
|
+
profiles.push({ profiler, profile })
|
|
205
210
|
}
|
|
206
|
-
|
|
207
|
-
profiles.push({ profiler, profile })
|
|
208
|
-
}
|
|
211
|
+
})
|
|
209
212
|
|
|
210
213
|
if (restart) {
|
|
211
214
|
this._capture(this._timeoutInterval, endDate)
|
|
@@ -14,7 +14,23 @@ const pprofValueUnit = 'nanoseconds'
|
|
|
14
14
|
const dateOffset = BigInt(Math.round(performance.timeOrigin * MS_TO_NS))
|
|
15
15
|
|
|
16
16
|
function labelFromStr (stringTable, key, valStr) {
|
|
17
|
-
return new Label({ key, str: stringTable.dedup(valStr) })
|
|
17
|
+
return new Label({ key, str: stringTable.dedup(safeToString(valStr)) })
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// We don't want to invoke toString for objects and functions, rather we'll
|
|
21
|
+
// provide dummy values. These values are not meant to emulate built-in toString
|
|
22
|
+
// behavior.
|
|
23
|
+
function safeToString (val) {
|
|
24
|
+
switch (typeof val) {
|
|
25
|
+
case 'string':
|
|
26
|
+
return val
|
|
27
|
+
case 'object':
|
|
28
|
+
return '[object]'
|
|
29
|
+
case 'function':
|
|
30
|
+
return '[function]'
|
|
31
|
+
default:
|
|
32
|
+
return String(val)
|
|
33
|
+
}
|
|
18
34
|
}
|
|
19
35
|
|
|
20
36
|
function labelFromStrStr (stringTable, keyStr, valStr) {
|
|
@@ -119,7 +119,7 @@ class Tracer extends NoopProxy {
|
|
|
119
119
|
this._flare.module.send(conf.args)
|
|
120
120
|
})
|
|
121
121
|
|
|
122
|
-
if (config.
|
|
122
|
+
if (config.dynamicInstrumentation.enabled) {
|
|
123
123
|
DynamicInstrumentation.start(config, rc)
|
|
124
124
|
}
|
|
125
125
|
}
|
|
@@ -166,7 +166,10 @@ class Tracer extends NoopProxy {
|
|
|
166
166
|
if (config.isManualApiEnabled) {
|
|
167
167
|
const TestApiManualPlugin = require('./ci-visibility/test-api-manual/test-api-manual-plugin')
|
|
168
168
|
this._testApiManualPlugin = new TestApiManualPlugin(this)
|
|
169
|
-
|
|
169
|
+
// `shouldGetEnvironmentData` is passed as false so that we only lazily calculate it
|
|
170
|
+
// This is the only place where we need to do this because the rest of the plugins
|
|
171
|
+
// are lazily configured when the library is imported.
|
|
172
|
+
this._testApiManualPlugin.configure({ ...config, enabled: true }, false)
|
|
170
173
|
}
|
|
171
174
|
}
|
|
172
175
|
if (config.ciVisAgentlessLogSubmissionEnabled) {
|
|
@@ -184,7 +187,7 @@ class Tracer extends NoopProxy {
|
|
|
184
187
|
|
|
185
188
|
if (config.isTestDynamicInstrumentationEnabled) {
|
|
186
189
|
const testVisibilityDynamicInstrumentation = require('./ci-visibility/dynamic-instrumentation')
|
|
187
|
-
testVisibilityDynamicInstrumentation.start()
|
|
190
|
+
testVisibilityDynamicInstrumentation.start(config)
|
|
188
191
|
}
|
|
189
192
|
} catch (e) {
|
|
190
193
|
log.error('Error initialising tracer', e)
|