dd-trace 4.18.0 → 5.6.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/CONTRIBUTING.md +98 -0
- package/LICENSE-3rdparty.csv +4 -5
- package/MIGRATING.md +15 -0
- package/README.md +20 -140
- package/ci/cypress/after-run.js +1 -0
- package/ci/cypress/after-spec.js +1 -0
- package/ci/init.js +1 -4
- package/ext/kinds.d.ts +1 -0
- package/ext/kinds.js +2 -1
- package/ext/tags.d.ts +2 -1
- package/ext/tags.js +6 -1
- package/index.d.ts +1523 -1460
- package/package.json +19 -19
- package/packages/datadog-core/src/storage/async_resource.js +1 -1
- package/packages/datadog-core/src/utils/src/get.js +11 -0
- package/packages/datadog-core/src/utils/src/has.js +14 -0
- package/packages/datadog-core/src/utils/src/kebabcase.js +16 -0
- package/packages/datadog-core/src/utils/src/pick.js +11 -0
- package/packages/datadog-core/src/utils/src/set.js +16 -0
- package/packages/datadog-core/src/utils/src/uniq.js +5 -0
- package/packages/datadog-esbuild/index.js +1 -20
- package/packages/datadog-instrumentations/src/aerospike.js +47 -0
- package/packages/datadog-instrumentations/src/amqplib.js +2 -2
- package/packages/datadog-instrumentations/src/apollo-server-core.js +41 -0
- package/packages/datadog-instrumentations/src/apollo-server.js +83 -0
- package/packages/datadog-instrumentations/src/child_process.js +150 -0
- package/packages/datadog-instrumentations/src/couchbase.js +5 -4
- package/packages/datadog-instrumentations/src/crypto.js +2 -1
- package/packages/datadog-instrumentations/src/cucumber.js +163 -46
- package/packages/datadog-instrumentations/src/dns.js +2 -1
- package/packages/datadog-instrumentations/src/express.js +20 -0
- package/packages/datadog-instrumentations/src/graphql.js +18 -4
- package/packages/datadog-instrumentations/src/grpc/client.js +56 -36
- package/packages/datadog-instrumentations/src/grpc/server.js +3 -1
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +1 -2
- package/packages/datadog-instrumentations/src/helpers/hooks.js +12 -3
- package/packages/datadog-instrumentations/src/helpers/instrument.js +9 -4
- package/packages/datadog-instrumentations/src/helpers/register.js +19 -3
- package/packages/datadog-instrumentations/src/http/client.js +12 -2
- package/packages/datadog-instrumentations/src/http/server.js +7 -4
- package/packages/datadog-instrumentations/src/http2/client.js +3 -1
- package/packages/datadog-instrumentations/src/http2/server.js +3 -1
- package/packages/datadog-instrumentations/src/jest.js +239 -52
- package/packages/datadog-instrumentations/src/kafkajs.js +27 -0
- package/packages/datadog-instrumentations/src/mocha.js +154 -18
- package/packages/datadog-instrumentations/src/mongodb-core.js +34 -3
- package/packages/datadog-instrumentations/src/mongoose.js +23 -10
- package/packages/datadog-instrumentations/src/mquery.js +65 -0
- package/packages/datadog-instrumentations/src/net.js +10 -2
- package/packages/datadog-instrumentations/src/next.js +35 -9
- package/packages/datadog-instrumentations/src/playwright.js +110 -16
- package/packages/datadog-instrumentations/src/restify.js +14 -1
- package/packages/datadog-instrumentations/src/rhea.js +15 -9
- package/packages/datadog-plugin-aerospike/src/index.js +113 -0
- package/packages/datadog-plugin-amqplib/src/consumer.js +14 -1
- package/packages/datadog-plugin-amqplib/src/producer.js +13 -1
- package/packages/datadog-plugin-aws-sdk/src/base.js +3 -2
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +163 -27
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +46 -8
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +129 -22
- package/packages/datadog-plugin-child_process/src/index.js +91 -0
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +125 -0
- package/packages/datadog-plugin-cucumber/src/index.js +70 -13
- package/packages/datadog-plugin-cypress/src/after-run.js +3 -0
- package/packages/datadog-plugin-cypress/src/after-spec.js +3 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +625 -0
- package/packages/datadog-plugin-cypress/src/plugin.js +6 -454
- package/packages/datadog-plugin-cypress/src/support.js +50 -3
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -0
- package/packages/datadog-plugin-graphql/src/index.js +1 -6
- package/packages/datadog-plugin-graphql/src/resolve.js +28 -18
- package/packages/datadog-plugin-grpc/src/client.js +16 -2
- package/packages/datadog-plugin-grpc/src/util.js +1 -1
- package/packages/datadog-plugin-http/src/client.js +19 -2
- package/packages/datadog-plugin-jest/src/index.js +118 -12
- package/packages/datadog-plugin-jest/src/util.js +38 -16
- package/packages/datadog-plugin-kafkajs/src/consumer.js +76 -6
- package/packages/datadog-plugin-kafkajs/src/producer.js +64 -8
- package/packages/datadog-plugin-mocha/src/index.js +87 -17
- package/packages/datadog-plugin-next/src/index.js +40 -14
- package/packages/datadog-plugin-playwright/src/index.js +71 -8
- package/packages/datadog-plugin-rhea/src/consumer.js +16 -1
- package/packages/datadog-plugin-rhea/src/producer.js +10 -0
- package/packages/dd-trace/src/appsec/activation.js +29 -0
- package/packages/dd-trace/src/appsec/addresses.js +5 -1
- package/packages/dd-trace/src/appsec/api_security_sampler.js +61 -0
- package/packages/dd-trace/src/appsec/blocked_templates.js +4 -1
- package/packages/dd-trace/src/appsec/blocking.js +95 -43
- package/packages/dd-trace/src/appsec/channels.js +7 -3
- package/packages/dd-trace/src/appsec/graphql.js +146 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +2 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/command-injection-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +105 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +22 -17
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +7 -28
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +10 -6
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-randomness-analyzer.js +19 -0
- package/packages/dd-trace/src/appsec/iast/context/context-plugin.js +90 -0
- package/packages/dd-trace/src/appsec/iast/context/kafka-ctx-plugin.js +14 -0
- package/packages/dd-trace/src/appsec/iast/iast-log.js +1 -1
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +13 -2
- package/packages/dd-trace/src/appsec/iast/index.js +15 -5
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +1 -1
- package/packages/dd-trace/src/appsec/iast/path-line.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +2 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +10 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +53 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +10 -46
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +13 -9
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +47 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +19 -6
- package/packages/dd-trace/src/appsec/iast/taint-tracking/source-types.js +3 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +41 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/constants.js +7 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +12 -19
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/header-sensitive-analyzer.js +20 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/json-sensitive-analyzer.js +6 -10
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +18 -25
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +79 -85
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +27 -36
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +14 -11
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +2 -0
- package/packages/dd-trace/src/appsec/index.js +49 -33
- package/packages/dd-trace/src/appsec/recommended.json +1763 -106
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +7 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +42 -16
- package/packages/dd-trace/src/appsec/remote_config/manager.js +9 -8
- package/packages/dd-trace/src/appsec/reporter.js +51 -34
- package/packages/dd-trace/src/appsec/rule_manager.js +11 -8
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -1
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +28 -13
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +0 -1
- package/packages/dd-trace/src/ci-visibility/{intelligent-test-runner/get-itr-configuration.js → early-flake-detection/get-known-tests.js} +17 -22
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +25 -6
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +30 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +2 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +30 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +95 -37
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +134 -61
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +37 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +131 -0
- package/packages/dd-trace/src/ci-visibility/telemetry.js +130 -0
- package/packages/dd-trace/src/config.js +561 -470
- package/packages/dd-trace/src/data_streams_context.js +1 -1
- package/packages/dd-trace/src/datastreams/pathway.js +58 -1
- package/packages/dd-trace/src/datastreams/processor.js +196 -27
- package/packages/dd-trace/src/datastreams/writer.js +11 -5
- package/packages/dd-trace/src/dogstatsd.js +3 -5
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +44 -6
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +14 -0
- package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +4 -0
- package/packages/dd-trace/src/exporters/common/form-data.js +4 -0
- package/packages/dd-trace/src/exporters/common/request.js +21 -3
- package/packages/dd-trace/src/format.js +30 -2
- package/packages/dd-trace/src/id.js +12 -0
- package/packages/dd-trace/src/iitm.js +1 -1
- package/packages/dd-trace/src/log/channels.js +1 -1
- package/packages/dd-trace/src/noop/proxy.js +4 -0
- package/packages/dd-trace/src/noop/span.js +1 -0
- package/packages/dd-trace/src/opentelemetry/span.js +104 -4
- package/packages/dd-trace/src/opentelemetry/tracer.js +9 -10
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +16 -7
- package/packages/dd-trace/src/opentracing/span.js +48 -4
- package/packages/dd-trace/src/opentracing/span_context.js +15 -6
- package/packages/dd-trace/src/opentracing/tracer.js +4 -3
- package/packages/dd-trace/src/plugin_manager.js +1 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +78 -19
- package/packages/dd-trace/src/plugins/database.js +1 -1
- package/packages/dd-trace/src/plugins/index.js +7 -0
- package/packages/dd-trace/src/plugins/plugin.js +1 -1
- package/packages/dd-trace/src/plugins/util/ci.js +6 -19
- package/packages/dd-trace/src/plugins/util/git.js +104 -22
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +7 -6
- package/packages/dd-trace/src/plugins/util/test.js +60 -10
- package/packages/dd-trace/src/plugins/util/url.js +26 -0
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +4 -16
- package/packages/dd-trace/src/plugins/util/web.js +1 -1
- package/packages/dd-trace/src/priority_sampler.js +30 -38
- package/packages/dd-trace/src/profiler.js +5 -3
- package/packages/dd-trace/src/profiling/config.js +77 -24
- package/packages/dd-trace/src/profiling/exporters/agent.js +77 -31
- package/packages/dd-trace/src/profiling/exporters/file.js +2 -1
- package/packages/dd-trace/src/profiling/profiler.js +33 -22
- package/packages/dd-trace/src/profiling/profilers/events.js +270 -0
- package/packages/dd-trace/src/profiling/profilers/shared.js +45 -0
- package/packages/dd-trace/src/profiling/profilers/space.js +18 -2
- package/packages/dd-trace/src/profiling/profilers/wall.js +146 -70
- package/packages/dd-trace/src/proxy.js +56 -24
- package/packages/dd-trace/src/ritm.js +1 -1
- package/packages/dd-trace/src/sampling_rule.js +130 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +5 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +4 -0
- package/packages/dd-trace/src/span_processor.js +9 -1
- package/packages/dd-trace/src/span_sampler.js +6 -64
- package/packages/dd-trace/src/spanleak.js +98 -0
- package/packages/dd-trace/src/startup-log.js +7 -1
- package/packages/dd-trace/src/telemetry/dependencies.js +56 -10
- package/packages/dd-trace/src/telemetry/index.js +182 -53
- package/packages/dd-trace/src/telemetry/logs/index.js +2 -2
- package/packages/dd-trace/src/telemetry/send-data.js +65 -7
- package/packages/dd-trace/src/tracer.js +12 -5
- package/register.js +4 -0
- package/scripts/install_plugin_modules.js +11 -3
- package/scripts/st.js +105 -0
- package/packages/datadog-instrumentations/src/child-process.js +0 -30
- package/packages/dd-trace/src/plugins/util/exec.js +0 -13
- package/packages/diagnostics_channel/index.js +0 -3
- package/packages/diagnostics_channel/src/index.js +0 -121
|
@@ -48,10 +48,17 @@ const TEST_MODULE_ID = 'test_module_id'
|
|
|
48
48
|
const TEST_SUITE_ID = 'test_suite_id'
|
|
49
49
|
const TEST_TOOLCHAIN = 'test.toolchain'
|
|
50
50
|
const TEST_SKIPPED_BY_ITR = 'test.skipped_by_itr'
|
|
51
|
+
// Browser used in browser test. Namespaced by test.configuration because it affects the fingerprint
|
|
52
|
+
const TEST_CONFIGURATION_BROWSER_NAME = 'test.configuration.browser_name'
|
|
53
|
+
// Early flake detection
|
|
54
|
+
const TEST_IS_NEW = 'test.is_new'
|
|
55
|
+
const TEST_EARLY_FLAKE_IS_RETRY = 'test.early_flake.is_retry'
|
|
56
|
+
const TEST_EARLY_FLAKE_IS_ENABLED = 'test.early_flake.is_enabled'
|
|
51
57
|
|
|
52
58
|
const CI_APP_ORIGIN = 'ciapp-test'
|
|
53
59
|
|
|
54
60
|
const JEST_TEST_RUNNER = 'test.jest.test_runner'
|
|
61
|
+
const JEST_DISPLAY_NAME = 'test.jest.display_name'
|
|
55
62
|
|
|
56
63
|
const TEST_ITR_TESTS_SKIPPED = '_dd.ci.itr.tests_skipped'
|
|
57
64
|
const TEST_ITR_SKIPPING_ENABLED = 'test.itr.tests_skipping.enabled'
|
|
@@ -60,6 +67,7 @@ const TEST_ITR_SKIPPING_COUNT = 'test.itr.tests_skipping.count'
|
|
|
60
67
|
const TEST_CODE_COVERAGE_ENABLED = 'test.code_coverage.enabled'
|
|
61
68
|
const TEST_ITR_UNSKIPPABLE = 'test.itr.unskippable'
|
|
62
69
|
const TEST_ITR_FORCED_RUN = 'test.itr.forced_run'
|
|
70
|
+
const ITR_CORRELATION_ID = 'itr_correlation_id'
|
|
63
71
|
|
|
64
72
|
const TEST_CODE_COVERAGE_LINES_PCT = 'test.code_coverage.lines_pct'
|
|
65
73
|
|
|
@@ -67,11 +75,16 @@ const TEST_CODE_COVERAGE_LINES_PCT = 'test.code_coverage.lines_pct'
|
|
|
67
75
|
const JEST_WORKER_TRACE_PAYLOAD_CODE = 60
|
|
68
76
|
const JEST_WORKER_COVERAGE_PAYLOAD_CODE = 61
|
|
69
77
|
|
|
78
|
+
// Early flake detection util strings
|
|
79
|
+
const EFD_STRING = "Retried by Datadog's Early Flake Detection"
|
|
80
|
+
const EFD_TEST_NAME_REGEX = new RegExp(EFD_STRING + ' \\(#\\d+\\): ', 'g')
|
|
81
|
+
|
|
70
82
|
module.exports = {
|
|
71
83
|
TEST_CODE_OWNERS,
|
|
72
84
|
TEST_FRAMEWORK,
|
|
73
85
|
TEST_FRAMEWORK_VERSION,
|
|
74
86
|
JEST_TEST_RUNNER,
|
|
87
|
+
JEST_DISPLAY_NAME,
|
|
75
88
|
TEST_TYPE,
|
|
76
89
|
TEST_NAME,
|
|
77
90
|
TEST_SUITE,
|
|
@@ -86,6 +99,10 @@ module.exports = {
|
|
|
86
99
|
JEST_WORKER_COVERAGE_PAYLOAD_CODE,
|
|
87
100
|
TEST_SOURCE_START,
|
|
88
101
|
TEST_SKIPPED_BY_ITR,
|
|
102
|
+
TEST_CONFIGURATION_BROWSER_NAME,
|
|
103
|
+
TEST_IS_NEW,
|
|
104
|
+
TEST_EARLY_FLAKE_IS_RETRY,
|
|
105
|
+
TEST_EARLY_FLAKE_IS_ENABLED,
|
|
89
106
|
getTestEnvironmentMetadata,
|
|
90
107
|
getTestParametersString,
|
|
91
108
|
finishAllTraceSpans,
|
|
@@ -111,6 +128,7 @@ module.exports = {
|
|
|
111
128
|
TEST_CODE_COVERAGE_LINES_PCT,
|
|
112
129
|
TEST_ITR_UNSKIPPABLE,
|
|
113
130
|
TEST_ITR_FORCED_RUN,
|
|
131
|
+
ITR_CORRELATION_ID,
|
|
114
132
|
addIntelligentTestRunnerSpanTags,
|
|
115
133
|
getCoveredFilenamesFromCoverage,
|
|
116
134
|
resetCoverage,
|
|
@@ -119,7 +137,11 @@ module.exports = {
|
|
|
119
137
|
getTestLineStart,
|
|
120
138
|
getCallSites,
|
|
121
139
|
removeInvalidMetadata,
|
|
122
|
-
parseAnnotations
|
|
140
|
+
parseAnnotations,
|
|
141
|
+
EFD_STRING,
|
|
142
|
+
EFD_TEST_NAME_REGEX,
|
|
143
|
+
removeEfdStringFromTestName,
|
|
144
|
+
addEfdStringToTestName
|
|
123
145
|
}
|
|
124
146
|
|
|
125
147
|
// Returns pkg manager and its version, separated by '-', e.g. npm-8.15.0 or yarn-1.22.19
|
|
@@ -251,7 +273,6 @@ function getTestCommonTags (name, suite, version, testFramework) {
|
|
|
251
273
|
[SAMPLING_PRIORITY]: AUTO_KEEP,
|
|
252
274
|
[TEST_NAME]: name,
|
|
253
275
|
[TEST_SUITE]: suite,
|
|
254
|
-
[TEST_SOURCE_FILE]: suite,
|
|
255
276
|
[RESOURCE_NAME]: `${suite}.${name}`,
|
|
256
277
|
[TEST_FRAMEWORK_VERSION]: version,
|
|
257
278
|
[LIBRARY_VERSION]: ddTraceVersion
|
|
@@ -279,16 +300,36 @@ const POSSIBLE_CODEOWNERS_LOCATIONS = [
|
|
|
279
300
|
'.gitlab/CODEOWNERS'
|
|
280
301
|
]
|
|
281
302
|
|
|
282
|
-
function
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
POSSIBLE_CODEOWNERS_LOCATIONS.forEach(location => {
|
|
303
|
+
function readCodeOwners (rootDir) {
|
|
304
|
+
for (const location of POSSIBLE_CODEOWNERS_LOCATIONS) {
|
|
286
305
|
try {
|
|
287
|
-
|
|
306
|
+
return fs.readFileSync(path.join(rootDir, location)).toString()
|
|
288
307
|
} catch (e) {
|
|
289
308
|
// retry with next path
|
|
290
309
|
}
|
|
291
|
-
}
|
|
310
|
+
}
|
|
311
|
+
return ''
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function getCodeOwnersFileEntries (rootDir) {
|
|
315
|
+
let codeOwnersContent
|
|
316
|
+
let usedRootDir = rootDir
|
|
317
|
+
let isTriedCwd = false
|
|
318
|
+
|
|
319
|
+
const processCwd = process.cwd()
|
|
320
|
+
|
|
321
|
+
if (!usedRootDir || usedRootDir === processCwd) {
|
|
322
|
+
usedRootDir = processCwd
|
|
323
|
+
isTriedCwd = true
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
codeOwnersContent = readCodeOwners(usedRootDir)
|
|
327
|
+
|
|
328
|
+
// If we haven't found CODEOWNERS in the provided root dir, we try with process.cwd()
|
|
329
|
+
if (!codeOwnersContent && !isTriedCwd) {
|
|
330
|
+
codeOwnersContent = readCodeOwners(processCwd)
|
|
331
|
+
}
|
|
332
|
+
|
|
292
333
|
if (!codeOwnersContent) {
|
|
293
334
|
return null
|
|
294
335
|
}
|
|
@@ -397,8 +438,9 @@ function addIntelligentTestRunnerSpanTags (
|
|
|
397
438
|
testModuleSpan.setTag(TEST_ITR_FORCED_RUN, 'true')
|
|
398
439
|
}
|
|
399
440
|
|
|
400
|
-
//
|
|
401
|
-
|
|
441
|
+
// This will not be reported unless the user has manually added code coverage.
|
|
442
|
+
// This is always the case for Mocha and Cucumber, but not for Jest.
|
|
443
|
+
if (testCodeCoverageLinesTotal !== undefined) {
|
|
402
444
|
testSessionSpan.setTag(TEST_CODE_COVERAGE_LINES_PCT, testCodeCoverageLinesTotal)
|
|
403
445
|
testModuleSpan.setTag(TEST_CODE_COVERAGE_LINES_PCT, testCodeCoverageLinesTotal)
|
|
404
446
|
}
|
|
@@ -520,3 +562,11 @@ function parseAnnotations (annotations) {
|
|
|
520
562
|
return tags
|
|
521
563
|
}, {})
|
|
522
564
|
}
|
|
565
|
+
|
|
566
|
+
function addEfdStringToTestName (testName, numAttempt) {
|
|
567
|
+
return `${EFD_STRING} (#${numAttempt}): ${testName}`
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
function removeEfdStringFromTestName (testName) {
|
|
571
|
+
return testName.replace(EFD_TEST_NAME_REGEX, '')
|
|
572
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const { URL } = require('url')
|
|
2
|
+
|
|
3
|
+
function filterSensitiveInfoFromRepository (repositoryUrl) {
|
|
4
|
+
if (!repositoryUrl) {
|
|
5
|
+
return ''
|
|
6
|
+
}
|
|
7
|
+
if (repositoryUrl.startsWith('git@')) {
|
|
8
|
+
return repositoryUrl
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Remove the username from ssh URLs
|
|
12
|
+
if (repositoryUrl.startsWith('ssh://')) {
|
|
13
|
+
const sshRegex = /^(ssh:\/\/)[^@/]*@/
|
|
14
|
+
return repositoryUrl.replace(sshRegex, '$1')
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const { protocol, host, pathname } = new URL(repositoryUrl)
|
|
19
|
+
|
|
20
|
+
return `${protocol}//${host}${pathname === '/' ? '' : pathname}`
|
|
21
|
+
} catch (e) {
|
|
22
|
+
return ''
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = { filterSensitiveInfoFromRepository }
|
|
@@ -13,7 +13,7 @@ const {
|
|
|
13
13
|
} = require('./tags')
|
|
14
14
|
|
|
15
15
|
const { normalizeRef } = require('./ci')
|
|
16
|
-
const {
|
|
16
|
+
const { filterSensitiveInfoFromRepository } = require('./url')
|
|
17
17
|
|
|
18
18
|
function removeEmptyValues (tags) {
|
|
19
19
|
return Object.keys(tags).reduce((filteredTags, tag) => {
|
|
@@ -27,23 +27,11 @@ function removeEmptyValues (tags) {
|
|
|
27
27
|
}, {})
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
if (repositoryUrl.startsWith('git@')) {
|
|
33
|
-
return repositoryUrl
|
|
34
|
-
}
|
|
35
|
-
const { protocol, hostname, pathname } = new URL(repositoryUrl)
|
|
36
|
-
|
|
37
|
-
return `${protocol}//${hostname}${pathname}`
|
|
38
|
-
} catch (e) {
|
|
39
|
-
return repositoryUrl
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// The regex is extracted from
|
|
30
|
+
// The regex is inspired by
|
|
44
31
|
// https://github.com/jonschlinkert/is-git-url/blob/396965ffabf2f46656c8af4c47bef1d69f09292e/index.js#L9C15-L9C87
|
|
32
|
+
// The `.git` suffix is optional in this version
|
|
45
33
|
function validateGitRepositoryUrl (repoUrl) {
|
|
46
|
-
return /(?:git|ssh|https?|git@[-\w.]+):(\/\/)?(.*?)(
|
|
34
|
+
return /(?:git|ssh|https?|git@[-\w.]+):(\/\/)?(.*?)(\/?|#[-\d\w._]+?)$/.test(repoUrl)
|
|
47
35
|
}
|
|
48
36
|
|
|
49
37
|
function validateGitCommitSha (gitCommitSha) {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const RateLimiter = require('./rate_limiter')
|
|
4
3
|
const Sampler = require('./sampler')
|
|
5
|
-
const ext = require('../../../ext')
|
|
6
4
|
const { setSamplingRules } = require('./startup-log')
|
|
5
|
+
const SamplingRule = require('./sampling_rule')
|
|
7
6
|
|
|
8
7
|
const {
|
|
9
8
|
SAMPLING_MECHANISM_DEFAULT,
|
|
@@ -16,14 +15,21 @@ const {
|
|
|
16
15
|
DECISION_MAKER_KEY
|
|
17
16
|
} = require('./constants')
|
|
18
17
|
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
const {
|
|
19
|
+
tags: {
|
|
20
|
+
MANUAL_KEEP,
|
|
21
|
+
MANUAL_DROP,
|
|
22
|
+
SAMPLING_PRIORITY,
|
|
23
|
+
SERVICE_NAME
|
|
24
|
+
},
|
|
25
|
+
priority: {
|
|
26
|
+
AUTO_REJECT,
|
|
27
|
+
AUTO_KEEP,
|
|
28
|
+
USER_REJECT,
|
|
29
|
+
USER_KEEP
|
|
30
|
+
}
|
|
31
|
+
} = require('../../../ext')
|
|
32
|
+
|
|
27
33
|
const DEFAULT_KEY = 'service:,env:'
|
|
28
34
|
|
|
29
35
|
const defaultSampler = new Sampler(AUTO_KEEP)
|
|
@@ -36,8 +42,7 @@ class PrioritySampler {
|
|
|
36
42
|
|
|
37
43
|
configure (env, { sampleRate, rateLimit = 100, rules = [] } = {}) {
|
|
38
44
|
this._env = env
|
|
39
|
-
this._rules = this._normalizeRules(rules, sampleRate)
|
|
40
|
-
this._limiter = new RateLimiter(rateLimit)
|
|
45
|
+
this._rules = this._normalizeRules(rules, sampleRate, rateLimit)
|
|
41
46
|
|
|
42
47
|
setSamplingRules(this._rules)
|
|
43
48
|
}
|
|
@@ -104,7 +109,7 @@ class PrioritySampler {
|
|
|
104
109
|
|
|
105
110
|
_getPriorityFromAuto (span) {
|
|
106
111
|
const context = this._getContext(span)
|
|
107
|
-
const rule = this._findRule(
|
|
112
|
+
const rule = this._findRule(span)
|
|
108
113
|
|
|
109
114
|
return rule
|
|
110
115
|
? this._getPriorityByRule(context, rule)
|
|
@@ -131,15 +136,14 @@ class PrioritySampler {
|
|
|
131
136
|
context._trace[SAMPLING_RULE_DECISION] = rule.sampleRate
|
|
132
137
|
context._sampling.mechanism = SAMPLING_MECHANISM_RULE
|
|
133
138
|
|
|
134
|
-
|
|
135
|
-
|
|
139
|
+
const sampled = rule.sample()
|
|
140
|
+
const priority = sampled ? USER_KEEP : USER_REJECT
|
|
136
141
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
context._trace[SAMPLING_LIMIT_DECISION] = this._limiter.effectiveRate()
|
|
142
|
+
if (sampled) {
|
|
143
|
+
context._trace[SAMPLING_LIMIT_DECISION] = rule.effectiveRate
|
|
144
|
+
}
|
|
141
145
|
|
|
142
|
-
return
|
|
146
|
+
return priority
|
|
143
147
|
}
|
|
144
148
|
|
|
145
149
|
_getPriorityByAgent (context) {
|
|
@@ -172,33 +176,21 @@ class PrioritySampler {
|
|
|
172
176
|
}
|
|
173
177
|
}
|
|
174
178
|
|
|
175
|
-
_normalizeRules (rules, sampleRate) {
|
|
179
|
+
_normalizeRules (rules, sampleRate, rateLimit) {
|
|
176
180
|
rules = [].concat(rules || [])
|
|
177
181
|
|
|
178
182
|
return rules
|
|
179
|
-
.concat({ sampleRate })
|
|
183
|
+
.concat({ sampleRate, maxPerSecond: rateLimit })
|
|
180
184
|
.map(rule => ({ ...rule, sampleRate: parseFloat(rule.sampleRate) }))
|
|
181
185
|
.filter(rule => !isNaN(rule.sampleRate))
|
|
182
|
-
.map(
|
|
186
|
+
.map(SamplingRule.from)
|
|
183
187
|
}
|
|
184
188
|
|
|
185
|
-
_findRule (
|
|
186
|
-
for (
|
|
187
|
-
if (
|
|
189
|
+
_findRule (span) {
|
|
190
|
+
for (const rule of this._rules) {
|
|
191
|
+
if (rule.match(span)) return rule
|
|
188
192
|
}
|
|
189
193
|
}
|
|
190
|
-
|
|
191
|
-
_matchRule (context, rule) {
|
|
192
|
-
const name = context._name
|
|
193
|
-
const service = context._tags['service.name']
|
|
194
|
-
|
|
195
|
-
if (rule.name instanceof RegExp && !rule.name.test(name)) return false
|
|
196
|
-
if (typeof rule.name === 'string' && rule.name !== name) return false
|
|
197
|
-
if (rule.service instanceof RegExp && !rule.service.test(service)) return false
|
|
198
|
-
if (typeof rule.service === 'string' && rule.service !== service) return false
|
|
199
|
-
|
|
200
|
-
return true
|
|
201
|
-
}
|
|
202
194
|
}
|
|
203
195
|
|
|
204
196
|
function hasOwn (object, prop) {
|
|
@@ -8,7 +8,7 @@ process.once('beforeExit', () => { profiler.stop() })
|
|
|
8
8
|
|
|
9
9
|
module.exports = {
|
|
10
10
|
start: config => {
|
|
11
|
-
const { service, version, env, url, hostname, port, tags } = config
|
|
11
|
+
const { service, version, env, url, hostname, port, tags, repositoryUrl, commitSHA } = config
|
|
12
12
|
const { enabled, sourceMap, exporters } = config.profiling
|
|
13
13
|
const logger = {
|
|
14
14
|
debug: (message) => log.debug(message),
|
|
@@ -17,7 +17,7 @@ module.exports = {
|
|
|
17
17
|
error: (message) => log.error(message)
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
profiler.start({
|
|
20
|
+
return profiler.start({
|
|
21
21
|
enabled,
|
|
22
22
|
service,
|
|
23
23
|
version,
|
|
@@ -28,7 +28,9 @@ module.exports = {
|
|
|
28
28
|
url,
|
|
29
29
|
hostname,
|
|
30
30
|
port,
|
|
31
|
-
tags
|
|
31
|
+
tags,
|
|
32
|
+
repositoryUrl,
|
|
33
|
+
commitSHA
|
|
32
34
|
})
|
|
33
35
|
},
|
|
34
36
|
|
|
@@ -9,38 +9,43 @@ const { FileExporter } = require('./exporters/file')
|
|
|
9
9
|
const { ConsoleLogger } = require('./loggers/console')
|
|
10
10
|
const WallProfiler = require('./profilers/wall')
|
|
11
11
|
const SpaceProfiler = require('./profilers/space')
|
|
12
|
+
const EventsProfiler = require('./profilers/events')
|
|
12
13
|
const { oomExportStrategies, snapshotKinds } = require('./constants')
|
|
14
|
+
const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../plugins/util/tags')
|
|
13
15
|
const { tagger } = require('./tagger')
|
|
14
16
|
const { isFalse, isTrue } = require('../util')
|
|
15
17
|
|
|
16
18
|
class Config {
|
|
17
19
|
constructor (options = {}) {
|
|
18
20
|
const {
|
|
19
|
-
DD_PROFILING_ENABLED,
|
|
20
|
-
DD_PROFILING_PROFILERS,
|
|
21
|
-
DD_ENV,
|
|
22
|
-
DD_TAGS,
|
|
23
|
-
DD_SERVICE,
|
|
24
|
-
DD_VERSION,
|
|
25
|
-
DD_TRACE_AGENT_URL,
|
|
26
21
|
DD_AGENT_HOST,
|
|
27
|
-
|
|
22
|
+
DD_ENV,
|
|
23
|
+
DD_PROFILING_CODEHOTSPOTS_ENABLED,
|
|
28
24
|
DD_PROFILING_DEBUG_SOURCE_MAPS,
|
|
29
|
-
|
|
25
|
+
DD_PROFILING_ENABLED,
|
|
26
|
+
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,
|
|
27
|
+
DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED,
|
|
28
|
+
DD_PROFILING_EXPERIMENTAL_CPU_ENABLED,
|
|
29
|
+
DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED,
|
|
30
|
+
DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES,
|
|
31
|
+
DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE,
|
|
32
|
+
DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT,
|
|
33
|
+
DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED,
|
|
34
|
+
DD_PROFILING_EXPERIMENTAL_TIMELINE_ENABLED,
|
|
35
|
+
DD_PROFILING_HEAP_ENABLED,
|
|
36
|
+
DD_PROFILING_PPROF_PREFIX,
|
|
37
|
+
DD_PROFILING_PROFILERS,
|
|
30
38
|
DD_PROFILING_SOURCE_MAP,
|
|
39
|
+
DD_PROFILING_TIMELINE_ENABLED,
|
|
31
40
|
DD_PROFILING_UPLOAD_PERIOD,
|
|
32
|
-
|
|
33
|
-
DD_PROFILING_HEAP_ENABLED,
|
|
41
|
+
DD_PROFILING_UPLOAD_TIMEOUT,
|
|
34
42
|
DD_PROFILING_V8_PROFILER_BUG_WORKAROUND,
|
|
35
43
|
DD_PROFILING_WALLTIME_ENABLED,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,
|
|
42
|
-
DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED,
|
|
43
|
-
DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED
|
|
44
|
+
DD_SERVICE,
|
|
45
|
+
DD_TAGS,
|
|
46
|
+
DD_TRACE_AGENT_PORT,
|
|
47
|
+
DD_TRACE_AGENT_URL,
|
|
48
|
+
DD_VERSION
|
|
44
49
|
} = process.env
|
|
45
50
|
|
|
46
51
|
const enabled = isTrue(coalesce(options.enabled, DD_PROFILING_ENABLED, true))
|
|
@@ -70,6 +75,13 @@ class Config {
|
|
|
70
75
|
tagger.parse(options.tags),
|
|
71
76
|
tagger.parse({ env, host, service, version, functionname })
|
|
72
77
|
)
|
|
78
|
+
|
|
79
|
+
// Add source code integration tags if available
|
|
80
|
+
if (options.repositoryUrl && options.commitSHA) {
|
|
81
|
+
this.tags[GIT_REPOSITORY_URL] = options.repositoryUrl
|
|
82
|
+
this.tags[GIT_COMMIT_SHA] = options.commitSHA
|
|
83
|
+
}
|
|
84
|
+
|
|
73
85
|
this.logger = ensureLogger(options.logger)
|
|
74
86
|
const logger = this.logger
|
|
75
87
|
function logExperimentalVarDeprecation (shortVarName) {
|
|
@@ -81,14 +93,28 @@ class Config {
|
|
|
81
93
|
logger.warn(`${deprecatedEnvVarName} is deprecated. Use DD_PROFILING_${shortVarName} instead.`)
|
|
82
94
|
}
|
|
83
95
|
}
|
|
96
|
+
// Profiler sampling contexts are not available on Windows, so features
|
|
97
|
+
// depending on those (code hotspots and endpoint collection) need to default
|
|
98
|
+
// to false on Windows.
|
|
99
|
+
const samplingContextsAvailable = process.platform !== 'win32'
|
|
100
|
+
function checkOptionAllowed (option, description, condition) {
|
|
101
|
+
if (option && !condition) {
|
|
102
|
+
throw new Error(`${description} not supported on ${process.platform}.`)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function checkOptionWithSamplingContextAllowed (option, description) {
|
|
106
|
+
checkOptionAllowed(option, description, samplingContextsAvailable)
|
|
107
|
+
}
|
|
108
|
+
|
|
84
109
|
this.flushInterval = flushInterval
|
|
85
110
|
this.uploadTimeout = uploadTimeout
|
|
86
111
|
this.sourceMap = sourceMap
|
|
87
112
|
this.debugSourceMaps = isTrue(coalesce(options.debugSourceMaps, DD_PROFILING_DEBUG_SOURCE_MAPS, false))
|
|
88
113
|
this.endpointCollectionEnabled = isTrue(coalesce(options.endpointCollection,
|
|
89
114
|
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,
|
|
90
|
-
DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED,
|
|
115
|
+
DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED, samplingContextsAvailable))
|
|
91
116
|
logExperimentalVarDeprecation('ENDPOINT_COLLECTION_ENABLED')
|
|
117
|
+
checkOptionWithSamplingContextAllowed(this.endpointCollectionEnabled, 'Endpoint collection')
|
|
92
118
|
|
|
93
119
|
this.pprofPrefix = pprofPrefix
|
|
94
120
|
this.v8ProfilerBugWorkaroundEnabled = isTrue(coalesce(options.v8ProfilerBugWorkaround,
|
|
@@ -105,8 +131,13 @@ class Config {
|
|
|
105
131
|
new AgentExporter(this)
|
|
106
132
|
], this)
|
|
107
133
|
|
|
134
|
+
// OOM monitoring does not work well on Windows, so it is disabled by default.
|
|
135
|
+
const oomMonitoringSupported = process.platform !== 'win32'
|
|
136
|
+
|
|
108
137
|
const oomMonitoringEnabled = isTrue(coalesce(options.oomMonitoring,
|
|
109
|
-
DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED,
|
|
138
|
+
DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED, oomMonitoringSupported))
|
|
139
|
+
checkOptionAllowed(oomMonitoringEnabled, 'OOM monitoring', oomMonitoringSupported)
|
|
140
|
+
|
|
110
141
|
const heapLimitExtensionSize = coalesce(options.oomHeapLimitExtensionSize,
|
|
111
142
|
Number(DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE), 0)
|
|
112
143
|
const maxHeapExtensionCount = coalesce(options.oomMaxHeapExtensionCount,
|
|
@@ -126,12 +157,27 @@ class Config {
|
|
|
126
157
|
|
|
127
158
|
const profilers = options.profilers
|
|
128
159
|
? options.profilers
|
|
129
|
-
: getProfilers({
|
|
160
|
+
: getProfilers({
|
|
161
|
+
DD_PROFILING_HEAP_ENABLED,
|
|
162
|
+
DD_PROFILING_WALLTIME_ENABLED,
|
|
163
|
+
DD_PROFILING_PROFILERS
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
this.timelineEnabled = isTrue(coalesce(options.timelineEnabled,
|
|
167
|
+
DD_PROFILING_TIMELINE_ENABLED,
|
|
168
|
+
DD_PROFILING_EXPERIMENTAL_TIMELINE_ENABLED, false))
|
|
169
|
+
logExperimentalVarDeprecation('TIMELINE_ENABLED')
|
|
170
|
+
checkOptionWithSamplingContextAllowed(this.timelineEnabled, 'Timeline view')
|
|
130
171
|
|
|
131
172
|
this.codeHotspotsEnabled = isTrue(coalesce(options.codeHotspotsEnabled,
|
|
132
173
|
DD_PROFILING_CODEHOTSPOTS_ENABLED,
|
|
133
|
-
DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED,
|
|
174
|
+
DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED, samplingContextsAvailable))
|
|
134
175
|
logExperimentalVarDeprecation('CODEHOTSPOTS_ENABLED')
|
|
176
|
+
checkOptionWithSamplingContextAllowed(this.codeHotspotsEnabled, 'Code hotspots')
|
|
177
|
+
|
|
178
|
+
this.cpuProfilingEnabled = isTrue(coalesce(options.cpuProfilingEnabled,
|
|
179
|
+
DD_PROFILING_EXPERIMENTAL_CPU_ENABLED, false))
|
|
180
|
+
checkOptionWithSamplingContextAllowed(this.cpuProfilingEnabled, 'CPU profiling')
|
|
135
181
|
|
|
136
182
|
this.profilers = ensureProfilers(profilers, this)
|
|
137
183
|
}
|
|
@@ -139,7 +185,9 @@ class Config {
|
|
|
139
185
|
|
|
140
186
|
module.exports = { Config }
|
|
141
187
|
|
|
142
|
-
function getProfilers ({
|
|
188
|
+
function getProfilers ({
|
|
189
|
+
DD_PROFILING_HEAP_ENABLED, DD_PROFILING_WALLTIME_ENABLED, DD_PROFILING_PROFILERS
|
|
190
|
+
}) {
|
|
143
191
|
// First consider "legacy" DD_PROFILING_PROFILERS env variable, defaulting to wall + space
|
|
144
192
|
// Use a Set to avoid duplicates
|
|
145
193
|
const profilers = new Set(coalesce(DD_PROFILING_PROFILERS, 'wall,space').split(','))
|
|
@@ -240,6 +288,11 @@ function ensureProfilers (profilers, options) {
|
|
|
240
288
|
}
|
|
241
289
|
}
|
|
242
290
|
|
|
291
|
+
// Events profiler is a profiler for timeline events
|
|
292
|
+
if (options.timelineEnabled) {
|
|
293
|
+
profilers.push(new EventsProfiler(options))
|
|
294
|
+
}
|
|
295
|
+
|
|
243
296
|
// Filter out any invalid profilers
|
|
244
297
|
return profilers.filter(v => v)
|
|
245
298
|
}
|