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
|
@@ -1,127 +1,5 @@
|
|
|
1
|
-
const {
|
|
2
|
-
TEST_STATUS,
|
|
3
|
-
TEST_IS_RUM_ACTIVE,
|
|
4
|
-
TEST_CODE_OWNERS,
|
|
5
|
-
getTestEnvironmentMetadata,
|
|
6
|
-
CI_APP_ORIGIN,
|
|
7
|
-
getTestParentSpan,
|
|
8
|
-
getCodeOwnersFileEntries,
|
|
9
|
-
getCodeOwnersForFilename,
|
|
10
|
-
getTestCommonTags,
|
|
11
|
-
getTestSessionCommonTags,
|
|
12
|
-
getTestModuleCommonTags,
|
|
13
|
-
getTestSuiteCommonTags,
|
|
14
|
-
TEST_SUITE_ID,
|
|
15
|
-
TEST_MODULE_ID,
|
|
16
|
-
TEST_SESSION_ID,
|
|
17
|
-
TEST_COMMAND,
|
|
18
|
-
TEST_MODULE,
|
|
19
|
-
TEST_SOURCE_START,
|
|
20
|
-
finishAllTraceSpans,
|
|
21
|
-
getCoveredFilenamesFromCoverage,
|
|
22
|
-
getTestSuitePath,
|
|
23
|
-
addIntelligentTestRunnerSpanTags,
|
|
24
|
-
TEST_SKIPPED_BY_ITR,
|
|
25
|
-
TEST_ITR_UNSKIPPABLE,
|
|
26
|
-
TEST_ITR_FORCED_RUN
|
|
27
|
-
} = require('../../dd-trace/src/plugins/util/test')
|
|
28
|
-
const { ORIGIN_KEY, COMPONENT } = require('../../dd-trace/src/constants')
|
|
29
|
-
const log = require('../../dd-trace/src/log')
|
|
30
1
|
const NoopTracer = require('../../dd-trace/src/noop/tracer')
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
const TEST_FRAMEWORK_NAME = 'cypress'
|
|
34
|
-
|
|
35
|
-
const CYPRESS_STATUS_TO_TEST_STATUS = {
|
|
36
|
-
passed: 'pass',
|
|
37
|
-
failed: 'fail',
|
|
38
|
-
pending: 'skip',
|
|
39
|
-
skipped: 'skip'
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function getTestSpanMetadata (tracer, testName, testSuite, cypressConfig) {
|
|
43
|
-
const childOf = getTestParentSpan(tracer)
|
|
44
|
-
|
|
45
|
-
const commonTags = getTestCommonTags(testName, testSuite, cypressConfig.version, TEST_FRAMEWORK_NAME)
|
|
46
|
-
|
|
47
|
-
return {
|
|
48
|
-
childOf,
|
|
49
|
-
...commonTags
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function getCypressVersion (details) {
|
|
54
|
-
if (details && details.cypressVersion) {
|
|
55
|
-
return details.cypressVersion
|
|
56
|
-
}
|
|
57
|
-
if (details && details.config && details.config.version) {
|
|
58
|
-
return details.config.version
|
|
59
|
-
}
|
|
60
|
-
return ''
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function getRootDir (details) {
|
|
64
|
-
if (details && details.config) {
|
|
65
|
-
return details.config.projectRoot || details.config.repoRoot || process.cwd()
|
|
66
|
-
}
|
|
67
|
-
return process.cwd()
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function getCypressCommand (details) {
|
|
71
|
-
if (!details) {
|
|
72
|
-
return TEST_FRAMEWORK_NAME
|
|
73
|
-
}
|
|
74
|
-
return `${TEST_FRAMEWORK_NAME} ${details.specPattern || ''}`
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function getSessionStatus (summary) {
|
|
78
|
-
if (summary.totalFailed !== undefined && summary.totalFailed > 0) {
|
|
79
|
-
return 'fail'
|
|
80
|
-
}
|
|
81
|
-
if (summary.totalSkipped !== undefined && summary.totalSkipped === summary.totalTests) {
|
|
82
|
-
return 'skip'
|
|
83
|
-
}
|
|
84
|
-
return 'pass'
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function getSuiteStatus (suiteStats) {
|
|
88
|
-
if (suiteStats.failures !== undefined && suiteStats.failures > 0) {
|
|
89
|
-
return 'fail'
|
|
90
|
-
}
|
|
91
|
-
if (suiteStats.tests !== undefined && suiteStats.tests === suiteStats.pending) {
|
|
92
|
-
return 'skip'
|
|
93
|
-
}
|
|
94
|
-
return 'pass'
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function getItrConfig (tracer, testConfiguration) {
|
|
98
|
-
return new Promise(resolve => {
|
|
99
|
-
if (!tracer._tracer._exporter || !tracer._tracer._exporter.getItrConfiguration) {
|
|
100
|
-
return resolve({ err: new Error('CI Visibility was not initialized correctly') })
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
tracer._tracer._exporter.getItrConfiguration(testConfiguration, (err, itrConfig) => {
|
|
104
|
-
resolve({ err, itrConfig })
|
|
105
|
-
})
|
|
106
|
-
})
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function getSkippableTests (isSuitesSkippingEnabled, tracer, testConfiguration) {
|
|
110
|
-
if (!isSuitesSkippingEnabled) {
|
|
111
|
-
return Promise.resolve({ skippableTests: [] })
|
|
112
|
-
}
|
|
113
|
-
return new Promise(resolve => {
|
|
114
|
-
if (!tracer._tracer._exporter || !tracer._tracer._exporter.getItrConfiguration) {
|
|
115
|
-
return resolve({ err: new Error('CI Visibility was not initialized correctly') })
|
|
116
|
-
}
|
|
117
|
-
tracer._tracer._exporter.getSkippableSuites(testConfiguration, (err, skippableTests) => {
|
|
118
|
-
resolve({
|
|
119
|
-
err,
|
|
120
|
-
skippableTests
|
|
121
|
-
})
|
|
122
|
-
})
|
|
123
|
-
})
|
|
124
|
-
}
|
|
2
|
+
const cypressPlugin = require('./cypress-plugin')
|
|
125
3
|
|
|
126
4
|
const noopTask = {
|
|
127
5
|
'dd:testSuiteStart': () => {
|
|
@@ -139,8 +17,6 @@ const noopTask = {
|
|
|
139
17
|
}
|
|
140
18
|
|
|
141
19
|
module.exports = (on, config) => {
|
|
142
|
-
let isTestsSkipped = false
|
|
143
|
-
const skippedTests = []
|
|
144
20
|
const tracer = require('../../dd-trace')
|
|
145
21
|
|
|
146
22
|
// The tracer was not init correctly for whatever reason (such as invalid DD_SITE)
|
|
@@ -149,334 +25,10 @@ module.exports = (on, config) => {
|
|
|
149
25
|
return on('task', noopTask)
|
|
150
26
|
}
|
|
151
27
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const {
|
|
155
|
-
'git.repository_url': repositoryUrl,
|
|
156
|
-
'git.commit.sha': sha,
|
|
157
|
-
'os.version': osVersion,
|
|
158
|
-
'os.platform': osPlatform,
|
|
159
|
-
'os.architecture': osArchitecture,
|
|
160
|
-
'runtime.name': runtimeName,
|
|
161
|
-
'runtime.version': runtimeVersion,
|
|
162
|
-
'git.branch': branch
|
|
163
|
-
} = testEnvironmentMetadata
|
|
164
|
-
|
|
165
|
-
const finishedTestsByFile = {}
|
|
166
|
-
|
|
167
|
-
const testConfiguration = {
|
|
168
|
-
repositoryUrl,
|
|
169
|
-
sha,
|
|
170
|
-
osVersion,
|
|
171
|
-
osPlatform,
|
|
172
|
-
osArchitecture,
|
|
173
|
-
runtimeName,
|
|
174
|
-
runtimeVersion,
|
|
175
|
-
branch,
|
|
176
|
-
testLevel: 'test'
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const codeOwnersEntries = getCodeOwnersFileEntries()
|
|
180
|
-
|
|
181
|
-
let activeSpan = null
|
|
182
|
-
let testSessionSpan = null
|
|
183
|
-
let testModuleSpan = null
|
|
184
|
-
let testSuiteSpan = null
|
|
185
|
-
let command = null
|
|
186
|
-
let frameworkVersion
|
|
187
|
-
let rootDir
|
|
188
|
-
let isSuitesSkippingEnabled = false
|
|
189
|
-
let isCodeCoverageEnabled = false
|
|
190
|
-
let testsToSkip = []
|
|
191
|
-
const unskippableSuites = []
|
|
192
|
-
let hasForcedToRunSuites = false
|
|
193
|
-
let hasUnskippableSuites = false
|
|
194
|
-
|
|
195
|
-
function getTestSpan (testName, testSuite, isUnskippable, isForcedToRun) {
|
|
196
|
-
const testSuiteTags = {
|
|
197
|
-
[TEST_COMMAND]: command,
|
|
198
|
-
[TEST_COMMAND]: command,
|
|
199
|
-
[TEST_MODULE]: TEST_FRAMEWORK_NAME
|
|
200
|
-
}
|
|
201
|
-
if (testSuiteSpan) {
|
|
202
|
-
testSuiteTags[TEST_SUITE_ID] = testSuiteSpan.context().toSpanId()
|
|
203
|
-
}
|
|
204
|
-
if (testSessionSpan && testModuleSpan) {
|
|
205
|
-
testSuiteTags[TEST_SESSION_ID] = testSessionSpan.context().toTraceId()
|
|
206
|
-
testSuiteTags[TEST_MODULE_ID] = testModuleSpan.context().toSpanId()
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const {
|
|
210
|
-
childOf,
|
|
211
|
-
resource,
|
|
212
|
-
...testSpanMetadata
|
|
213
|
-
} = getTestSpanMetadata(tracer, testName, testSuite, config)
|
|
214
|
-
|
|
215
|
-
const codeOwners = getCodeOwnersForFilename(testSuite, codeOwnersEntries)
|
|
216
|
-
|
|
217
|
-
if (codeOwners) {
|
|
218
|
-
testSpanMetadata[TEST_CODE_OWNERS] = codeOwners
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (isUnskippable) {
|
|
222
|
-
hasUnskippableSuites = true
|
|
223
|
-
testSpanMetadata[TEST_ITR_UNSKIPPABLE] = 'true'
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
if (isForcedToRun) {
|
|
227
|
-
hasForcedToRunSuites = true
|
|
228
|
-
testSpanMetadata[TEST_ITR_FORCED_RUN] = 'true'
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return tracer.startSpan(`${TEST_FRAMEWORK_NAME}.test`, {
|
|
232
|
-
childOf,
|
|
233
|
-
tags: {
|
|
234
|
-
[COMPONENT]: TEST_FRAMEWORK_NAME,
|
|
235
|
-
[ORIGIN_KEY]: CI_APP_ORIGIN,
|
|
236
|
-
...testSpanMetadata,
|
|
237
|
-
...testEnvironmentMetadata,
|
|
238
|
-
...testSuiteTags
|
|
239
|
-
}
|
|
240
|
-
})
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
on('before:run', (details) => {
|
|
244
|
-
return getItrConfig(tracer, testConfiguration).then(({ err, itrConfig }) => {
|
|
245
|
-
if (err) {
|
|
246
|
-
log.error(err)
|
|
247
|
-
} else {
|
|
248
|
-
isSuitesSkippingEnabled = itrConfig.isSuitesSkippingEnabled
|
|
249
|
-
isCodeCoverageEnabled = itrConfig.isCodeCoverageEnabled
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
return getSkippableTests(isSuitesSkippingEnabled, tracer, testConfiguration).then(({ err, skippableTests }) => {
|
|
253
|
-
if (err) {
|
|
254
|
-
log.error(err)
|
|
255
|
-
} else {
|
|
256
|
-
testsToSkip = skippableTests || []
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// `details.specs` are test files
|
|
260
|
-
details.specs.forEach(({ absolute, relative }) => {
|
|
261
|
-
const isUnskippableSuite = isMarkedAsUnskippable({ path: absolute })
|
|
262
|
-
if (isUnskippableSuite) {
|
|
263
|
-
unskippableSuites.push(relative)
|
|
264
|
-
}
|
|
265
|
-
})
|
|
266
|
-
|
|
267
|
-
const childOf = getTestParentSpan(tracer)
|
|
268
|
-
rootDir = getRootDir(details)
|
|
269
|
-
|
|
270
|
-
command = getCypressCommand(details)
|
|
271
|
-
frameworkVersion = getCypressVersion(details)
|
|
272
|
-
|
|
273
|
-
const testSessionSpanMetadata = getTestSessionCommonTags(command, frameworkVersion, TEST_FRAMEWORK_NAME)
|
|
274
|
-
const testModuleSpanMetadata = getTestModuleCommonTags(command, frameworkVersion, TEST_FRAMEWORK_NAME)
|
|
275
|
-
|
|
276
|
-
testSessionSpan = tracer.startSpan(`${TEST_FRAMEWORK_NAME}.test_session`, {
|
|
277
|
-
childOf,
|
|
278
|
-
tags: {
|
|
279
|
-
[COMPONENT]: TEST_FRAMEWORK_NAME,
|
|
280
|
-
...testEnvironmentMetadata,
|
|
281
|
-
...testSessionSpanMetadata
|
|
282
|
-
}
|
|
283
|
-
})
|
|
284
|
-
testModuleSpan = tracer.startSpan(`${TEST_FRAMEWORK_NAME}.test_module`, {
|
|
285
|
-
childOf: testSessionSpan,
|
|
286
|
-
tags: {
|
|
287
|
-
[COMPONENT]: TEST_FRAMEWORK_NAME,
|
|
288
|
-
...testEnvironmentMetadata,
|
|
289
|
-
...testModuleSpanMetadata
|
|
290
|
-
}
|
|
291
|
-
})
|
|
292
|
-
return details
|
|
293
|
-
})
|
|
294
|
-
})
|
|
295
|
-
})
|
|
296
|
-
on('after:spec', (spec, { tests, stats }) => {
|
|
297
|
-
const cypressTests = tests || []
|
|
298
|
-
const finishedTests = finishedTestsByFile[spec.relative] || []
|
|
299
|
-
|
|
300
|
-
// Get tests that didn't go through `dd:afterEach`
|
|
301
|
-
// and create a skipped test span for each of them
|
|
302
|
-
cypressTests.filter(({ title }) => {
|
|
303
|
-
const cypressTestName = title.join(' ')
|
|
304
|
-
const isTestFinished = finishedTests.find(({ testName }) => cypressTestName === testName)
|
|
305
|
-
|
|
306
|
-
return !isTestFinished
|
|
307
|
-
}).forEach(({ title }) => {
|
|
308
|
-
const cypressTestName = title.join(' ')
|
|
309
|
-
const isSkippedByItr = testsToSkip.find(test =>
|
|
310
|
-
cypressTestName === test.name && spec.relative === test.suite
|
|
311
|
-
)
|
|
312
|
-
const skippedTestSpan = getTestSpan(cypressTestName, spec.relative)
|
|
313
|
-
skippedTestSpan.setTag(TEST_STATUS, 'skip')
|
|
314
|
-
if (isSkippedByItr) {
|
|
315
|
-
skippedTestSpan.setTag(TEST_SKIPPED_BY_ITR, 'true')
|
|
316
|
-
}
|
|
317
|
-
skippedTestSpan.finish()
|
|
318
|
-
})
|
|
319
|
-
|
|
320
|
-
// Make sure that reported test statuses are the same as Cypress reports.
|
|
321
|
-
// This is not always the case, such as when an `after` hook fails:
|
|
322
|
-
// Cypress will report the last run test as failed, but we don't know that yet at `dd:afterEach`
|
|
323
|
-
let latestError
|
|
324
|
-
finishedTests.forEach((finishedTest) => {
|
|
325
|
-
const cypressTest = cypressTests.find(test => test.title.join(' ') === finishedTest.testName)
|
|
326
|
-
if (!cypressTest) {
|
|
327
|
-
return
|
|
328
|
-
}
|
|
329
|
-
if (cypressTest.displayError) {
|
|
330
|
-
latestError = new Error(cypressTest.displayError)
|
|
331
|
-
}
|
|
332
|
-
const cypressTestStatus = CYPRESS_STATUS_TO_TEST_STATUS[cypressTest.state]
|
|
333
|
-
// update test status
|
|
334
|
-
if (cypressTestStatus !== finishedTest.testStatus) {
|
|
335
|
-
finishedTest.testSpan.setTag(TEST_STATUS, cypressTestStatus)
|
|
336
|
-
finishedTest.testSpan.setTag('error', latestError)
|
|
337
|
-
}
|
|
338
|
-
finishedTest.testSpan.finish(finishedTest.finishTime)
|
|
339
|
-
})
|
|
340
|
-
|
|
341
|
-
if (testSuiteSpan) {
|
|
342
|
-
const status = getSuiteStatus(stats)
|
|
343
|
-
testSuiteSpan.setTag(TEST_STATUS, status)
|
|
344
|
-
|
|
345
|
-
if (latestError) {
|
|
346
|
-
testSuiteSpan.setTag('error', latestError)
|
|
347
|
-
}
|
|
348
|
-
testSuiteSpan.finish()
|
|
349
|
-
testSuiteSpan = null
|
|
350
|
-
}
|
|
351
|
-
})
|
|
352
|
-
|
|
353
|
-
on('after:run', (suiteStats) => {
|
|
354
|
-
if (testSessionSpan && testModuleSpan) {
|
|
355
|
-
const testStatus = getSessionStatus(suiteStats)
|
|
356
|
-
testModuleSpan.setTag(TEST_STATUS, testStatus)
|
|
357
|
-
testSessionSpan.setTag(TEST_STATUS, testStatus)
|
|
358
|
-
|
|
359
|
-
addIntelligentTestRunnerSpanTags(
|
|
360
|
-
testSessionSpan,
|
|
361
|
-
testModuleSpan,
|
|
362
|
-
{
|
|
363
|
-
isSuitesSkipped: isTestsSkipped,
|
|
364
|
-
isSuitesSkippingEnabled,
|
|
365
|
-
isCodeCoverageEnabled,
|
|
366
|
-
skippingType: 'test',
|
|
367
|
-
skippingCount: skippedTests.length,
|
|
368
|
-
hasForcedToRunSuites,
|
|
369
|
-
hasUnskippableSuites
|
|
370
|
-
}
|
|
371
|
-
)
|
|
372
|
-
|
|
373
|
-
testModuleSpan.finish()
|
|
374
|
-
testSessionSpan.finish()
|
|
375
|
-
|
|
376
|
-
finishAllTraceSpans(testSessionSpan)
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
return new Promise(resolve => {
|
|
380
|
-
const exporter = tracer._tracer._exporter
|
|
381
|
-
if (!exporter) {
|
|
382
|
-
return resolve(null)
|
|
383
|
-
}
|
|
384
|
-
if (exporter.flush) {
|
|
385
|
-
exporter.flush(() => {
|
|
386
|
-
resolve(null)
|
|
387
|
-
})
|
|
388
|
-
} else if (exporter._writer) {
|
|
389
|
-
exporter._writer.flush(() => {
|
|
390
|
-
resolve(null)
|
|
391
|
-
})
|
|
392
|
-
}
|
|
393
|
-
})
|
|
394
|
-
})
|
|
395
|
-
on('task', {
|
|
396
|
-
'dd:testSuiteStart': (suite) => {
|
|
397
|
-
if (testSuiteSpan) {
|
|
398
|
-
return null
|
|
399
|
-
}
|
|
400
|
-
const testSuiteSpanMetadata = getTestSuiteCommonTags(command, frameworkVersion, suite, TEST_FRAMEWORK_NAME)
|
|
401
|
-
testSuiteSpan = tracer.startSpan(`${TEST_FRAMEWORK_NAME}.test_suite`, {
|
|
402
|
-
childOf: testModuleSpan,
|
|
403
|
-
tags: {
|
|
404
|
-
[COMPONENT]: TEST_FRAMEWORK_NAME,
|
|
405
|
-
...testEnvironmentMetadata,
|
|
406
|
-
...testSuiteSpanMetadata
|
|
407
|
-
}
|
|
408
|
-
})
|
|
409
|
-
return null
|
|
410
|
-
},
|
|
411
|
-
'dd:beforeEach': (test) => {
|
|
412
|
-
const { testName, testSuite } = test
|
|
413
|
-
const shouldSkip = !!testsToSkip.find(test => {
|
|
414
|
-
return testName === test.name && testSuite === test.suite
|
|
415
|
-
})
|
|
416
|
-
const isUnskippable = unskippableSuites.includes(testSuite)
|
|
417
|
-
const isForcedToRun = shouldSkip && isUnskippable
|
|
418
|
-
|
|
419
|
-
// skip test
|
|
420
|
-
if (shouldSkip && !isUnskippable) {
|
|
421
|
-
skippedTests.push(test)
|
|
422
|
-
isTestsSkipped = true
|
|
423
|
-
return { shouldSkip: true }
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
if (!activeSpan) {
|
|
427
|
-
activeSpan = getTestSpan(testName, testSuite, isUnskippable, isForcedToRun)
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
return activeSpan ? { traceId: activeSpan.context().toTraceId() } : {}
|
|
431
|
-
},
|
|
432
|
-
'dd:afterEach': ({ test, coverage }) => {
|
|
433
|
-
const { state, error, isRUMActive, testSourceLine, testSuite, testName } = test
|
|
434
|
-
if (activeSpan) {
|
|
435
|
-
if (coverage && isCodeCoverageEnabled && tracer._tracer._exporter && tracer._tracer._exporter.exportCoverage) {
|
|
436
|
-
const coverageFiles = getCoveredFilenamesFromCoverage(coverage)
|
|
437
|
-
const relativeCoverageFiles = coverageFiles.map(file => getTestSuitePath(file, rootDir))
|
|
438
|
-
const { _traceId, _spanId } = testSuiteSpan.context()
|
|
439
|
-
const formattedCoverage = {
|
|
440
|
-
sessionId: _traceId,
|
|
441
|
-
suiteId: _spanId,
|
|
442
|
-
testId: activeSpan.context()._spanId,
|
|
443
|
-
files: relativeCoverageFiles
|
|
444
|
-
}
|
|
445
|
-
tracer._tracer._exporter.exportCoverage(formattedCoverage)
|
|
446
|
-
}
|
|
447
|
-
const testStatus = CYPRESS_STATUS_TO_TEST_STATUS[state]
|
|
448
|
-
activeSpan.setTag(TEST_STATUS, testStatus)
|
|
28
|
+
cypressPlugin.init(tracer, config)
|
|
449
29
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
activeSpan.setTag(TEST_IS_RUM_ACTIVE, 'true')
|
|
455
|
-
}
|
|
456
|
-
if (testSourceLine) {
|
|
457
|
-
activeSpan.setTag(TEST_SOURCE_START, testSourceLine)
|
|
458
|
-
}
|
|
459
|
-
const finishedTest = {
|
|
460
|
-
testName,
|
|
461
|
-
testStatus,
|
|
462
|
-
finishTime: activeSpan._getTime(), // we store the finish time here
|
|
463
|
-
testSpan: activeSpan
|
|
464
|
-
}
|
|
465
|
-
if (finishedTestsByFile[testSuite]) {
|
|
466
|
-
finishedTestsByFile[testSuite].push(finishedTest)
|
|
467
|
-
} else {
|
|
468
|
-
finishedTestsByFile[testSuite] = [finishedTest]
|
|
469
|
-
}
|
|
470
|
-
// test spans are finished at after:spec
|
|
471
|
-
}
|
|
472
|
-
activeSpan = null
|
|
473
|
-
return null
|
|
474
|
-
},
|
|
475
|
-
'dd:addTags': (tags) => {
|
|
476
|
-
if (activeSpan) {
|
|
477
|
-
activeSpan.addTags(tags)
|
|
478
|
-
}
|
|
479
|
-
return null
|
|
480
|
-
}
|
|
481
|
-
})
|
|
30
|
+
on('before:run', cypressPlugin.beforeRun.bind(cypressPlugin))
|
|
31
|
+
on('after:spec', cypressPlugin.afterSpec.bind(cypressPlugin))
|
|
32
|
+
on('after:run', cypressPlugin.afterRun.bind(cypressPlugin))
|
|
33
|
+
on('task', cypressPlugin.getTasks())
|
|
482
34
|
}
|
|
@@ -1,4 +1,43 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
|
+
let isEarlyFlakeDetectionEnabled = false
|
|
3
|
+
let knownTestsForSuite = []
|
|
4
|
+
let suiteTests = []
|
|
5
|
+
let earlyFlakeDetectionNumRetries = 0
|
|
6
|
+
|
|
7
|
+
function isNewTest (test) {
|
|
8
|
+
return !knownTestsForSuite.includes(test.fullTitle())
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function retryTest (test, suiteTests) {
|
|
12
|
+
for (let retryIndex = 0; retryIndex < earlyFlakeDetectionNumRetries; retryIndex++) {
|
|
13
|
+
const clonedTest = test.clone()
|
|
14
|
+
// TODO: signal in framework logs that this is a retry.
|
|
15
|
+
// TODO: Change it so these tests are allowed to fail.
|
|
16
|
+
// TODO: figure out if reported duration is skewed.
|
|
17
|
+
suiteTests.unshift(clonedTest)
|
|
18
|
+
clonedTest._ddIsNew = true
|
|
19
|
+
clonedTest._ddIsEfdRetry = true
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
const oldRunTests = Cypress.mocha.getRunner().runTests
|
|
25
|
+
Cypress.mocha.getRunner().runTests = function (suite, fn) {
|
|
26
|
+
if (!isEarlyFlakeDetectionEnabled) {
|
|
27
|
+
return oldRunTests.apply(this, arguments)
|
|
28
|
+
}
|
|
29
|
+
// We copy the new tests at the beginning of the suite run (runTests), so that they're run
|
|
30
|
+
// multiple times.
|
|
31
|
+
suite.tests.forEach(test => {
|
|
32
|
+
if (!test._ddIsNew && !test.isPending() && isNewTest(test)) {
|
|
33
|
+
test._ddIsNew = true
|
|
34
|
+
retryTest(test, suite.tests)
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
return oldRunTests.apply(this, [suite, fn])
|
|
39
|
+
}
|
|
40
|
+
|
|
2
41
|
beforeEach(function () {
|
|
3
42
|
cy.task('dd:beforeEach', {
|
|
4
43
|
testName: Cypress.mocha.getRunner().suite.ctx.currentTest.fullTitle(),
|
|
@@ -11,8 +50,14 @@ beforeEach(function () {
|
|
|
11
50
|
})
|
|
12
51
|
})
|
|
13
52
|
|
|
14
|
-
before(()
|
|
15
|
-
cy.task('dd:testSuiteStart', Cypress.mocha.getRootSuite().file)
|
|
53
|
+
before(function () {
|
|
54
|
+
cy.task('dd:testSuiteStart', Cypress.mocha.getRootSuite().file).then((suiteConfig) => {
|
|
55
|
+
if (suiteConfig) {
|
|
56
|
+
isEarlyFlakeDetectionEnabled = suiteConfig.isEarlyFlakeDetectionEnabled
|
|
57
|
+
knownTestsForSuite = suiteConfig.knownTestsForSuite
|
|
58
|
+
earlyFlakeDetectionNumRetries = suiteConfig.earlyFlakeDetectionNumRetries
|
|
59
|
+
}
|
|
60
|
+
})
|
|
16
61
|
})
|
|
17
62
|
|
|
18
63
|
after(() => {
|
|
@@ -24,7 +69,7 @@ after(() => {
|
|
|
24
69
|
})
|
|
25
70
|
|
|
26
71
|
|
|
27
|
-
afterEach(()
|
|
72
|
+
afterEach(function () {
|
|
28
73
|
cy.window().then(win => {
|
|
29
74
|
const currentTest = Cypress.mocha.getRunner().suite.ctx.currentTest
|
|
30
75
|
const testInfo = {
|
|
@@ -32,6 +77,8 @@ afterEach(() => {
|
|
|
32
77
|
testSuite: Cypress.mocha.getRootSuite().file,
|
|
33
78
|
state: currentTest.state,
|
|
34
79
|
error: currentTest.err,
|
|
80
|
+
isNew: currentTest._ddIsNew,
|
|
81
|
+
isEfdRetry: currentTest._ddIsEfdRetry
|
|
35
82
|
}
|
|
36
83
|
try {
|
|
37
84
|
testInfo.testSourceLine = Cypress.mocha.getRunner().currentRunnable.invocationDetails.line
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const pick = require('../../datadog-core/src/utils/src/pick')
|
|
3
4
|
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
4
5
|
const log = require('../../dd-trace/src/log')
|
|
5
6
|
const GraphQLExecutePlugin = require('./execute')
|
|
@@ -63,10 +64,4 @@ function getHooks (config) {
|
|
|
63
64
|
return { execute, parse, validate }
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
// non-lodash pick
|
|
67
|
-
|
|
68
|
-
function pick (obj, selectors) {
|
|
69
|
-
return Object.fromEntries(Object.entries(obj).filter(([key]) => selectors.includes(key)))
|
|
70
|
-
}
|
|
71
|
-
|
|
72
67
|
module.exports = GraphQLPlugin
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
|
|
4
|
+
const dc = require('dc-polyfill')
|
|
4
5
|
|
|
5
6
|
const collapsedPathSym = Symbol('collapsedPaths')
|
|
6
7
|
|
|
@@ -14,8 +15,6 @@ class GraphQLResolvePlugin extends TracingPlugin {
|
|
|
14
15
|
if (!shouldInstrument(this.config, path)) return
|
|
15
16
|
const computedPathString = path.join('.')
|
|
16
17
|
|
|
17
|
-
addResolver(context, info, args)
|
|
18
|
-
|
|
19
18
|
if (this.config.collapse) {
|
|
20
19
|
if (!context[collapsedPathSym]) {
|
|
21
20
|
context[collapsedPathSym] = {}
|
|
@@ -55,6 +54,10 @@ class GraphQLResolvePlugin extends TracingPlugin {
|
|
|
55
54
|
span.setTag(`graphql.variables.${name}`, variables[name])
|
|
56
55
|
})
|
|
57
56
|
}
|
|
57
|
+
|
|
58
|
+
if (this.resolverStartCh.hasSubscribers) {
|
|
59
|
+
this.resolverStartCh.publish({ context, resolverInfo: getResolverInfo(info, args) })
|
|
60
|
+
}
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
constructor (...args) {
|
|
@@ -69,6 +72,8 @@ class GraphQLResolvePlugin extends TracingPlugin {
|
|
|
69
72
|
field.finishTime = span._getTime ? span._getTime() : 0
|
|
70
73
|
field.error = field.error || err
|
|
71
74
|
})
|
|
75
|
+
|
|
76
|
+
this.resolverStartCh = dc.channel('datadog:graphql:resolver:start')
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
configure (config) {
|
|
@@ -109,28 +114,33 @@ function withCollapse (responsePathAsArray) {
|
|
|
109
114
|
}
|
|
110
115
|
}
|
|
111
116
|
|
|
112
|
-
function
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
117
|
+
function getResolverInfo (info, args) {
|
|
118
|
+
let resolverInfo = null
|
|
119
|
+
const resolverVars = {}
|
|
116
120
|
|
|
117
|
-
if (
|
|
118
|
-
|
|
121
|
+
if (args && Object.keys(args).length) {
|
|
122
|
+
Object.assign(resolverVars, args)
|
|
119
123
|
}
|
|
120
124
|
|
|
121
|
-
const
|
|
125
|
+
const directives = info.fieldNodes?.[0]?.directives
|
|
126
|
+
if (Array.isArray(directives)) {
|
|
127
|
+
for (const directive of directives) {
|
|
128
|
+
const argList = {}
|
|
129
|
+
for (const argument of directive['arguments']) {
|
|
130
|
+
argList[argument.name.value] = argument.value.value
|
|
131
|
+
}
|
|
122
132
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
} else {
|
|
127
|
-
resolvers[info.fieldName] = []
|
|
128
|
-
}
|
|
129
|
-
} else {
|
|
130
|
-
if (args && Object.keys(args).length) {
|
|
131
|
-
resolvers[info.fieldName].push(args)
|
|
133
|
+
if (Object.keys(argList).length) {
|
|
134
|
+
resolverVars[directive.name.value] = argList
|
|
135
|
+
}
|
|
132
136
|
}
|
|
133
137
|
}
|
|
138
|
+
|
|
139
|
+
if (Object.keys(resolverVars).length) {
|
|
140
|
+
resolverInfo = { [info.fieldName]: resolverVars }
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return resolverInfo
|
|
134
144
|
}
|
|
135
145
|
|
|
136
146
|
module.exports = GraphQLResolvePlugin
|
|
@@ -41,7 +41,6 @@ class GrpcClientPlugin extends ClientPlugin {
|
|
|
41
41
|
'grpc.status.code': 0
|
|
42
42
|
}
|
|
43
43
|
}, false)
|
|
44
|
-
|
|
45
44
|
// needed as precursor for peer.service
|
|
46
45
|
if (method.service && method.package) {
|
|
47
46
|
span.setTag('rpc.service', method.package + '.' + method.service)
|
|
@@ -68,7 +67,7 @@ class GrpcClientPlugin extends ClientPlugin {
|
|
|
68
67
|
this.addError(error, span)
|
|
69
68
|
}
|
|
70
69
|
|
|
71
|
-
finish ({ span, result }) {
|
|
70
|
+
finish ({ span, result, peer }) {
|
|
72
71
|
if (!span) return
|
|
73
72
|
|
|
74
73
|
const { code, metadata } = result || {}
|
|
@@ -80,6 +79,21 @@ class GrpcClientPlugin extends ClientPlugin {
|
|
|
80
79
|
addMetadataTags(span, metadata, metadataFilter, 'response')
|
|
81
80
|
}
|
|
82
81
|
|
|
82
|
+
if (peer) {
|
|
83
|
+
// The only scheme we want to support here is ipv[46]:port, although
|
|
84
|
+
// more are supported by the library
|
|
85
|
+
// https://github.com/grpc/grpc/blob/v1.60.0/doc/naming.md
|
|
86
|
+
const parts = peer.split(':')
|
|
87
|
+
if (parts[parts.length - 1].match(/^\d+/)) {
|
|
88
|
+
const port = parts[parts.length - 1]
|
|
89
|
+
const ip = parts.slice(0, -1).join(':')
|
|
90
|
+
span.setTag('network.destination.ip', ip)
|
|
91
|
+
span.setTag('network.destination.port', port)
|
|
92
|
+
} else {
|
|
93
|
+
span.setTag('network.destination.ip', peer)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
83
97
|
this.tagPeerService(span)
|
|
84
98
|
span.finish()
|
|
85
99
|
}
|