dd-trace 3.12.1 → 3.15.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 +5 -5
- package/ci/init.js +3 -1
- package/index.d.ts +100 -1
- package/package.json +5 -4
- package/packages/datadog-instrumentations/src/aws-sdk.js +86 -0
- package/packages/datadog-instrumentations/src/cucumber.js +74 -15
- package/packages/datadog-instrumentations/src/cypress.js +1 -1
- package/packages/datadog-instrumentations/src/fs.js +358 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +24 -23
- package/packages/datadog-instrumentations/src/ldapjs.js +12 -2
- package/packages/datadog-instrumentations/src/mocha.js +10 -7
- package/packages/datadog-instrumentations/src/mongoose.js +1 -1
- package/packages/datadog-instrumentations/src/mysql.js +7 -1
- package/packages/datadog-instrumentations/src/mysql2.js +7 -1
- package/packages/datadog-instrumentations/src/next.js +2 -1
- package/packages/datadog-instrumentations/src/playwright.js +263 -0
- package/packages/datadog-plugin-aws-sdk/src/base.js +12 -5
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +29 -24
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +31 -16
- package/packages/datadog-plugin-cucumber/src/index.js +42 -11
- package/packages/datadog-plugin-cypress/src/plugin.js +129 -4
- package/packages/datadog-plugin-cypress/src/support.js +5 -0
- package/packages/datadog-plugin-fs/src/index.js +45 -0
- package/packages/datadog-plugin-hapi/src/index.js +5 -1
- package/packages/datadog-plugin-http/src/server.js +1 -1
- package/packages/datadog-plugin-http2/src/server.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +40 -70
- package/packages/datadog-plugin-mocha/src/index.js +44 -64
- package/packages/datadog-plugin-mysql/src/index.js +8 -7
- package/packages/datadog-plugin-playwright/src/index.js +112 -0
- package/packages/datadog-shimmer/src/shimmer.js +28 -11
- package/packages/dd-trace/src/appsec/addresses.js +3 -1
- package/packages/dd-trace/src/appsec/blocking.js +35 -9
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +60 -0
- package/packages/dd-trace/src/appsec/iast/iast-context.js +6 -2
- package/packages/dd-trace/src/appsec/iast/index.js +3 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +5 -2
- package/packages/dd-trace/src/appsec/index.js +5 -5
- package/packages/dd-trace/src/appsec/recommended.json +320 -184
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +3 -0
- package/packages/dd-trace/src/appsec/reporter.js +14 -14
- package/packages/dd-trace/src/appsec/sdk/index.js +41 -0
- package/packages/dd-trace/src/appsec/sdk/noop.js +17 -0
- package/packages/dd-trace/src/appsec/sdk/set_user.js +30 -0
- package/packages/dd-trace/src/appsec/sdk/track_event.js +74 -0
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +73 -0
- package/packages/dd-trace/src/appsec/sdk/utils.js +10 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +1 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +1 -5
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +48 -11
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +7 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +4 -2
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +5 -3
- package/packages/dd-trace/src/config.js +63 -7
- package/packages/dd-trace/src/encode/0.4.js +1 -1
- package/packages/dd-trace/src/encode/0.5.js +1 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +44 -4
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +52 -37
- package/packages/dd-trace/src/encode/tags-processors.js +3 -2
- package/packages/dd-trace/src/exporters/common/request.js +10 -3
- package/packages/dd-trace/src/lambda/handler.js +5 -6
- package/packages/dd-trace/src/log/channels.js +47 -0
- package/packages/dd-trace/src/log/index.js +79 -0
- package/packages/dd-trace/src/log/writer.js +124 -0
- package/packages/dd-trace/src/metrics.js +18 -0
- package/packages/dd-trace/src/noop/proxy.js +5 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +188 -36
- package/packages/dd-trace/src/opentracing/propagation/tracestate.js +99 -0
- package/packages/dd-trace/src/opentracing/span.js +2 -1
- package/packages/dd-trace/src/opentracing/span_context.js +6 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +72 -12
- package/packages/dd-trace/src/plugins/index.js +2 -0
- package/packages/dd-trace/src/plugins/util/ci.js +13 -21
- package/packages/dd-trace/src/plugins/util/exec.js +2 -2
- package/packages/dd-trace/src/plugins/util/git.js +16 -1
- package/packages/dd-trace/src/{appsec → plugins/util}/ip_extractor.js +1 -1
- package/packages/dd-trace/src/plugins/util/test.js +53 -10
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +2 -7
- package/packages/dd-trace/src/plugins/util/web.js +11 -0
- package/packages/dd-trace/src/profiler.js +3 -0
- package/packages/dd-trace/src/profiling/config.js +8 -3
- package/packages/dd-trace/src/profiling/exporters/file.js +13 -2
- package/packages/dd-trace/src/profiling/profiler.js +23 -6
- package/packages/dd-trace/src/profiling/profilers/wall.js +1 -0
- package/packages/dd-trace/src/proxy.js +2 -0
- package/packages/dd-trace/src/span_processor.js +1 -1
- package/packages/dd-trace/src/span_sampler.js +68 -52
- package/packages/dd-trace/src/startup-log.js +3 -6
- package/packages/dd-trace/src/telemetry/index.js +23 -2
- package/packages/dd-trace/src/telemetry/send-data.js +4 -1
- package/packages/dd-trace/src/tracer.js +0 -16
- package/scripts/check-proposal-labels.js +71 -0
- package/packages/dd-trace/src/log.js +0 -143
- /package/packages/dd-trace/src/{appsec → plugins/util}/ip_blocklist.js +0 -0
|
@@ -122,7 +122,7 @@ module.exports = {
|
|
|
122
122
|
[CI_ENV_VARS]: JSON.stringify({ DD_CUSTOM_TRACE_ID })
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
const isTag = JENKINS_GIT_BRANCH && JENKINS_GIT_BRANCH.includes('tags')
|
|
125
|
+
const isTag = JENKINS_GIT_BRANCH && JENKINS_GIT_BRANCH.includes('tags/')
|
|
126
126
|
const refKey = isTag ? GIT_TAG : GIT_BRANCH
|
|
127
127
|
const ref = normalizeRef(JENKINS_GIT_BRANCH)
|
|
128
128
|
|
|
@@ -216,7 +216,8 @@ module.exports = {
|
|
|
216
216
|
[GIT_REPOSITORY_URL]: CIRCLE_REPOSITORY_URL,
|
|
217
217
|
[CI_JOB_URL]: CIRCLE_BUILD_URL,
|
|
218
218
|
[CI_WORKSPACE_PATH]: CIRCLE_WORKING_DIRECTORY,
|
|
219
|
-
[
|
|
219
|
+
[GIT_TAG]: CIRCLE_TAG,
|
|
220
|
+
[GIT_BRANCH]: CIRCLE_BRANCH,
|
|
220
221
|
[CI_ENV_VARS]: JSON.stringify({
|
|
221
222
|
CIRCLE_WORKFLOW_ID,
|
|
222
223
|
CIRCLE_BUILD_NUM
|
|
@@ -249,7 +250,7 @@ module.exports = {
|
|
|
249
250
|
const jobUrl = `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/commit/${GITHUB_SHA}/checks`
|
|
250
251
|
|
|
251
252
|
const ref = GITHUB_HEAD_REF || GITHUB_REF || ''
|
|
252
|
-
const refKey = ref.includes('tags') ? GIT_TAG : GIT_BRANCH
|
|
253
|
+
const refKey = ref.includes('tags/') ? GIT_TAG : GIT_BRANCH
|
|
253
254
|
|
|
254
255
|
tags = {
|
|
255
256
|
[CI_PIPELINE_ID]: GITHUB_RUN_ID,
|
|
@@ -305,13 +306,12 @@ module.exports = {
|
|
|
305
306
|
}
|
|
306
307
|
|
|
307
308
|
if (APPVEYOR_REPO_PROVIDER === 'github') {
|
|
308
|
-
const refKey = APPVEYOR_REPO_TAG_NAME ? GIT_TAG : GIT_BRANCH
|
|
309
|
-
const ref = APPVEYOR_REPO_TAG_NAME || APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH || APPVEYOR_REPO_BRANCH
|
|
310
309
|
tags = {
|
|
311
310
|
...tags,
|
|
312
311
|
[GIT_REPOSITORY_URL]: `https://github.com/${APPVEYOR_REPO_NAME}.git`,
|
|
313
312
|
[GIT_COMMIT_SHA]: APPVEYOR_REPO_COMMIT,
|
|
314
|
-
[
|
|
313
|
+
[GIT_TAG]: APPVEYOR_REPO_TAG_NAME,
|
|
314
|
+
[GIT_BRANCH]: APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH || APPVEYOR_REPO_BRANCH
|
|
315
315
|
}
|
|
316
316
|
}
|
|
317
317
|
}
|
|
@@ -340,7 +340,7 @@ module.exports = {
|
|
|
340
340
|
} = env
|
|
341
341
|
|
|
342
342
|
const ref = SYSTEM_PULLREQUEST_SOURCEBRANCH || BUILD_SOURCEBRANCH || BUILD_SOURCEBRANCHNAME
|
|
343
|
-
const refKey = (ref || '').includes('tags') ? GIT_TAG : GIT_BRANCH
|
|
343
|
+
const refKey = (ref || '').includes('tags/') ? GIT_TAG : GIT_BRANCH
|
|
344
344
|
|
|
345
345
|
tags = {
|
|
346
346
|
[CI_PROVIDER_NAME]: 'azurepipelines',
|
|
@@ -419,10 +419,6 @@ module.exports = {
|
|
|
419
419
|
BITRISE_GIT_MESSAGE
|
|
420
420
|
} = env
|
|
421
421
|
|
|
422
|
-
const isTag = !!BITRISE_GIT_TAG
|
|
423
|
-
const refKey = isTag ? GIT_TAG : GIT_BRANCH
|
|
424
|
-
const ref = BITRISE_GIT_TAG || BITRISEIO_GIT_BRANCH_DEST || BITRISE_GIT_BRANCH
|
|
425
|
-
|
|
426
422
|
tags = {
|
|
427
423
|
[CI_PROVIDER_NAME]: 'bitrise',
|
|
428
424
|
[CI_PIPELINE_ID]: BITRISE_BUILD_SLUG,
|
|
@@ -432,7 +428,8 @@ module.exports = {
|
|
|
432
428
|
[GIT_COMMIT_SHA]: BITRISE_GIT_COMMIT || GIT_CLONE_COMMIT_HASH,
|
|
433
429
|
[GIT_REPOSITORY_URL]: BITRISE_GIT_REPOSITORY_URL,
|
|
434
430
|
[CI_WORKSPACE_PATH]: BITRISE_SOURCE_DIR,
|
|
435
|
-
[
|
|
431
|
+
[GIT_TAG]: BITRISE_GIT_TAG,
|
|
432
|
+
[GIT_BRANCH]: BITRISEIO_GIT_BRANCH_DEST || BITRISE_GIT_BRANCH,
|
|
436
433
|
[GIT_COMMIT_MESSAGE]: BITRISE_GIT_MESSAGE
|
|
437
434
|
}
|
|
438
435
|
}
|
|
@@ -454,9 +451,6 @@ module.exports = {
|
|
|
454
451
|
BUILDKITE_MESSAGE
|
|
455
452
|
} = env
|
|
456
453
|
|
|
457
|
-
const ref = BUILDKITE_TAG || BUILDKITE_BRANCH
|
|
458
|
-
const refKey = BUILDKITE_TAG ? GIT_TAG : GIT_BRANCH
|
|
459
|
-
|
|
460
454
|
tags = {
|
|
461
455
|
[CI_PROVIDER_NAME]: 'buildkite',
|
|
462
456
|
[CI_PIPELINE_ID]: BUILDKITE_BUILD_ID,
|
|
@@ -467,7 +461,8 @@ module.exports = {
|
|
|
467
461
|
[GIT_COMMIT_SHA]: BUILDKITE_COMMIT,
|
|
468
462
|
[CI_WORKSPACE_PATH]: BUILDKITE_BUILD_CHECKOUT_PATH,
|
|
469
463
|
[GIT_REPOSITORY_URL]: BUILDKITE_REPO,
|
|
470
|
-
[
|
|
464
|
+
[GIT_TAG]: BUILDKITE_TAG,
|
|
465
|
+
[GIT_BRANCH]: BUILDKITE_BRANCH,
|
|
471
466
|
[GIT_COMMIT_AUTHOR_NAME]: BUILDKITE_BUILD_AUTHOR,
|
|
472
467
|
[GIT_COMMIT_AUTHOR_EMAIL]: BUILDKITE_BUILD_AUTHOR_EMAIL,
|
|
473
468
|
[GIT_COMMIT_MESSAGE]: BUILDKITE_MESSAGE,
|
|
@@ -493,10 +488,6 @@ module.exports = {
|
|
|
493
488
|
TRAVIS_COMMIT_MESSAGE
|
|
494
489
|
} = env
|
|
495
490
|
|
|
496
|
-
const isTag = !!TRAVIS_TAG
|
|
497
|
-
const ref = TRAVIS_TAG || TRAVIS_PULL_REQUEST_BRANCH || TRAVIS_BRANCH
|
|
498
|
-
const refKey = isTag ? GIT_TAG : GIT_BRANCH
|
|
499
|
-
|
|
500
491
|
tags = {
|
|
501
492
|
[CI_PROVIDER_NAME]: 'travisci',
|
|
502
493
|
[CI_JOB_URL]: TRAVIS_JOB_WEB_URL,
|
|
@@ -507,7 +498,8 @@ module.exports = {
|
|
|
507
498
|
[GIT_COMMIT_SHA]: TRAVIS_COMMIT,
|
|
508
499
|
[GIT_REPOSITORY_URL]: `https://github.com/${TRAVIS_REPO_SLUG}.git`,
|
|
509
500
|
[CI_WORKSPACE_PATH]: TRAVIS_BUILD_DIR,
|
|
510
|
-
[
|
|
501
|
+
[GIT_TAG]: TRAVIS_TAG,
|
|
502
|
+
[GIT_BRANCH]: TRAVIS_PULL_REQUEST_BRANCH || TRAVIS_BRANCH,
|
|
511
503
|
[GIT_COMMIT_MESSAGE]: TRAVIS_COMMIT_MESSAGE
|
|
512
504
|
}
|
|
513
505
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const
|
|
1
|
+
const cp = require('child_process')
|
|
2
2
|
|
|
3
3
|
const sanitizedExec = (cmd, options = {}) => {
|
|
4
4
|
try {
|
|
5
|
-
return execSync(cmd, options).toString().replace(/(\r\n|\n|\r)/gm, '')
|
|
5
|
+
return cp.execSync(cmd, options).toString().replace(/(\r\n|\n|\r)/gm, '')
|
|
6
6
|
} catch (e) {
|
|
7
7
|
return ''
|
|
8
8
|
}
|
|
@@ -21,6 +21,19 @@ const {
|
|
|
21
21
|
|
|
22
22
|
const GIT_REV_LIST_MAX_BUFFER = 8 * 1024 * 1024 // 8MB
|
|
23
23
|
|
|
24
|
+
function isShallowRepository () {
|
|
25
|
+
return sanitizedExec('git rev-parse --is-shallow-repository', { stdio: 'pipe' }) === 'true'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function unshallowRepository () {
|
|
29
|
+
try {
|
|
30
|
+
execSync('git config remote.origin.partialclonefilter "blob:none"', { stdio: 'pipe' })
|
|
31
|
+
execSync('git fetch --shallow-since="1 month ago" --update-shallow --refetch', { stdio: 'pipe' })
|
|
32
|
+
} catch (err) {
|
|
33
|
+
log.error(err)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
24
37
|
function getRepositoryUrl () {
|
|
25
38
|
return sanitizedExec('git config --get remote.origin.url', { stdio: 'pipe' })
|
|
26
39
|
}
|
|
@@ -146,5 +159,7 @@ module.exports = {
|
|
|
146
159
|
getRepositoryUrl,
|
|
147
160
|
generatePackFilesForCommits,
|
|
148
161
|
getCommitsToUpload,
|
|
149
|
-
GIT_REV_LIST_MAX_BUFFER
|
|
162
|
+
GIT_REV_LIST_MAX_BUFFER,
|
|
163
|
+
isShallowRepository,
|
|
164
|
+
unshallowRepository
|
|
150
165
|
}
|
|
@@ -38,7 +38,9 @@ const TEST_CODE_OWNERS = 'test.codeowners'
|
|
|
38
38
|
const TEST_SOURCE_FILE = 'test.source.file'
|
|
39
39
|
const LIBRARY_VERSION = 'library_version'
|
|
40
40
|
const TEST_COMMAND = 'test.command'
|
|
41
|
+
const TEST_BUNDLE = 'test.bundle'
|
|
41
42
|
const TEST_SESSION_ID = 'test_session_id'
|
|
43
|
+
const TEST_MODULE_ID = 'test_module_id'
|
|
42
44
|
const TEST_SUITE_ID = 'test_suite_id'
|
|
43
45
|
|
|
44
46
|
const CI_APP_ORIGIN = 'ciapp-test'
|
|
@@ -48,6 +50,8 @@ const JEST_TEST_RUNNER = 'test.jest.test_runner'
|
|
|
48
50
|
const TEST_ITR_TESTS_SKIPPED = '_dd.ci.itr.tests_skipped'
|
|
49
51
|
const TEST_SESSION_ITR_SKIPPING_ENABLED = 'test_session.itr.tests_skipping.enabled'
|
|
50
52
|
const TEST_SESSION_CODE_COVERAGE_ENABLED = 'test_session.code_coverage.enabled'
|
|
53
|
+
const TEST_MODULE_ITR_SKIPPING_ENABLED = 'test_module.itr.tests_skipping.enabled'
|
|
54
|
+
const TEST_MODULE_CODE_COVERAGE_ENABLED = 'test_module.code_coverage.enabled'
|
|
51
55
|
|
|
52
56
|
const TEST_CODE_COVERAGE_LINES_TOTAL = 'test.codecov_lines_total'
|
|
53
57
|
|
|
@@ -75,14 +79,20 @@ module.exports = {
|
|
|
75
79
|
getCodeOwnersForFilename,
|
|
76
80
|
getTestCommonTags,
|
|
77
81
|
getTestSessionCommonTags,
|
|
82
|
+
getTestModuleCommonTags,
|
|
78
83
|
getTestSuiteCommonTags,
|
|
79
84
|
TEST_COMMAND,
|
|
80
85
|
TEST_SESSION_ID,
|
|
86
|
+
TEST_MODULE_ID,
|
|
81
87
|
TEST_SUITE_ID,
|
|
82
88
|
TEST_ITR_TESTS_SKIPPED,
|
|
89
|
+
TEST_BUNDLE,
|
|
83
90
|
TEST_SESSION_ITR_SKIPPING_ENABLED,
|
|
84
91
|
TEST_SESSION_CODE_COVERAGE_ENABLED,
|
|
92
|
+
TEST_MODULE_ITR_SKIPPING_ENABLED,
|
|
93
|
+
TEST_MODULE_CODE_COVERAGE_ENABLED,
|
|
85
94
|
TEST_CODE_COVERAGE_LINES_TOTAL,
|
|
95
|
+
addIntelligentTestRunnerSpanTags,
|
|
86
96
|
getCoveredFilenamesFromCoverage,
|
|
87
97
|
resetCoverage,
|
|
88
98
|
mergeCoverage,
|
|
@@ -242,26 +252,59 @@ function getCodeOwnersForFilename (filename, entries) {
|
|
|
242
252
|
return null
|
|
243
253
|
}
|
|
244
254
|
|
|
245
|
-
function
|
|
255
|
+
function getTestLevelCommonTags (command, testFrameworkVersion) {
|
|
256
|
+
return {
|
|
257
|
+
[TEST_FRAMEWORK_VERSION]: testFrameworkVersion,
|
|
258
|
+
[LIBRARY_VERSION]: ddTraceVersion,
|
|
259
|
+
[TEST_COMMAND]: command,
|
|
260
|
+
[TEST_TYPE]: 'test'
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function getTestSessionCommonTags (command, testFrameworkVersion) {
|
|
246
265
|
return {
|
|
247
266
|
[SPAN_TYPE]: 'test_session_end',
|
|
248
|
-
[TEST_TYPE]: 'test',
|
|
249
267
|
[RESOURCE_NAME]: `test_session.${command}`,
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
268
|
+
...getTestLevelCommonTags(command, testFrameworkVersion)
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function getTestModuleCommonTags (command, testFrameworkVersion) {
|
|
273
|
+
return {
|
|
274
|
+
[SPAN_TYPE]: 'test_module_end',
|
|
275
|
+
[RESOURCE_NAME]: `test_module.${command}`,
|
|
276
|
+
[TEST_BUNDLE]: command,
|
|
277
|
+
...getTestLevelCommonTags(command, testFrameworkVersion)
|
|
253
278
|
}
|
|
254
279
|
}
|
|
255
280
|
|
|
256
|
-
function getTestSuiteCommonTags (command,
|
|
281
|
+
function getTestSuiteCommonTags (command, testFrameworkVersion, testSuite) {
|
|
257
282
|
return {
|
|
258
283
|
[SPAN_TYPE]: 'test_suite_end',
|
|
259
|
-
[TEST_TYPE]: 'test',
|
|
260
284
|
[RESOURCE_NAME]: `test_suite.${testSuite}`,
|
|
261
|
-
[
|
|
262
|
-
[LIBRARY_VERSION]: ddTraceVersion,
|
|
285
|
+
[TEST_BUNDLE]: command,
|
|
263
286
|
[TEST_SUITE]: testSuite,
|
|
264
|
-
|
|
287
|
+
...getTestLevelCommonTags(command, testFrameworkVersion)
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function addIntelligentTestRunnerSpanTags (
|
|
292
|
+
testSessionSpan,
|
|
293
|
+
testModuleSpan,
|
|
294
|
+
{ isSuitesSkipped, isSuitesSkippingEnabled, isCodeCoverageEnabled, testCodeCoverageLinesTotal }
|
|
295
|
+
) {
|
|
296
|
+
testSessionSpan.setTag(TEST_ITR_TESTS_SKIPPED, isSuitesSkipped ? 'true' : 'false')
|
|
297
|
+
testSessionSpan.setTag(TEST_SESSION_ITR_SKIPPING_ENABLED, isSuitesSkippingEnabled ? 'true' : 'false')
|
|
298
|
+
testSessionSpan.setTag(TEST_SESSION_CODE_COVERAGE_ENABLED, isCodeCoverageEnabled ? 'true' : 'false')
|
|
299
|
+
|
|
300
|
+
testModuleSpan.setTag(TEST_ITR_TESTS_SKIPPED, isSuitesSkipped ? 'true' : 'false')
|
|
301
|
+
testModuleSpan.setTag(TEST_MODULE_ITR_SKIPPING_ENABLED, isSuitesSkippingEnabled ? 'true' : 'false')
|
|
302
|
+
testModuleSpan.setTag(TEST_MODULE_CODE_COVERAGE_ENABLED, isCodeCoverageEnabled ? 'true' : 'false')
|
|
303
|
+
|
|
304
|
+
// If suites have been skipped we don't want to report the total coverage, as it will be wrong
|
|
305
|
+
if (testCodeCoverageLinesTotal !== undefined && !isSuitesSkipped) {
|
|
306
|
+
testSessionSpan.setTag(TEST_CODE_COVERAGE_LINES_TOTAL, testCodeCoverageLinesTotal)
|
|
307
|
+
testModuleSpan.setTag(TEST_CODE_COVERAGE_LINES_TOTAL, testCodeCoverageLinesTotal)
|
|
265
308
|
}
|
|
266
309
|
}
|
|
267
310
|
|
|
@@ -54,16 +54,11 @@ function getUserProviderGitMetadata () {
|
|
|
54
54
|
DD_GIT_COMMIT_AUTHOR_DATE
|
|
55
55
|
} = process.env
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
const branch = normalizeRef(DD_GIT_BRANCH)
|
|
58
58
|
let tag = normalizeRef(DD_GIT_TAG)
|
|
59
59
|
|
|
60
|
-
if
|
|
61
|
-
branch = undefined
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// if DD_GIT_BRANCH is a tag, we associate its value to TAG instead of BRANCH
|
|
60
|
+
// if DD_GIT_BRANCH is a tag, we associate its value to TAG too
|
|
65
61
|
if ((DD_GIT_BRANCH || '').includes('origin/tags') || (DD_GIT_BRANCH || '').includes('refs/heads/tags')) {
|
|
66
|
-
branch = undefined
|
|
67
62
|
tag = normalizeRef(DD_GIT_BRANCH)
|
|
68
63
|
}
|
|
69
64
|
|
|
@@ -8,6 +8,7 @@ const tags = require('../../../../../ext/tags')
|
|
|
8
8
|
const types = require('../../../../../ext/types')
|
|
9
9
|
const kinds = require('../../../../../ext/kinds')
|
|
10
10
|
const urlFilter = require('./urlfilter')
|
|
11
|
+
const { extractIp } = require('./ip_extractor')
|
|
11
12
|
const { ERROR_MESSAGE, ERROR_TYPE, ERROR_STACK } = require('../../constants')
|
|
12
13
|
|
|
13
14
|
const WEB = types.WEB
|
|
@@ -24,6 +25,7 @@ const HTTP_ROUTE = tags.HTTP_ROUTE
|
|
|
24
25
|
const HTTP_REQUEST_HEADERS = tags.HTTP_REQUEST_HEADERS
|
|
25
26
|
const HTTP_RESPONSE_HEADERS = tags.HTTP_RESPONSE_HEADERS
|
|
26
27
|
const HTTP_USERAGENT = tags.HTTP_USERAGENT
|
|
28
|
+
const HTTP_CLIENT_IP = tags.HTTP_CLIENT_IP
|
|
27
29
|
const MANUAL_DROP = tags.MANUAL_DROP
|
|
28
30
|
|
|
29
31
|
const HTTP2_HEADER_AUTHORITY = ':authority'
|
|
@@ -432,6 +434,15 @@ function addRequestTags (context) {
|
|
|
432
434
|
[HTTP_USERAGENT]: req.headers['user-agent']
|
|
433
435
|
})
|
|
434
436
|
|
|
437
|
+
// if client ip has already been set by appsec, no need to run it again
|
|
438
|
+
if (config.clientIpEnabled && !span.context()._tags.hasOwnProperty(HTTP_CLIENT_IP)) {
|
|
439
|
+
const clientIp = extractIp(config, req)
|
|
440
|
+
|
|
441
|
+
if (clientIp) {
|
|
442
|
+
span.setTag(HTTP_CLIENT_IP, clientIp)
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
435
446
|
addHeaders(context)
|
|
436
447
|
}
|
|
437
448
|
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
const log = require('./log')
|
|
4
4
|
const { profiler } = require('./profiling')
|
|
5
5
|
|
|
6
|
+
// Stop profiler upon exit in order to collect and export the current profile
|
|
7
|
+
process.once('beforeExit', () => { profiler.stop() })
|
|
8
|
+
|
|
6
9
|
module.exports = {
|
|
7
10
|
start: config => {
|
|
8
11
|
const { service, version, env, url, hostname, port, tags } = config
|
|
@@ -23,7 +23,9 @@ const {
|
|
|
23
23
|
DD_AGENT_HOST,
|
|
24
24
|
DD_TRACE_AGENT_PORT,
|
|
25
25
|
DD_PROFILING_UPLOAD_TIMEOUT,
|
|
26
|
-
DD_PROFILING_SOURCE_MAP
|
|
26
|
+
DD_PROFILING_SOURCE_MAP,
|
|
27
|
+
DD_PROFILING_UPLOAD_PERIOD,
|
|
28
|
+
DD_PROFILING_PPROF_PREFIX
|
|
27
29
|
} = process.env
|
|
28
30
|
|
|
29
31
|
class Config {
|
|
@@ -35,13 +37,15 @@ class Config {
|
|
|
35
37
|
const version = coalesce(options.version, DD_VERSION)
|
|
36
38
|
const functionname = process.env.AWS_LAMBDA_FUNCTION_NAME
|
|
37
39
|
// Must be longer than one minute so pad with five seconds
|
|
38
|
-
const flushInterval = coalesce(options.interval, 65 * 1000)
|
|
40
|
+
const flushInterval = coalesce(options.interval, Number(DD_PROFILING_UPLOAD_PERIOD) * 1000, 65 * 1000)
|
|
39
41
|
const uploadTimeout = coalesce(options.uploadTimeout,
|
|
40
|
-
DD_PROFILING_UPLOAD_TIMEOUT, 60 * 1000)
|
|
42
|
+
Number(DD_PROFILING_UPLOAD_TIMEOUT), 60 * 1000)
|
|
41
43
|
const sourceMap = coalesce(options.sourceMap,
|
|
42
44
|
DD_PROFILING_SOURCE_MAP, true)
|
|
43
45
|
const endpointCollection = coalesce(options.endpointCollection,
|
|
44
46
|
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED, false)
|
|
47
|
+
const pprofPrefix = coalesce(options.pprofPrefix,
|
|
48
|
+
DD_PROFILING_PPROF_PREFIX)
|
|
45
49
|
|
|
46
50
|
this.enabled = String(enabled) !== 'false'
|
|
47
51
|
this.service = service
|
|
@@ -60,6 +64,7 @@ class Config {
|
|
|
60
64
|
this.uploadTimeout = uploadTimeout
|
|
61
65
|
this.sourceMap = sourceMap
|
|
62
66
|
this.endpointCollection = endpointCollection
|
|
67
|
+
this.pprofPrefix = pprofPrefix
|
|
63
68
|
|
|
64
69
|
const hostname = coalesce(options.hostname, DD_AGENT_HOST) || 'localhost'
|
|
65
70
|
const port = coalesce(options.port, DD_TRACE_AGENT_PORT) || 8126
|
|
@@ -4,11 +4,22 @@ const fs = require('fs')
|
|
|
4
4
|
const { promisify } = require('util')
|
|
5
5
|
const writeFile = promisify(fs.writeFile)
|
|
6
6
|
|
|
7
|
+
function formatDateTime (t) {
|
|
8
|
+
const pad = (n) => String(n).padStart(2, '0')
|
|
9
|
+
return `${t.getUTCFullYear()}${pad(t.getUTCMonth() + 1)}${pad(t.getUTCDate())}` +
|
|
10
|
+
`T${pad(t.getUTCHours())}${pad(t.getUTCMinutes())}${pad(t.getUTCSeconds())}Z`
|
|
11
|
+
}
|
|
12
|
+
|
|
7
13
|
class FileExporter {
|
|
8
|
-
|
|
14
|
+
constructor ({ pprofPrefix } = {}) {
|
|
15
|
+
this._pprofPrefix = pprofPrefix || ''
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export ({ profiles, end }) {
|
|
9
19
|
const types = Object.keys(profiles)
|
|
20
|
+
const dateStr = formatDateTime(end)
|
|
10
21
|
const tasks = types.map(type => {
|
|
11
|
-
return writeFile(`${type}.
|
|
22
|
+
return writeFile(`${this._pprofPrefix}${type}_${dateStr}.pprof`, profiles[type])
|
|
12
23
|
})
|
|
13
24
|
|
|
14
25
|
return Promise.all(tasks)
|
|
@@ -56,7 +56,7 @@ class Profiler extends EventEmitter {
|
|
|
56
56
|
this._capture(this._timeoutInterval)
|
|
57
57
|
} catch (e) {
|
|
58
58
|
this._logger.error(e)
|
|
59
|
-
this.
|
|
59
|
+
this._stop()
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -64,7 +64,16 @@ class Profiler extends EventEmitter {
|
|
|
64
64
|
this._timeoutInterval = this._config.flushInterval
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
stop () {
|
|
67
|
+
async stop () {
|
|
68
|
+
if (!this._enabled) return
|
|
69
|
+
|
|
70
|
+
// collect and export current profiles
|
|
71
|
+
// once collect returns, profilers can be safely stopped
|
|
72
|
+
this._collect()
|
|
73
|
+
this._stop()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
_stop () {
|
|
68
77
|
if (!this._enabled) return
|
|
69
78
|
|
|
70
79
|
this._enabled = false
|
|
@@ -92,16 +101,24 @@ class Profiler extends EventEmitter {
|
|
|
92
101
|
}
|
|
93
102
|
|
|
94
103
|
async _collect () {
|
|
104
|
+
if (!this._enabled) return
|
|
105
|
+
|
|
95
106
|
const start = this._lastStart
|
|
96
107
|
const end = new Date()
|
|
97
|
-
const profiles =
|
|
108
|
+
const profiles = []
|
|
109
|
+
const encodedProfiles = {}
|
|
98
110
|
|
|
99
111
|
try {
|
|
112
|
+
// collect profiles synchronously so that profilers can be safely stopped asynchronously
|
|
100
113
|
for (const profiler of this._config.profilers) {
|
|
101
114
|
const profile = profiler.profile()
|
|
102
115
|
if (!profile) continue
|
|
116
|
+
profiles.push({ profiler, profile })
|
|
117
|
+
}
|
|
103
118
|
|
|
104
|
-
|
|
119
|
+
// encode and export asynchronously
|
|
120
|
+
for (const { profiler, profile } of profiles) {
|
|
121
|
+
encodedProfiles[profiler.type] = await profiler.encode(profile)
|
|
105
122
|
this._logger.debug(() => {
|
|
106
123
|
const profileJson = JSON.stringify(profile, (key, value) => {
|
|
107
124
|
return typeof value === 'bigint' ? value.toString() : value
|
|
@@ -111,11 +128,11 @@ class Profiler extends EventEmitter {
|
|
|
111
128
|
}
|
|
112
129
|
|
|
113
130
|
this._capture(this._timeoutInterval)
|
|
114
|
-
await this._submit(
|
|
131
|
+
await this._submit(encodedProfiles, start, end)
|
|
115
132
|
this._logger.debug('Submitted profiles')
|
|
116
133
|
} catch (err) {
|
|
117
134
|
this._logger.error(err)
|
|
118
|
-
this.
|
|
135
|
+
this._stop()
|
|
119
136
|
}
|
|
120
137
|
}
|
|
121
138
|
|
|
@@ -8,6 +8,7 @@ const { setStartupLogPluginManager } = require('./startup-log')
|
|
|
8
8
|
const telemetry = require('./telemetry')
|
|
9
9
|
const PluginManager = require('./plugin_manager')
|
|
10
10
|
const remoteConfig = require('./appsec/remote_config')
|
|
11
|
+
const AppsecSdk = require('./appsec/sdk')
|
|
11
12
|
|
|
12
13
|
class Tracer extends NoopProxy {
|
|
13
14
|
constructor () {
|
|
@@ -50,6 +51,7 @@ class Tracer extends NoopProxy {
|
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
this._tracer = new DatadogTracer(config)
|
|
54
|
+
this.appsec = new AppsecSdk(this._tracer, config)
|
|
53
55
|
|
|
54
56
|
if (config.iast.enabled) {
|
|
55
57
|
require('./appsec/iast').enable(config, this._tracer)
|
|
@@ -2,76 +2,92 @@
|
|
|
2
2
|
const { globMatch } = require('../src/util')
|
|
3
3
|
const { USER_KEEP, AUTO_KEEP } = require('../../../ext').priority
|
|
4
4
|
const RateLimiter = require('./rate_limiter')
|
|
5
|
+
const Sampler = require('./sampler')
|
|
5
6
|
|
|
6
|
-
class
|
|
7
|
-
constructor ({
|
|
8
|
-
this.
|
|
9
|
-
this.
|
|
7
|
+
class SpanSamplingRule {
|
|
8
|
+
constructor ({ service, name, sampleRate = 1.0, maxPerSecond } = {}) {
|
|
9
|
+
this.service = service
|
|
10
|
+
this.name = name
|
|
11
|
+
|
|
12
|
+
this._sampler = new Sampler(sampleRate)
|
|
13
|
+
this._limiter = undefined
|
|
14
|
+
|
|
15
|
+
if (Number.isFinite(maxPerSecond)) {
|
|
16
|
+
this._limiter = new RateLimiter(maxPerSecond)
|
|
17
|
+
}
|
|
10
18
|
}
|
|
11
19
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
20
|
+
get sampleRate () {
|
|
21
|
+
return this._sampler.rate()
|
|
22
|
+
}
|
|
15
23
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const name = span._name
|
|
20
|
-
const rule = findRule(this._rules, service, name)
|
|
21
|
-
if (!rule) continue
|
|
24
|
+
get maxPerSecond () {
|
|
25
|
+
return this._limiter && this._limiter._rateLimit
|
|
26
|
+
}
|
|
22
27
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (!sampled) continue
|
|
28
|
+
static from (config) {
|
|
29
|
+
return new SpanSamplingRule(config)
|
|
30
|
+
}
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
span.context()._sampling.spanSampling = {
|
|
32
|
-
sampleRate,
|
|
33
|
-
maxPerSecond
|
|
34
|
-
}
|
|
35
|
-
}
|
|
32
|
+
match (service, name) {
|
|
33
|
+
if (this.service && !globMatch(this.service, service)) {
|
|
34
|
+
return false
|
|
36
35
|
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const servicePattern = getService(rule.service)
|
|
43
|
-
const namePattern = getName(rule.name)
|
|
44
|
-
if (globMatch(servicePattern, service) && globMatch(namePattern, name)) {
|
|
45
|
-
return rule
|
|
37
|
+
if (this.name && !globMatch(this.name, name)) {
|
|
38
|
+
return false
|
|
46
39
|
}
|
|
40
|
+
|
|
41
|
+
return true
|
|
47
42
|
}
|
|
48
|
-
}
|
|
49
43
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
44
|
+
sample () {
|
|
45
|
+
if (!this._sampler.isSampled()) {
|
|
46
|
+
return false
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (this._limiter) {
|
|
50
|
+
return this._limiter.isAllowed()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return true
|
|
53
54
|
}
|
|
54
|
-
return list[key]
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
class SpanSampler {
|
|
58
|
+
constructor ({ spanSamplingRules = [] } = {}) {
|
|
59
|
+
this._rules = spanSamplingRules.map(SpanSamplingRule.from)
|
|
60
|
+
}
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
findRule (service, name) {
|
|
63
|
+
for (const rule of this._rules) {
|
|
64
|
+
if (rule.match(service, name)) {
|
|
65
|
+
return rule
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
64
69
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
70
|
+
sample (spanContext) {
|
|
71
|
+
const decision = spanContext._sampling.priority
|
|
72
|
+
if (decision === USER_KEEP || decision === AUTO_KEEP) return
|
|
68
73
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
74
|
+
const { started } = spanContext._trace
|
|
75
|
+
for (const span of started) {
|
|
76
|
+
const tags = span.context()._tags || {}
|
|
77
|
+
const name = span._name
|
|
78
|
+
const service = tags.service ||
|
|
79
|
+
tags['service.name'] ||
|
|
80
|
+
span.tracer()._service
|
|
72
81
|
|
|
73
|
-
|
|
74
|
-
|
|
82
|
+
const rule = this.findRule(service, name)
|
|
83
|
+
if (rule && rule.sample()) {
|
|
84
|
+
span.context()._sampling.spanSampling = {
|
|
85
|
+
sampleRate: rule.sampleRate,
|
|
86
|
+
maxPerSecond: rule.maxPerSecond
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
75
91
|
}
|
|
76
92
|
|
|
77
93
|
module.exports = SpanSampler
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const { info, warn } = require('./log/writer')
|
|
4
4
|
|
|
5
5
|
const os = require('os')
|
|
6
6
|
const { inspect } = require('util')
|
|
7
7
|
const tracerVersion = require('../../../package.json').version
|
|
8
8
|
|
|
9
|
-
const logger = Object.create(mainLogger)
|
|
10
|
-
logger._enabled = true
|
|
11
|
-
|
|
12
9
|
let config
|
|
13
10
|
let pluginManager
|
|
14
11
|
let samplingRules = []
|
|
@@ -89,9 +86,9 @@ function startupLog ({ agentError } = {}) {
|
|
|
89
86
|
// out.service_mapping
|
|
90
87
|
// out.service_mapping_error
|
|
91
88
|
|
|
92
|
-
|
|
89
|
+
info('DATADOG TRACER CONFIGURATION - ' + out)
|
|
93
90
|
if (agentError) {
|
|
94
|
-
|
|
91
|
+
warn('DATADOG TRACER DIAGNOSTIC - Agent Error: ' + agentError.message)
|
|
95
92
|
}
|
|
96
93
|
|
|
97
94
|
config = undefined
|