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
|
@@ -13,9 +13,26 @@ const {
|
|
|
13
13
|
addIntelligentTestRunnerSpanTags,
|
|
14
14
|
TEST_SOURCE_START,
|
|
15
15
|
TEST_ITR_UNSKIPPABLE,
|
|
16
|
-
TEST_ITR_FORCED_RUN
|
|
16
|
+
TEST_ITR_FORCED_RUN,
|
|
17
|
+
TEST_CODE_OWNERS,
|
|
18
|
+
ITR_CORRELATION_ID,
|
|
19
|
+
TEST_SOURCE_FILE,
|
|
20
|
+
removeEfdStringFromTestName,
|
|
21
|
+
TEST_IS_NEW,
|
|
22
|
+
TEST_EARLY_FLAKE_IS_RETRY,
|
|
23
|
+
TEST_EARLY_FLAKE_IS_ENABLED
|
|
17
24
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
18
25
|
const { COMPONENT } = require('../../dd-trace/src/constants')
|
|
26
|
+
const {
|
|
27
|
+
TELEMETRY_EVENT_CREATED,
|
|
28
|
+
TELEMETRY_EVENT_FINISHED,
|
|
29
|
+
TELEMETRY_CODE_COVERAGE_STARTED,
|
|
30
|
+
TELEMETRY_CODE_COVERAGE_FINISHED,
|
|
31
|
+
TELEMETRY_ITR_FORCED_TO_RUN,
|
|
32
|
+
TELEMETRY_CODE_COVERAGE_EMPTY,
|
|
33
|
+
TELEMETRY_ITR_UNSKIPPABLE,
|
|
34
|
+
TELEMETRY_CODE_COVERAGE_NUM_FILES
|
|
35
|
+
} = require('../../dd-trace/src/ci-visibility/telemetry')
|
|
19
36
|
|
|
20
37
|
class MochaPlugin extends CiPlugin {
|
|
21
38
|
static get id () {
|
|
@@ -26,15 +43,19 @@ class MochaPlugin extends CiPlugin {
|
|
|
26
43
|
super(...args)
|
|
27
44
|
|
|
28
45
|
this._testSuites = new Map()
|
|
29
|
-
this.
|
|
46
|
+
this._testTitleToParams = {}
|
|
30
47
|
this.sourceRoot = process.cwd()
|
|
31
48
|
|
|
32
49
|
this.addSub('ci:mocha:test-suite:code-coverage', ({ coverageFiles, suiteFile }) => {
|
|
33
|
-
if (!this.
|
|
50
|
+
if (!this.libraryConfig?.isCodeCoverageEnabled) {
|
|
34
51
|
return
|
|
35
52
|
}
|
|
36
53
|
const testSuiteSpan = this._testSuites.get(suiteFile)
|
|
37
54
|
|
|
55
|
+
if (!coverageFiles.length) {
|
|
56
|
+
this.telemetry.count(TELEMETRY_CODE_COVERAGE_EMPTY)
|
|
57
|
+
}
|
|
58
|
+
|
|
38
59
|
const relativeCoverageFiles = [...coverageFiles, suiteFile]
|
|
39
60
|
.map(filename => getTestSuitePath(filename, this.sourceRoot))
|
|
40
61
|
|
|
@@ -47,9 +68,16 @@ class MochaPlugin extends CiPlugin {
|
|
|
47
68
|
}
|
|
48
69
|
|
|
49
70
|
this.tracer._exporter.exportCoverage(formattedCoverage)
|
|
71
|
+
this.telemetry.ciVisEvent(TELEMETRY_CODE_COVERAGE_FINISHED, 'suite', { library: 'istanbul' })
|
|
72
|
+
this.telemetry.distribution(TELEMETRY_CODE_COVERAGE_NUM_FILES, {}, relativeCoverageFiles.length)
|
|
50
73
|
})
|
|
51
74
|
|
|
52
|
-
this.addSub('ci:mocha:test-suite:start', ({
|
|
75
|
+
this.addSub('ci:mocha:test-suite:start', ({
|
|
76
|
+
testSuite,
|
|
77
|
+
isUnskippable,
|
|
78
|
+
isForcedToRun,
|
|
79
|
+
itrCorrelationId
|
|
80
|
+
}) => {
|
|
53
81
|
const store = storage.getStore()
|
|
54
82
|
const testSuiteMetadata = getTestSuiteCommonTags(
|
|
55
83
|
this.command,
|
|
@@ -59,9 +87,11 @@ class MochaPlugin extends CiPlugin {
|
|
|
59
87
|
)
|
|
60
88
|
if (isUnskippable) {
|
|
61
89
|
testSuiteMetadata[TEST_ITR_UNSKIPPABLE] = 'true'
|
|
90
|
+
this.telemetry.count(TELEMETRY_ITR_UNSKIPPABLE, { testLevel: 'suite' })
|
|
62
91
|
}
|
|
63
92
|
if (isForcedToRun) {
|
|
64
93
|
testSuiteMetadata[TEST_ITR_FORCED_RUN] = 'true'
|
|
94
|
+
this.telemetry.count(TELEMETRY_ITR_FORCED_TO_RUN, { testLevel: 'suite' })
|
|
65
95
|
}
|
|
66
96
|
|
|
67
97
|
const testSuiteSpan = this.tracer.startSpan('mocha.test_suite', {
|
|
@@ -72,6 +102,13 @@ class MochaPlugin extends CiPlugin {
|
|
|
72
102
|
...testSuiteMetadata
|
|
73
103
|
}
|
|
74
104
|
})
|
|
105
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'suite')
|
|
106
|
+
if (this.libraryConfig?.isCodeCoverageEnabled) {
|
|
107
|
+
this.telemetry.ciVisEvent(TELEMETRY_CODE_COVERAGE_STARTED, 'suite', { library: 'istanbul' })
|
|
108
|
+
}
|
|
109
|
+
if (itrCorrelationId) {
|
|
110
|
+
testSuiteSpan.setTag(ITR_CORRELATION_ID, itrCorrelationId)
|
|
111
|
+
}
|
|
75
112
|
this.enter(testSuiteSpan, store)
|
|
76
113
|
this._testSuites.set(testSuite, testSuiteSpan)
|
|
77
114
|
})
|
|
@@ -85,6 +122,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
85
122
|
span.setTag(TEST_STATUS, status)
|
|
86
123
|
}
|
|
87
124
|
span.finish()
|
|
125
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
|
|
88
126
|
}
|
|
89
127
|
})
|
|
90
128
|
|
|
@@ -97,9 +135,9 @@ class MochaPlugin extends CiPlugin {
|
|
|
97
135
|
}
|
|
98
136
|
})
|
|
99
137
|
|
|
100
|
-
this.addSub('ci:mocha:test:start', (
|
|
138
|
+
this.addSub('ci:mocha:test:start', (testInfo) => {
|
|
101
139
|
const store = storage.getStore()
|
|
102
|
-
const span = this.startTestSpan(
|
|
140
|
+
const span = this.startTestSpan(testInfo)
|
|
103
141
|
|
|
104
142
|
this.enter(span, store)
|
|
105
143
|
})
|
|
@@ -113,16 +151,21 @@ class MochaPlugin extends CiPlugin {
|
|
|
113
151
|
span.setTag(TEST_STATUS, status)
|
|
114
152
|
|
|
115
153
|
span.finish()
|
|
154
|
+
this.telemetry.ciVisEvent(
|
|
155
|
+
TELEMETRY_EVENT_FINISHED,
|
|
156
|
+
'test',
|
|
157
|
+
{ hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
|
|
158
|
+
)
|
|
116
159
|
finishAllTraceSpans(span)
|
|
117
160
|
}
|
|
118
161
|
})
|
|
119
162
|
|
|
120
|
-
this.addSub('ci:mocha:test:skip', (
|
|
163
|
+
this.addSub('ci:mocha:test:skip', (testInfo) => {
|
|
121
164
|
const store = storage.getStore()
|
|
122
165
|
// skipped through it.skip, so the span is not created yet
|
|
123
166
|
// for this test
|
|
124
167
|
if (!store) {
|
|
125
|
-
const testSpan = this.startTestSpan(
|
|
168
|
+
const testSpan = this.startTestSpan(testInfo)
|
|
126
169
|
this.enter(testSpan, store)
|
|
127
170
|
}
|
|
128
171
|
})
|
|
@@ -140,8 +183,8 @@ class MochaPlugin extends CiPlugin {
|
|
|
140
183
|
}
|
|
141
184
|
})
|
|
142
185
|
|
|
143
|
-
this.addSub('ci:mocha:test:parameterize', ({
|
|
144
|
-
this.
|
|
186
|
+
this.addSub('ci:mocha:test:parameterize', ({ title, params }) => {
|
|
187
|
+
this._testTitleToParams[title] = params
|
|
145
188
|
})
|
|
146
189
|
|
|
147
190
|
this.addSub('ci:mocha:session:finish', ({
|
|
@@ -151,10 +194,11 @@ class MochaPlugin extends CiPlugin {
|
|
|
151
194
|
numSkippedSuites,
|
|
152
195
|
hasForcedToRunSuites,
|
|
153
196
|
hasUnskippableSuites,
|
|
154
|
-
error
|
|
197
|
+
error,
|
|
198
|
+
isEarlyFlakeDetectionEnabled
|
|
155
199
|
}) => {
|
|
156
200
|
if (this.testSessionSpan) {
|
|
157
|
-
const { isSuitesSkippingEnabled, isCodeCoverageEnabled } = this.
|
|
201
|
+
const { isSuitesSkippingEnabled, isCodeCoverageEnabled } = this.libraryConfig || {}
|
|
158
202
|
this.testSessionSpan.setTag(TEST_STATUS, status)
|
|
159
203
|
this.testModuleSpan.setTag(TEST_STATUS, status)
|
|
160
204
|
|
|
@@ -178,21 +222,34 @@ class MochaPlugin extends CiPlugin {
|
|
|
178
222
|
}
|
|
179
223
|
)
|
|
180
224
|
|
|
225
|
+
if (isEarlyFlakeDetectionEnabled) {
|
|
226
|
+
this.testSessionSpan.setTag(TEST_EARLY_FLAKE_IS_ENABLED, 'true')
|
|
227
|
+
}
|
|
228
|
+
|
|
181
229
|
this.testModuleSpan.finish()
|
|
230
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
|
|
182
231
|
this.testSessionSpan.finish()
|
|
232
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
|
|
183
233
|
finishAllTraceSpans(this.testSessionSpan)
|
|
184
234
|
}
|
|
185
|
-
this.
|
|
235
|
+
this.libraryConfig = null
|
|
186
236
|
this.tracer._exporter.flush()
|
|
187
237
|
})
|
|
188
238
|
}
|
|
189
239
|
|
|
190
|
-
startTestSpan (
|
|
191
|
-
const
|
|
192
|
-
|
|
240
|
+
startTestSpan (testInfo) {
|
|
241
|
+
const {
|
|
242
|
+
testSuiteAbsolutePath,
|
|
243
|
+
title,
|
|
244
|
+
isNew,
|
|
245
|
+
isEfdRetry,
|
|
246
|
+
testStartLine
|
|
247
|
+
} = testInfo
|
|
248
|
+
|
|
249
|
+
const testName = removeEfdStringFromTestName(testInfo.testName)
|
|
193
250
|
|
|
194
251
|
const extraTags = {}
|
|
195
|
-
const testParametersString = getTestParametersString(this.
|
|
252
|
+
const testParametersString = getTestParametersString(this._testTitleToParams, title)
|
|
196
253
|
if (testParametersString) {
|
|
197
254
|
extraTags[TEST_PARAMETERS] = testParametersString
|
|
198
255
|
}
|
|
@@ -204,6 +261,19 @@ class MochaPlugin extends CiPlugin {
|
|
|
204
261
|
const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.sourceRoot)
|
|
205
262
|
const testSuiteSpan = this._testSuites.get(testSuiteAbsolutePath)
|
|
206
263
|
|
|
264
|
+
if (this.repositoryRoot !== this.sourceRoot && !!this.repositoryRoot) {
|
|
265
|
+
extraTags[TEST_SOURCE_FILE] = getTestSuitePath(testSuiteAbsolutePath, this.repositoryRoot)
|
|
266
|
+
} else {
|
|
267
|
+
extraTags[TEST_SOURCE_FILE] = testSuite
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (isNew) {
|
|
271
|
+
extraTags[TEST_IS_NEW] = 'true'
|
|
272
|
+
if (isEfdRetry) {
|
|
273
|
+
extraTags[TEST_EARLY_FLAKE_IS_RETRY] = 'true'
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
207
277
|
return super.startTestSpan(testName, testSuite, testSuiteSpan, extraTags)
|
|
208
278
|
}
|
|
209
279
|
}
|
|
@@ -6,6 +6,8 @@ const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
|
6
6
|
const { COMPONENT } = require('../../dd-trace/src/constants')
|
|
7
7
|
const web = require('../../dd-trace/src/plugins/util/web')
|
|
8
8
|
|
|
9
|
+
const errorPages = ['/404', '/500', '/_error', '/_not-found']
|
|
10
|
+
|
|
9
11
|
class NextPlugin extends ServerPlugin {
|
|
10
12
|
static get id () {
|
|
11
13
|
return 'next'
|
|
@@ -40,6 +42,13 @@ class NextPlugin extends ServerPlugin {
|
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
error ({ span, error }) {
|
|
45
|
+
if (!span) {
|
|
46
|
+
const store = storage.getStore()
|
|
47
|
+
if (!store) return
|
|
48
|
+
|
|
49
|
+
span = store.span
|
|
50
|
+
}
|
|
51
|
+
|
|
43
52
|
this.addError(error, span)
|
|
44
53
|
}
|
|
45
54
|
|
|
@@ -50,10 +59,20 @@ class NextPlugin extends ServerPlugin {
|
|
|
50
59
|
|
|
51
60
|
const span = store.span
|
|
52
61
|
const error = span.context()._tags['error']
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
const requestError = req.error || nextRequest.error
|
|
63
|
+
|
|
64
|
+
if (requestError) {
|
|
65
|
+
// prioritize user-set errors from API routes
|
|
66
|
+
span.setTag('error', requestError)
|
|
67
|
+
web.addError(req, requestError)
|
|
68
|
+
} else if (error) {
|
|
69
|
+
// general error handling
|
|
70
|
+
span.setTag('error', error)
|
|
71
|
+
web.addError(req, requestError || error)
|
|
72
|
+
} else if (!this.config.validateStatus(res.statusCode)) {
|
|
73
|
+
// where there's no error, we still need to validate status
|
|
74
|
+
span.setTag('error', true)
|
|
75
|
+
web.addError(req, true)
|
|
57
76
|
}
|
|
58
77
|
|
|
59
78
|
span.addTags({
|
|
@@ -65,7 +84,7 @@ class NextPlugin extends ServerPlugin {
|
|
|
65
84
|
span.finish()
|
|
66
85
|
}
|
|
67
86
|
|
|
68
|
-
pageLoad ({ page, isAppPath = false }) {
|
|
87
|
+
pageLoad ({ page, isAppPath = false, isStatic = false }) {
|
|
69
88
|
const store = storage.getStore()
|
|
70
89
|
|
|
71
90
|
if (!store) return
|
|
@@ -73,21 +92,28 @@ class NextPlugin extends ServerPlugin {
|
|
|
73
92
|
const span = store.span
|
|
74
93
|
const req = this._requests.get(span)
|
|
75
94
|
|
|
95
|
+
// safeguard against missing req in complicated timeout scenarios
|
|
96
|
+
if (!req) return
|
|
97
|
+
|
|
76
98
|
// Only use error page names if there's not already a name
|
|
77
99
|
const current = span.context()._tags['next.page']
|
|
78
|
-
|
|
100
|
+
const isErrorPage = errorPages.includes(page)
|
|
101
|
+
|
|
102
|
+
if (current && isErrorPage) {
|
|
79
103
|
return
|
|
80
104
|
}
|
|
81
105
|
|
|
82
106
|
// remove ending /route or /page for appDir projects
|
|
83
|
-
if
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
107
|
+
// need to check if not an error page too, as those are marked as app directory
|
|
108
|
+
// in newer versions
|
|
109
|
+
if (isAppPath && !isErrorPage) page = page.substring(0, page.lastIndexOf('/'))
|
|
110
|
+
|
|
111
|
+
// handle static resource
|
|
112
|
+
if (isStatic) {
|
|
113
|
+
page = req.url.includes('_next/static')
|
|
114
|
+
? '/_next/static/*'
|
|
115
|
+
: '/public/*'
|
|
116
|
+
}
|
|
91
117
|
|
|
92
118
|
span.addTags({
|
|
93
119
|
[COMPONENT]: this.constructor.id,
|
|
@@ -8,10 +8,18 @@ const {
|
|
|
8
8
|
finishAllTraceSpans,
|
|
9
9
|
getTestSuitePath,
|
|
10
10
|
getTestSuiteCommonTags,
|
|
11
|
-
TEST_SOURCE_START
|
|
11
|
+
TEST_SOURCE_START,
|
|
12
|
+
TEST_CODE_OWNERS,
|
|
13
|
+
TEST_SOURCE_FILE,
|
|
14
|
+
TEST_CONFIGURATION_BROWSER_NAME
|
|
12
15
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
13
16
|
const { RESOURCE_NAME } = require('../../../ext/tags')
|
|
14
17
|
const { COMPONENT } = require('../../dd-trace/src/constants')
|
|
18
|
+
const {
|
|
19
|
+
TELEMETRY_EVENT_CREATED,
|
|
20
|
+
TELEMETRY_EVENT_FINISHED
|
|
21
|
+
} = require('../../dd-trace/src/ci-visibility/telemetry')
|
|
22
|
+
const { appClosing: appClosingTelemetry } = require('../../dd-trace/src/telemetry')
|
|
15
23
|
|
|
16
24
|
class PlaywrightPlugin extends CiPlugin {
|
|
17
25
|
static get id () {
|
|
@@ -22,15 +30,31 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
22
30
|
super(...args)
|
|
23
31
|
|
|
24
32
|
this._testSuites = new Map()
|
|
33
|
+
this.numFailedTests = 0
|
|
34
|
+
this.numFailedSuites = 0
|
|
25
35
|
|
|
26
36
|
this.addSub('ci:playwright:session:finish', ({ status, onDone }) => {
|
|
27
37
|
this.testModuleSpan.setTag(TEST_STATUS, status)
|
|
28
38
|
this.testSessionSpan.setTag(TEST_STATUS, status)
|
|
29
39
|
|
|
40
|
+
if (this.numFailedSuites > 0) {
|
|
41
|
+
let errorMessage = `Test suites failed: ${this.numFailedSuites}.`
|
|
42
|
+
if (this.numFailedTests > 0) {
|
|
43
|
+
errorMessage += ` Tests failed: ${this.numFailedTests}`
|
|
44
|
+
}
|
|
45
|
+
const error = new Error(errorMessage)
|
|
46
|
+
this.testModuleSpan.setTag('error', error)
|
|
47
|
+
this.testSessionSpan.setTag('error', error)
|
|
48
|
+
}
|
|
49
|
+
|
|
30
50
|
this.testModuleSpan.finish()
|
|
51
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
|
|
31
52
|
this.testSessionSpan.finish()
|
|
53
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
|
|
32
54
|
finishAllTraceSpans(this.testSessionSpan)
|
|
55
|
+
appClosingTelemetry()
|
|
33
56
|
this.tracer._exporter.flush(onDone)
|
|
57
|
+
this.numFailedTests = 0
|
|
34
58
|
})
|
|
35
59
|
|
|
36
60
|
this.addSub('ci:playwright:test-suite:start', (testSuiteAbsolutePath) => {
|
|
@@ -52,23 +76,36 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
52
76
|
...testSuiteMetadata
|
|
53
77
|
}
|
|
54
78
|
})
|
|
79
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'suite')
|
|
55
80
|
this.enter(testSuiteSpan, store)
|
|
56
81
|
|
|
57
82
|
this._testSuites.set(testSuite, testSuiteSpan)
|
|
58
83
|
})
|
|
59
84
|
|
|
60
|
-
this.addSub('ci:playwright:test-suite:finish', (status) => {
|
|
85
|
+
this.addSub('ci:playwright:test-suite:finish', ({ status, error }) => {
|
|
61
86
|
const store = storage.getStore()
|
|
62
87
|
const span = store && store.span
|
|
63
88
|
if (!span) return
|
|
64
|
-
|
|
89
|
+
if (error) {
|
|
90
|
+
span.setTag('error', error)
|
|
91
|
+
span.setTag(TEST_STATUS, 'fail')
|
|
92
|
+
} else {
|
|
93
|
+
span.setTag(TEST_STATUS, status)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (status === 'fail' || error) {
|
|
97
|
+
this.numFailedSuites++
|
|
98
|
+
}
|
|
99
|
+
|
|
65
100
|
span.finish()
|
|
101
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
|
|
66
102
|
})
|
|
67
103
|
|
|
68
|
-
this.addSub('ci:playwright:test:start', ({ testName, testSuiteAbsolutePath, testSourceLine }) => {
|
|
104
|
+
this.addSub('ci:playwright:test:start', ({ testName, testSuiteAbsolutePath, testSourceLine, browserName }) => {
|
|
69
105
|
const store = storage.getStore()
|
|
70
106
|
const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.rootDir)
|
|
71
|
-
const
|
|
107
|
+
const testSourceFile = getTestSuitePath(testSuiteAbsolutePath, this.repositoryRoot)
|
|
108
|
+
const span = this.startTestSpan(testName, testSuite, testSourceFile, testSourceLine, browserName)
|
|
72
109
|
|
|
73
110
|
this.enter(span, store)
|
|
74
111
|
})
|
|
@@ -100,17 +137,43 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
100
137
|
if (step.error) {
|
|
101
138
|
stepSpan.setTag('error', step.error)
|
|
102
139
|
}
|
|
103
|
-
|
|
140
|
+
let stepDuration = step.duration
|
|
141
|
+
if (stepDuration <= 0 || isNaN(stepDuration)) {
|
|
142
|
+
stepDuration = 0
|
|
143
|
+
}
|
|
144
|
+
stepSpan.finish(stepStartTime + stepDuration)
|
|
104
145
|
})
|
|
105
146
|
|
|
106
147
|
span.finish()
|
|
148
|
+
|
|
149
|
+
if (testStatus === 'fail') {
|
|
150
|
+
this.numFailedTests++
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
this.telemetry.ciVisEvent(
|
|
154
|
+
TELEMETRY_EVENT_FINISHED,
|
|
155
|
+
'test',
|
|
156
|
+
{ hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
|
|
157
|
+
)
|
|
158
|
+
|
|
107
159
|
finishAllTraceSpans(span)
|
|
108
160
|
})
|
|
109
161
|
}
|
|
110
162
|
|
|
111
|
-
startTestSpan (testName, testSuite, testSourceLine) {
|
|
163
|
+
startTestSpan (testName, testSuite, testSourceFile, testSourceLine, browserName) {
|
|
112
164
|
const testSuiteSpan = this._testSuites.get(testSuite)
|
|
113
|
-
|
|
165
|
+
|
|
166
|
+
const extraTags = {
|
|
167
|
+
[TEST_SOURCE_START]: testSourceLine
|
|
168
|
+
}
|
|
169
|
+
if (testSourceFile) {
|
|
170
|
+
extraTags[TEST_SOURCE_FILE] = testSourceFile || testSuite
|
|
171
|
+
}
|
|
172
|
+
if (browserName) {
|
|
173
|
+
extraTags[TEST_CONFIGURATION_BROWSER_NAME] = browserName
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return super.startTestSpan(testName, testSuite, testSuiteSpan, extraTags)
|
|
114
177
|
}
|
|
115
178
|
}
|
|
116
179
|
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
|
|
4
4
|
const { storage } = require('../../datadog-core')
|
|
5
|
+
const { getAmqpMessageSize } = require('../../dd-trace/src/datastreams/processor')
|
|
6
|
+
const { DsmPathwayCodec } = require('../../dd-trace/src/datastreams/pathway')
|
|
5
7
|
|
|
6
8
|
class RheaConsumerPlugin extends ConsumerPlugin {
|
|
7
9
|
static get id () { return 'rhea' }
|
|
@@ -19,7 +21,7 @@ class RheaConsumerPlugin extends ConsumerPlugin {
|
|
|
19
21
|
const name = getResourceNameFromMessage(msgObj)
|
|
20
22
|
const childOf = extractTextMap(msgObj, this.tracer)
|
|
21
23
|
|
|
22
|
-
this.startSpan({
|
|
24
|
+
const span = this.startSpan({
|
|
23
25
|
childOf,
|
|
24
26
|
resource: name,
|
|
25
27
|
type: 'worker',
|
|
@@ -29,6 +31,19 @@ class RheaConsumerPlugin extends ConsumerPlugin {
|
|
|
29
31
|
'amqp.link.role': 'receiver'
|
|
30
32
|
}
|
|
31
33
|
})
|
|
34
|
+
|
|
35
|
+
if (
|
|
36
|
+
this.config.dsmEnabled &&
|
|
37
|
+
msgObj?.message?.delivery_annotations &&
|
|
38
|
+
DsmPathwayCodec.contextExists(msgObj.message.delivery_annotations)
|
|
39
|
+
) {
|
|
40
|
+
const payloadSize = getAmqpMessageSize(
|
|
41
|
+
{ headers: msgObj.message.delivery_annotations, content: msgObj.message.body }
|
|
42
|
+
)
|
|
43
|
+
this.tracer.decodeDataStreamsContext(msgObj.message.delivery_annotations)
|
|
44
|
+
this.tracer
|
|
45
|
+
.setCheckpoint(['direction:in', `topic:${name}`, 'type:rabbitmq'], span, payloadSize)
|
|
46
|
+
}
|
|
32
47
|
}
|
|
33
48
|
}
|
|
34
49
|
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const { CLIENT_PORT_KEY } = require('../../dd-trace/src/constants')
|
|
4
4
|
const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
|
|
5
|
+
const { DsmPathwayCodec } = require('../../dd-trace/src/datastreams/pathway')
|
|
6
|
+
const { getAmqpMessageSize } = require('../../dd-trace/src/datastreams/processor')
|
|
5
7
|
|
|
6
8
|
class RheaProducerPlugin extends ProducerPlugin {
|
|
7
9
|
static get id () { return 'rhea' }
|
|
@@ -36,6 +38,14 @@ function addDeliveryAnnotations (msg, tracer, span) {
|
|
|
36
38
|
msg.delivery_annotations = msg.delivery_annotations || {}
|
|
37
39
|
|
|
38
40
|
tracer.inject(span, 'text_map', msg.delivery_annotations)
|
|
41
|
+
|
|
42
|
+
if (tracer._config.dsmEnabled) {
|
|
43
|
+
const targetName = span.context()._tags['amqp.link.target.address']
|
|
44
|
+
const payloadSize = getAmqpMessageSize({ content: msg.body, headers: msg.delivery_annotations })
|
|
45
|
+
const dataStreamsContext = tracer
|
|
46
|
+
.setCheckpoint(['direction:out', `exchange:${targetName}`, 'type:rabbitmq'], span, payloadSize)
|
|
47
|
+
DsmPathwayCodec.encode(dataStreamsContext, msg.delivery_annotations)
|
|
48
|
+
}
|
|
39
49
|
}
|
|
40
50
|
}
|
|
41
51
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const Activation = {
|
|
4
|
+
ONECLICK: 'OneClick',
|
|
5
|
+
ENABLED: 'Enabled',
|
|
6
|
+
DISABLED: 'Disabled',
|
|
7
|
+
|
|
8
|
+
fromConfig (config) {
|
|
9
|
+
switch (config.appsec.enabled) {
|
|
10
|
+
// ASM is activated by an env var DD_APPSEC_ENABLED=true
|
|
11
|
+
case true:
|
|
12
|
+
return Activation.ENABLED
|
|
13
|
+
|
|
14
|
+
// ASM is disabled by an env var DD_APPSEC_ENABLED=false
|
|
15
|
+
case false:
|
|
16
|
+
return Activation.DISABLED
|
|
17
|
+
|
|
18
|
+
// ASM is activated by one click remote config
|
|
19
|
+
case undefined:
|
|
20
|
+
return Activation.ONECLICK
|
|
21
|
+
|
|
22
|
+
// Any other value should never occur
|
|
23
|
+
default:
|
|
24
|
+
return Activation.DISABLED
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = Activation
|
|
@@ -13,8 +13,12 @@ module.exports = {
|
|
|
13
13
|
HTTP_INCOMING_RESPONSE_HEADERS: 'server.response.headers.no_cookies',
|
|
14
14
|
// TODO: 'server.response.trailers',
|
|
15
15
|
HTTP_INCOMING_GRAPHQL_RESOLVERS: 'graphql.server.all_resolvers',
|
|
16
|
+
HTTP_INCOMING_GRAPHQL_RESOLVER: 'graphql.server.resolver',
|
|
17
|
+
|
|
18
|
+
HTTP_OUTGOING_BODY: 'server.response.body',
|
|
16
19
|
|
|
17
20
|
HTTP_CLIENT_IP: 'http.client_ip',
|
|
18
21
|
|
|
19
|
-
USER_ID: 'usr.id'
|
|
22
|
+
USER_ID: 'usr.id',
|
|
23
|
+
WAF_CONTEXT_PROCESSOR: 'waf.context.processor'
|
|
20
24
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const log = require('../log')
|
|
4
|
+
|
|
5
|
+
let enabled
|
|
6
|
+
let requestSampling
|
|
7
|
+
|
|
8
|
+
const sampledRequests = new WeakSet()
|
|
9
|
+
|
|
10
|
+
function configure ({ apiSecurity }) {
|
|
11
|
+
enabled = apiSecurity.enabled
|
|
12
|
+
setRequestSampling(apiSecurity.requestSampling)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function disable () {
|
|
16
|
+
enabled = false
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function setRequestSampling (sampling) {
|
|
20
|
+
requestSampling = parseRequestSampling(sampling)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function parseRequestSampling (requestSampling) {
|
|
24
|
+
let parsed = parseFloat(requestSampling)
|
|
25
|
+
|
|
26
|
+
if (isNaN(parsed)) {
|
|
27
|
+
log.warn(`Incorrect API Security request sampling value: ${requestSampling}`)
|
|
28
|
+
|
|
29
|
+
parsed = 0
|
|
30
|
+
} else {
|
|
31
|
+
parsed = Math.min(1, Math.max(0, parsed))
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return parsed
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function sampleRequest (req) {
|
|
38
|
+
if (!enabled || !requestSampling) {
|
|
39
|
+
return false
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const shouldSample = Math.random() <= requestSampling
|
|
43
|
+
|
|
44
|
+
if (shouldSample) {
|
|
45
|
+
sampledRequests.add(req)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return shouldSample
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function isSampled (req) {
|
|
52
|
+
return sampledRequests.has(req)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = {
|
|
56
|
+
configure,
|
|
57
|
+
disable,
|
|
58
|
+
setRequestSampling,
|
|
59
|
+
sampleRequest,
|
|
60
|
+
isSampled
|
|
61
|
+
}
|
|
@@ -5,7 +5,10 @@ const html = `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta n
|
|
|
5
5
|
|
|
6
6
|
const json = `{"errors":[{"title":"You've been blocked","detail":"Sorry, you cannot access this page. Please contact the customer service team. Security provided by Datadog."}]}`
|
|
7
7
|
|
|
8
|
+
const graphqlJson = `{"errors":[{"message":"You've been blocked","extensions":{"detail":"Sorry, you cannot perform this operation. Please contact the customer service team. Security provided by Datadog."}}]}`
|
|
9
|
+
|
|
8
10
|
module.exports = {
|
|
9
11
|
html,
|
|
10
|
-
json
|
|
12
|
+
json,
|
|
13
|
+
graphqlJson
|
|
11
14
|
}
|