dd-trace 3.37.0 → 3.38.1
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/package.json +4 -3
- package/packages/datadog-instrumentations/src/body-parser.js +2 -1
- package/packages/datadog-instrumentations/src/cucumber.js +24 -4
- package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +45 -0
- package/packages/datadog-instrumentations/src/express.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -1
- package/packages/datadog-instrumentations/src/jest.js +20 -11
- package/packages/datadog-instrumentations/src/knex.js +62 -1
- package/packages/datadog-instrumentations/src/mocha.js +19 -4
- package/packages/datadog-instrumentations/src/mongodb.js +63 -0
- package/packages/datadog-instrumentations/src/mongoose.js +140 -1
- package/packages/datadog-instrumentations/src/next.js +40 -0
- package/packages/datadog-instrumentations/src/playwright.js +11 -2
- package/packages/datadog-plugin-cucumber/src/index.js +17 -5
- package/packages/datadog-plugin-cypress/src/plugin.js +38 -8
- package/packages/datadog-plugin-jest/src/index.js +19 -4
- package/packages/datadog-plugin-jest/src/util.js +45 -2
- package/packages/datadog-plugin-memcached/src/index.js +10 -5
- package/packages/datadog-plugin-mocha/src/index.js +19 -6
- package/packages/dd-trace/src/appsec/channels.js +3 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +166 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +21 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/unvalidated-redirect-analyzer.js +3 -3
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +1 -2
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +4 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +25 -12
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +4 -4
- package/packages/dd-trace/src/appsec/iast/taint-tracking/secure-marks-generator.js +13 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/source-types.js +2 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/json-sensitive-analyzer.js +16 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +3 -4
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +9 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +13 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +169 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
- package/packages/dd-trace/src/appsec/index.js +31 -13
- package/packages/dd-trace/src/appsec/remote_config/manager.js +11 -3
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +14 -1
- package/packages/dd-trace/src/config.js +8 -0
- package/packages/dd-trace/src/format.js +3 -0
- package/packages/dd-trace/src/plugin_manager.js +3 -1
- package/packages/dd-trace/src/plugins/util/ci.js +17 -0
- package/packages/dd-trace/src/plugins/util/git.js +26 -4
- package/packages/dd-trace/src/plugins/util/test.js +16 -1
- package/packages/dd-trace/src/profiling/config.js +36 -5
- package/packages/dd-trace/src/profiling/profilers/wall.js +7 -1
- package/packages/dd-trace/src/service-naming/extra-services.js +24 -0
- package/packages/dd-trace/src/telemetry/metrics.js +0 -5
|
@@ -602,6 +602,23 @@ module.exports = {
|
|
|
602
602
|
tags[refKey] = ref
|
|
603
603
|
}
|
|
604
604
|
|
|
605
|
+
if (env.CODEBUILD_INITIATOR?.startsWith('codepipeline/')) {
|
|
606
|
+
const {
|
|
607
|
+
CODEBUILD_BUILD_ARN,
|
|
608
|
+
DD_ACTION_EXECUTION_ID,
|
|
609
|
+
DD_PIPELINE_EXECUTION_ID
|
|
610
|
+
} = env
|
|
611
|
+
tags = {
|
|
612
|
+
[CI_PROVIDER_NAME]: 'awscodepipeline',
|
|
613
|
+
[CI_PIPELINE_ID]: DD_PIPELINE_EXECUTION_ID,
|
|
614
|
+
[CI_ENV_VARS]: JSON.stringify({
|
|
615
|
+
CODEBUILD_BUILD_ARN,
|
|
616
|
+
DD_PIPELINE_EXECUTION_ID,
|
|
617
|
+
DD_ACTION_EXECUTION_ID
|
|
618
|
+
})
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
605
622
|
normalizeTag(tags, CI_WORKSPACE_PATH, resolveTilde)
|
|
606
623
|
normalizeTag(tags, GIT_REPOSITORY_URL, filterSensitiveInfoFromRepository)
|
|
607
624
|
normalizeTag(tags, GIT_BRANCH, normalizeRef)
|
|
@@ -61,15 +61,37 @@ function unshallowRepository () {
|
|
|
61
61
|
}
|
|
62
62
|
const defaultRemoteName = sanitizedExec('git', ['config', '--default', 'origin', '--get', 'clone.defaultRemoteName'])
|
|
63
63
|
const revParseHead = sanitizedExec('git', ['rev-parse', 'HEAD'])
|
|
64
|
-
|
|
64
|
+
|
|
65
|
+
const baseGitOptions = [
|
|
65
66
|
'fetch',
|
|
66
67
|
'--shallow-since="1 month ago"',
|
|
67
68
|
'--update-shallow',
|
|
68
69
|
'--filter=blob:none',
|
|
69
70
|
'--recurse-submodules=no',
|
|
70
|
-
defaultRemoteName
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
defaultRemoteName
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
execFileSync('git', [
|
|
76
|
+
...baseGitOptions,
|
|
77
|
+
revParseHead
|
|
78
|
+
], { stdio: 'pipe' })
|
|
79
|
+
} catch (e) {
|
|
80
|
+
// If the local HEAD is a commit that has not been pushed to the remote, the above command will fail.
|
|
81
|
+
log.error(e)
|
|
82
|
+
const upstreamRemote = sanitizedExec('git', ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{upstream}'])
|
|
83
|
+
try {
|
|
84
|
+
execFileSync('git', [
|
|
85
|
+
...baseGitOptions,
|
|
86
|
+
upstreamRemote
|
|
87
|
+
], { stdio: 'pipe' })
|
|
88
|
+
} catch (e) {
|
|
89
|
+
// If the CI is working on a detached HEAD or branch tracking hasn’t been set up, the above command will fail.
|
|
90
|
+
log.error(e)
|
|
91
|
+
// We use sanitizedExec here because if this last option fails, we'll give up.
|
|
92
|
+
sanitizedExec('git', baseGitOptions)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
73
95
|
}
|
|
74
96
|
|
|
75
97
|
function getRepositoryUrl () {
|
|
@@ -58,6 +58,8 @@ const TEST_ITR_SKIPPING_ENABLED = 'test.itr.tests_skipping.enabled'
|
|
|
58
58
|
const TEST_ITR_SKIPPING_TYPE = 'test.itr.tests_skipping.type'
|
|
59
59
|
const TEST_ITR_SKIPPING_COUNT = 'test.itr.tests_skipping.count'
|
|
60
60
|
const TEST_CODE_COVERAGE_ENABLED = 'test.code_coverage.enabled'
|
|
61
|
+
const TEST_ITR_UNSKIPPABLE = 'test.itr.unskippable'
|
|
62
|
+
const TEST_ITR_FORCED_RUN = 'test.itr.forced_run'
|
|
61
63
|
|
|
62
64
|
const TEST_CODE_COVERAGE_LINES_PCT = 'test.code_coverage.lines_pct'
|
|
63
65
|
|
|
@@ -107,6 +109,8 @@ module.exports = {
|
|
|
107
109
|
TEST_ITR_SKIPPING_COUNT,
|
|
108
110
|
TEST_CODE_COVERAGE_ENABLED,
|
|
109
111
|
TEST_CODE_COVERAGE_LINES_PCT,
|
|
112
|
+
TEST_ITR_UNSKIPPABLE,
|
|
113
|
+
TEST_ITR_FORCED_RUN,
|
|
110
114
|
addIntelligentTestRunnerSpanTags,
|
|
111
115
|
getCoveredFilenamesFromCoverage,
|
|
112
116
|
resetCoverage,
|
|
@@ -366,7 +370,9 @@ function addIntelligentTestRunnerSpanTags (
|
|
|
366
370
|
isCodeCoverageEnabled,
|
|
367
371
|
testCodeCoverageLinesTotal,
|
|
368
372
|
skippingCount,
|
|
369
|
-
skippingType = 'suite'
|
|
373
|
+
skippingType = 'suite',
|
|
374
|
+
hasUnskippableSuites,
|
|
375
|
+
hasForcedToRunSuites
|
|
370
376
|
}
|
|
371
377
|
) {
|
|
372
378
|
testSessionSpan.setTag(TEST_ITR_TESTS_SKIPPED, isSuitesSkipped ? 'true' : 'false')
|
|
@@ -381,6 +387,15 @@ function addIntelligentTestRunnerSpanTags (
|
|
|
381
387
|
testModuleSpan.setTag(TEST_ITR_SKIPPING_COUNT, skippingCount)
|
|
382
388
|
testModuleSpan.setTag(TEST_CODE_COVERAGE_ENABLED, isCodeCoverageEnabled ? 'true' : 'false')
|
|
383
389
|
|
|
390
|
+
if (hasUnskippableSuites) {
|
|
391
|
+
testSessionSpan.setTag(TEST_ITR_UNSKIPPABLE, 'true')
|
|
392
|
+
testModuleSpan.setTag(TEST_ITR_UNSKIPPABLE, 'true')
|
|
393
|
+
}
|
|
394
|
+
if (hasForcedToRunSuites) {
|
|
395
|
+
testSessionSpan.setTag(TEST_ITR_FORCED_RUN, 'true')
|
|
396
|
+
testModuleSpan.setTag(TEST_ITR_FORCED_RUN, 'true')
|
|
397
|
+
}
|
|
398
|
+
|
|
384
399
|
// If suites have been skipped we don't want to report the total coverage, as it will be wrong
|
|
385
400
|
if (testCodeCoverageLinesTotal !== undefined && !isSuitesSkipped) {
|
|
386
401
|
testSessionSpan.setTag(TEST_CODE_COVERAGE_LINES_PCT, testCodeCoverageLinesTotal)
|
|
@@ -37,6 +37,8 @@ class Config {
|
|
|
37
37
|
DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE,
|
|
38
38
|
DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT,
|
|
39
39
|
DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES,
|
|
40
|
+
DD_PROFILING_CODEHOTSPOTS_ENABLED,
|
|
41
|
+
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,
|
|
40
42
|
DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED,
|
|
41
43
|
DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED
|
|
42
44
|
} = process.env
|
|
@@ -53,8 +55,6 @@ class Config {
|
|
|
53
55
|
Number(DD_PROFILING_UPLOAD_TIMEOUT), 60 * 1000)
|
|
54
56
|
const sourceMap = coalesce(options.sourceMap,
|
|
55
57
|
DD_PROFILING_SOURCE_MAP, true)
|
|
56
|
-
const endpointCollectionEnabled = coalesce(options.endpointCollection,
|
|
57
|
-
DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED, false)
|
|
58
58
|
const pprofPrefix = coalesce(options.pprofPrefix,
|
|
59
59
|
DD_PROFILING_PPROF_PREFIX, '')
|
|
60
60
|
|
|
@@ -71,11 +71,25 @@ class Config {
|
|
|
71
71
|
tagger.parse({ env, host, service, version, functionname })
|
|
72
72
|
)
|
|
73
73
|
this.logger = ensureLogger(options.logger)
|
|
74
|
+
const logger = this.logger
|
|
75
|
+
function logExperimentalVarDeprecation (shortVarName) {
|
|
76
|
+
const deprecatedEnvVarName = `DD_PROFILING_EXPERIMENTAL_${shortVarName}`
|
|
77
|
+
const v = process.env[deprecatedEnvVarName]
|
|
78
|
+
// not null, undefined, or NaN -- same logic as koalas.hasValue
|
|
79
|
+
// eslint-disable-next-line no-self-compare
|
|
80
|
+
if (v != null && v === v) {
|
|
81
|
+
logger.warn(`${deprecatedEnvVarName} is deprecated. Use DD_PROFILING_${shortVarName} instead.`)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
74
84
|
this.flushInterval = flushInterval
|
|
75
85
|
this.uploadTimeout = uploadTimeout
|
|
76
86
|
this.sourceMap = sourceMap
|
|
77
87
|
this.debugSourceMaps = isTrue(coalesce(options.debugSourceMaps, DD_PROFILING_DEBUG_SOURCE_MAPS, false))
|
|
78
|
-
this.endpointCollectionEnabled =
|
|
88
|
+
this.endpointCollectionEnabled = isTrue(coalesce(options.endpointCollection,
|
|
89
|
+
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,
|
|
90
|
+
DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED, false))
|
|
91
|
+
logExperimentalVarDeprecation('ENDPOINT_COLLECTION_ENABLED')
|
|
92
|
+
|
|
79
93
|
this.pprofPrefix = pprofPrefix
|
|
80
94
|
this.v8ProfilerBugWorkaroundEnabled = isTrue(coalesce(options.v8ProfilerBugWorkaround,
|
|
81
95
|
DD_PROFILING_V8_PROFILER_BUG_WORKAROUND, true))
|
|
@@ -113,8 +127,25 @@ class Config {
|
|
|
113
127
|
const profilers = options.profilers
|
|
114
128
|
? options.profilers
|
|
115
129
|
: getProfilers({ DD_PROFILING_HEAP_ENABLED, DD_PROFILING_WALLTIME_ENABLED, DD_PROFILING_PROFILERS })
|
|
116
|
-
|
|
117
|
-
|
|
130
|
+
|
|
131
|
+
function getCodeHotspotsOptionsOr (defvalue) {
|
|
132
|
+
return coalesce(options.codeHotspotsEnabled,
|
|
133
|
+
DD_PROFILING_CODEHOTSPOTS_ENABLED,
|
|
134
|
+
DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED, defvalue)
|
|
135
|
+
}
|
|
136
|
+
this.codeHotspotsEnabled = isTrue(getCodeHotspotsOptionsOr(false))
|
|
137
|
+
logExperimentalVarDeprecation('CODEHOTSPOTS_ENABLED')
|
|
138
|
+
if (this.endpointCollectionEnabled && !this.codeHotspotsEnabled) {
|
|
139
|
+
if (getCodeHotspotsOptionsOr(undefined) !== undefined) {
|
|
140
|
+
this.logger.warn(
|
|
141
|
+
'Endpoint collection is enabled, but Code Hotspots are disabled. ' +
|
|
142
|
+
'Enable Code Hotspots too for endpoint collection to work.')
|
|
143
|
+
this.endpointCollectionEnabled = false
|
|
144
|
+
} else {
|
|
145
|
+
this.logger.info('Code Hotspots are implicitly enabled by endpoint collection.')
|
|
146
|
+
this.codeHotspotsEnabled = true
|
|
147
|
+
}
|
|
148
|
+
}
|
|
118
149
|
|
|
119
150
|
this.profilers = ensureProfilers(profilers, this)
|
|
120
151
|
}
|
|
@@ -23,7 +23,7 @@ function getStartedSpans (context) {
|
|
|
23
23
|
return context._trace.started
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
function generateLabels ({ spanId, rootSpanId, webTags, endpoint }) {
|
|
26
|
+
function generateLabels ({ context: { spanId, rootSpanId, webTags, endpoint }, timestamp }) {
|
|
27
27
|
const labels = {}
|
|
28
28
|
if (spanId) {
|
|
29
29
|
labels['span id'] = spanId
|
|
@@ -37,6 +37,8 @@ function generateLabels ({ spanId, rootSpanId, webTags, endpoint }) {
|
|
|
37
37
|
// fallback to endpoint computed when sample was taken
|
|
38
38
|
labels['trace endpoint'] = endpoint
|
|
39
39
|
}
|
|
40
|
+
// Incoming timestamps are in microseconds, we emit nanos.
|
|
41
|
+
labels['end_timestamp_ns'] = timestamp * 1000n
|
|
40
42
|
|
|
41
43
|
return labels
|
|
42
44
|
}
|
|
@@ -100,6 +102,10 @@ class NativeWallProfiler {
|
|
|
100
102
|
return this._codeHotspotsEnabled
|
|
101
103
|
}
|
|
102
104
|
|
|
105
|
+
endpointCollectionEnabled () {
|
|
106
|
+
return this._endpointCollectionEnabled
|
|
107
|
+
}
|
|
108
|
+
|
|
103
109
|
start ({ mapper } = {}) {
|
|
104
110
|
if (this._started) return
|
|
105
111
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const maxExtraServices = 64
|
|
4
|
+
const extraServices = new Set()
|
|
5
|
+
|
|
6
|
+
function getExtraServices () {
|
|
7
|
+
return [...extraServices]
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function registerExtraService (serviceName) {
|
|
11
|
+
if (serviceName && extraServices.size < maxExtraServices) {
|
|
12
|
+
extraServices.add(serviceName)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function clear () {
|
|
17
|
+
extraServices.clear()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = {
|
|
21
|
+
registerExtraService,
|
|
22
|
+
getExtraServices,
|
|
23
|
+
clear
|
|
24
|
+
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { version } = require('../../../../package.json')
|
|
4
|
-
|
|
5
3
|
const { sendData } = require('./send-data')
|
|
6
4
|
|
|
7
5
|
function getId (type, namespace, name, tags) {
|
|
@@ -35,10 +33,7 @@ class Metric {
|
|
|
35
33
|
this.metric = common ? metric : `nodejs.${metric}`
|
|
36
34
|
this.tags = tagArray(tags)
|
|
37
35
|
if (common) {
|
|
38
|
-
this.tags.push('lib_language:nodejs')
|
|
39
36
|
this.tags.push(`version:${process.version}`)
|
|
40
|
-
} else {
|
|
41
|
-
this.tags.push(`lib_version:${version}`)
|
|
42
37
|
}
|
|
43
38
|
this.common = common
|
|
44
39
|
|