dd-trace 3.43.0 → 3.45.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/package.json +6 -6
- package/packages/datadog-instrumentations/src/child-process.js +4 -5
- package/packages/datadog-instrumentations/src/couchbase.js +5 -4
- package/packages/datadog-instrumentations/src/crypto.js +2 -1
- package/packages/datadog-instrumentations/src/dns.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +7 -2
- package/packages/datadog-instrumentations/src/helpers/instrument.js +8 -3
- package/packages/datadog-instrumentations/src/helpers/register.js +18 -2
- package/packages/datadog-instrumentations/src/http/client.js +2 -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 +3 -1
- package/packages/datadog-instrumentations/src/net.js +10 -2
- package/packages/datadog-plugin-cucumber/src/index.js +34 -2
- package/packages/datadog-plugin-cypress/src/plugin.js +60 -8
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -0
- package/packages/datadog-plugin-jest/src/index.js +60 -6
- package/packages/datadog-plugin-jest/src/util.js +38 -16
- package/packages/datadog-plugin-mocha/src/index.js +32 -1
- package/packages/datadog-plugin-playwright/src/index.js +17 -1
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +5 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +4 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +30 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +30 -1
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +36 -4
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +18 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +26 -1
- package/packages/dd-trace/src/ci-visibility/telemetry.js +130 -0
- package/packages/dd-trace/src/config.js +100 -59
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +14 -1
- 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/opentracing/tracer.js +2 -2
- package/packages/dd-trace/src/plugins/ci_plugin.js +44 -8
- package/packages/dd-trace/src/plugins/index.js +5 -0
- package/packages/dd-trace/src/plugins/util/exec.js +23 -2
- package/packages/dd-trace/src/plugins/util/git.js +94 -19
- package/packages/dd-trace/src/priority_sampler.js +30 -38
- package/packages/dd-trace/src/profiling/config.js +17 -2
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -0
- package/packages/dd-trace/src/profiling/exporters/file.js +2 -1
- package/packages/dd-trace/src/profiling/profiler.js +18 -14
- package/packages/dd-trace/src/profiling/profilers/events.js +11 -5
- package/packages/dd-trace/src/profiling/profilers/shared.js +7 -1
- package/packages/dd-trace/src/profiling/profilers/space.js +17 -2
- package/packages/dd-trace/src/profiling/profilers/wall.js +34 -21
- package/packages/dd-trace/src/sampling_rule.js +130 -0
- package/packages/dd-trace/src/span_sampler.js +6 -64
- package/packages/dd-trace/src/telemetry/index.js +43 -5
- package/packages/dd-trace/src/telemetry/send-data.js +35 -16
|
@@ -12,10 +12,21 @@ const {
|
|
|
12
12
|
TEST_FRAMEWORK_VERSION,
|
|
13
13
|
TEST_SOURCE_START,
|
|
14
14
|
TEST_ITR_UNSKIPPABLE,
|
|
15
|
-
TEST_ITR_FORCED_RUN
|
|
15
|
+
TEST_ITR_FORCED_RUN,
|
|
16
|
+
TEST_CODE_OWNERS
|
|
16
17
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
17
18
|
const { COMPONENT } = require('../../dd-trace/src/constants')
|
|
18
19
|
const id = require('../../dd-trace/src/id')
|
|
20
|
+
const {
|
|
21
|
+
TELEMETRY_EVENT_CREATED,
|
|
22
|
+
TELEMETRY_EVENT_FINISHED,
|
|
23
|
+
TELEMETRY_CODE_COVERAGE_STARTED,
|
|
24
|
+
TELEMETRY_CODE_COVERAGE_FINISHED,
|
|
25
|
+
TELEMETRY_ITR_FORCED_TO_RUN,
|
|
26
|
+
TELEMETRY_CODE_COVERAGE_EMPTY,
|
|
27
|
+
TELEMETRY_ITR_UNSKIPPABLE,
|
|
28
|
+
TELEMETRY_CODE_COVERAGE_NUM_FILES
|
|
29
|
+
} = require('../../dd-trace/src/ci-visibility/telemetry')
|
|
19
30
|
|
|
20
31
|
const isJestWorker = !!process.env.JEST_WORKER_ID
|
|
21
32
|
|
|
@@ -27,6 +38,20 @@ class JestPlugin extends CiPlugin {
|
|
|
27
38
|
return 'jest'
|
|
28
39
|
}
|
|
29
40
|
|
|
41
|
+
// The lists are the same for every test suite, so we can cache them
|
|
42
|
+
getUnskippableSuites (unskippableSuitesList) {
|
|
43
|
+
if (!this.unskippableSuites) {
|
|
44
|
+
this.unskippableSuites = JSON.parse(unskippableSuitesList)
|
|
45
|
+
}
|
|
46
|
+
return this.unskippableSuites
|
|
47
|
+
}
|
|
48
|
+
getForcedToRunSuites (forcedToRunSuitesList) {
|
|
49
|
+
if (!this.forcedToRunSuites) {
|
|
50
|
+
this.forcedToRunSuites = JSON.parse(forcedToRunSuitesList)
|
|
51
|
+
}
|
|
52
|
+
return this.forcedToRunSuites
|
|
53
|
+
}
|
|
54
|
+
|
|
30
55
|
constructor (...args) {
|
|
31
56
|
super(...args)
|
|
32
57
|
|
|
@@ -81,7 +106,9 @@ class JestPlugin extends CiPlugin {
|
|
|
81
106
|
)
|
|
82
107
|
|
|
83
108
|
this.testModuleSpan.finish()
|
|
109
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
|
|
84
110
|
this.testSessionSpan.finish()
|
|
111
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
|
|
85
112
|
finishAllTraceSpans(this.testSessionSpan)
|
|
86
113
|
this.tracer._exporter.flush()
|
|
87
114
|
})
|
|
@@ -103,7 +130,8 @@ class JestPlugin extends CiPlugin {
|
|
|
103
130
|
_ddTestCommand: testCommand,
|
|
104
131
|
_ddTestModuleId: testModuleId,
|
|
105
132
|
_ddForcedToRun,
|
|
106
|
-
_ddUnskippable
|
|
133
|
+
_ddUnskippable,
|
|
134
|
+
_ddTestCodeCoverageEnabled
|
|
107
135
|
} = testEnvironmentOptions
|
|
108
136
|
|
|
109
137
|
const testSessionSpanContext = this.tracer.extract('text_map', {
|
|
@@ -114,9 +142,17 @@ class JestPlugin extends CiPlugin {
|
|
|
114
142
|
const testSuiteMetadata = getTestSuiteCommonTags(testCommand, frameworkVersion, testSuite, 'jest')
|
|
115
143
|
|
|
116
144
|
if (_ddUnskippable) {
|
|
117
|
-
|
|
145
|
+
const unskippableSuites = this.getUnskippableSuites(_ddUnskippable)
|
|
146
|
+
if (unskippableSuites[testSuite]) {
|
|
147
|
+
this.telemetry.count(TELEMETRY_ITR_UNSKIPPABLE, { testLevel: 'suite' })
|
|
148
|
+
testSuiteMetadata[TEST_ITR_UNSKIPPABLE] = 'true'
|
|
149
|
+
}
|
|
118
150
|
if (_ddForcedToRun) {
|
|
119
|
-
|
|
151
|
+
const forcedToRunSuites = this.getForcedToRunSuites(_ddForcedToRun)
|
|
152
|
+
if (forcedToRunSuites[testSuite]) {
|
|
153
|
+
this.telemetry.count(TELEMETRY_ITR_FORCED_TO_RUN, { testLevel: 'suite' })
|
|
154
|
+
testSuiteMetadata[TEST_ITR_FORCED_RUN] = 'true'
|
|
155
|
+
}
|
|
120
156
|
}
|
|
121
157
|
}
|
|
122
158
|
|
|
@@ -128,6 +164,10 @@ class JestPlugin extends CiPlugin {
|
|
|
128
164
|
...testSuiteMetadata
|
|
129
165
|
}
|
|
130
166
|
})
|
|
167
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'suite')
|
|
168
|
+
if (_ddTestCodeCoverageEnabled) {
|
|
169
|
+
this.telemetry.ciVisEvent(TELEMETRY_CODE_COVERAGE_STARTED, 'suite', { library: 'istanbul' })
|
|
170
|
+
}
|
|
131
171
|
})
|
|
132
172
|
|
|
133
173
|
this.addSub('ci:jest:worker-report:trace', traces => {
|
|
@@ -164,6 +204,7 @@ class JestPlugin extends CiPlugin {
|
|
|
164
204
|
this.testSuiteSpan.setTag('error', new Error(errorMessage))
|
|
165
205
|
}
|
|
166
206
|
this.testSuiteSpan.finish()
|
|
207
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
|
|
167
208
|
// Suites potentially run in a different process than the session,
|
|
168
209
|
// so calling finishAllTraceSpans on the session span is not enough
|
|
169
210
|
finishAllTraceSpans(this.testSuiteSpan)
|
|
@@ -180,14 +221,22 @@ class JestPlugin extends CiPlugin {
|
|
|
180
221
|
* because this subscription happens in a different process from the one
|
|
181
222
|
* fetching the ITR config.
|
|
182
223
|
*/
|
|
183
|
-
this.addSub('ci:jest:test-suite:code-coverage', (coverageFiles) => {
|
|
224
|
+
this.addSub('ci:jest:test-suite:code-coverage', ({ coverageFiles, testSuite }) => {
|
|
225
|
+
if (!coverageFiles.length) {
|
|
226
|
+
this.telemetry.count(TELEMETRY_CODE_COVERAGE_EMPTY)
|
|
227
|
+
}
|
|
228
|
+
const files = [...coverageFiles, testSuite]
|
|
229
|
+
|
|
184
230
|
const { _traceId, _spanId } = this.testSuiteSpan.context()
|
|
185
231
|
const formattedCoverage = {
|
|
186
232
|
sessionId: _traceId,
|
|
187
233
|
suiteId: _spanId,
|
|
188
|
-
files
|
|
234
|
+
files
|
|
189
235
|
}
|
|
236
|
+
|
|
190
237
|
this.tracer._exporter.exportCoverage(formattedCoverage)
|
|
238
|
+
this.telemetry.ciVisEvent(TELEMETRY_CODE_COVERAGE_FINISHED, 'suite', { library: 'istanbul' })
|
|
239
|
+
this.telemetry.distribution(TELEMETRY_CODE_COVERAGE_NUM_FILES, {}, files.length)
|
|
191
240
|
})
|
|
192
241
|
|
|
193
242
|
this.addSub('ci:jest:test:start', (test) => {
|
|
@@ -204,6 +253,11 @@ class JestPlugin extends CiPlugin {
|
|
|
204
253
|
span.setTag(TEST_SOURCE_START, testStartLine)
|
|
205
254
|
}
|
|
206
255
|
span.finish()
|
|
256
|
+
this.telemetry.ciVisEvent(
|
|
257
|
+
TELEMETRY_EVENT_FINISHED,
|
|
258
|
+
'test',
|
|
259
|
+
{ hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
|
|
260
|
+
)
|
|
207
261
|
finishAllTraceSpans(span)
|
|
208
262
|
})
|
|
209
263
|
|
|
@@ -77,30 +77,52 @@ function isMarkedAsUnskippable (test) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
function getJestSuitesToRun (skippableSuites, originalTests, rootDir) {
|
|
80
|
-
|
|
80
|
+
const unskippableSuites = {}
|
|
81
|
+
const forcedToRunSuites = {}
|
|
82
|
+
|
|
83
|
+
const skippedSuites = []
|
|
84
|
+
const suitesToRun = []
|
|
85
|
+
|
|
86
|
+
for (const test of originalTests) {
|
|
81
87
|
const relativePath = getTestSuitePath(test.path, rootDir)
|
|
82
88
|
const shouldBeSkipped = skippableSuites.includes(relativePath)
|
|
83
|
-
|
|
84
89
|
if (isMarkedAsUnskippable(test)) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (shouldBeSkipped) {
|
|
90
|
-
test.context.config.testEnvironmentOptions['_ddForcedToRun'] = true
|
|
91
|
-
acc.hasForcedToRunSuites = true
|
|
92
|
-
}
|
|
90
|
+
suitesToRun.push(test)
|
|
91
|
+
unskippableSuites[relativePath] = true
|
|
92
|
+
if (shouldBeSkipped) {
|
|
93
|
+
forcedToRunSuites[relativePath] = true
|
|
93
94
|
}
|
|
94
|
-
|
|
95
|
+
continue
|
|
95
96
|
}
|
|
96
|
-
|
|
97
97
|
if (shouldBeSkipped) {
|
|
98
|
-
|
|
98
|
+
skippedSuites.push(relativePath)
|
|
99
99
|
} else {
|
|
100
|
-
|
|
100
|
+
suitesToRun.push(test)
|
|
101
101
|
}
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const hasUnskippableSuites = Object.keys(unskippableSuites).length > 0
|
|
105
|
+
const hasForcedToRunSuites = Object.keys(forcedToRunSuites).length > 0
|
|
106
|
+
|
|
107
|
+
if (originalTests.length) {
|
|
108
|
+
// The config object is shared by all tests, so we can just take the first one
|
|
109
|
+
const [test] = originalTests
|
|
110
|
+
if (test?.context?.config?.testEnvironmentOptions) {
|
|
111
|
+
if (hasUnskippableSuites) {
|
|
112
|
+
test.context.config.testEnvironmentOptions._ddUnskippable = JSON.stringify(unskippableSuites)
|
|
113
|
+
}
|
|
114
|
+
if (hasForcedToRunSuites) {
|
|
115
|
+
test.context.config.testEnvironmentOptions._ddForcedToRun = JSON.stringify(forcedToRunSuites)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
skippedSuites,
|
|
122
|
+
suitesToRun,
|
|
123
|
+
hasUnskippableSuites,
|
|
124
|
+
hasForcedToRunSuites
|
|
125
|
+
}
|
|
104
126
|
}
|
|
105
127
|
|
|
106
128
|
module.exports = { getFormattedJestTestParameters, getJestTestName, getJestSuitesToRun, isMarkedAsUnskippable }
|
|
@@ -13,9 +13,20 @@ 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
|
|
17
18
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
18
19
|
const { COMPONENT } = require('../../dd-trace/src/constants')
|
|
20
|
+
const {
|
|
21
|
+
TELEMETRY_EVENT_CREATED,
|
|
22
|
+
TELEMETRY_EVENT_FINISHED,
|
|
23
|
+
TELEMETRY_CODE_COVERAGE_STARTED,
|
|
24
|
+
TELEMETRY_CODE_COVERAGE_FINISHED,
|
|
25
|
+
TELEMETRY_ITR_FORCED_TO_RUN,
|
|
26
|
+
TELEMETRY_CODE_COVERAGE_EMPTY,
|
|
27
|
+
TELEMETRY_ITR_UNSKIPPABLE,
|
|
28
|
+
TELEMETRY_CODE_COVERAGE_NUM_FILES
|
|
29
|
+
} = require('../../dd-trace/src/ci-visibility/telemetry')
|
|
19
30
|
|
|
20
31
|
class MochaPlugin extends CiPlugin {
|
|
21
32
|
static get id () {
|
|
@@ -35,6 +46,10 @@ class MochaPlugin extends CiPlugin {
|
|
|
35
46
|
}
|
|
36
47
|
const testSuiteSpan = this._testSuites.get(suiteFile)
|
|
37
48
|
|
|
49
|
+
if (!coverageFiles.length) {
|
|
50
|
+
this.telemetry.count(TELEMETRY_CODE_COVERAGE_EMPTY)
|
|
51
|
+
}
|
|
52
|
+
|
|
38
53
|
const relativeCoverageFiles = [...coverageFiles, suiteFile]
|
|
39
54
|
.map(filename => getTestSuitePath(filename, this.sourceRoot))
|
|
40
55
|
|
|
@@ -47,6 +62,8 @@ class MochaPlugin extends CiPlugin {
|
|
|
47
62
|
}
|
|
48
63
|
|
|
49
64
|
this.tracer._exporter.exportCoverage(formattedCoverage)
|
|
65
|
+
this.telemetry.ciVisEvent(TELEMETRY_CODE_COVERAGE_FINISHED, 'suite', { library: 'istanbul' })
|
|
66
|
+
this.telemetry.distribution(TELEMETRY_CODE_COVERAGE_NUM_FILES, {}, relativeCoverageFiles.length)
|
|
50
67
|
})
|
|
51
68
|
|
|
52
69
|
this.addSub('ci:mocha:test-suite:start', ({ testSuite, isUnskippable, isForcedToRun }) => {
|
|
@@ -59,9 +76,11 @@ class MochaPlugin extends CiPlugin {
|
|
|
59
76
|
)
|
|
60
77
|
if (isUnskippable) {
|
|
61
78
|
testSuiteMetadata[TEST_ITR_UNSKIPPABLE] = 'true'
|
|
79
|
+
this.telemetry.count(TELEMETRY_ITR_UNSKIPPABLE, { testLevel: 'suite' })
|
|
62
80
|
}
|
|
63
81
|
if (isForcedToRun) {
|
|
64
82
|
testSuiteMetadata[TEST_ITR_FORCED_RUN] = 'true'
|
|
83
|
+
this.telemetry.count(TELEMETRY_ITR_FORCED_TO_RUN, { testLevel: 'suite' })
|
|
65
84
|
}
|
|
66
85
|
|
|
67
86
|
const testSuiteSpan = this.tracer.startSpan('mocha.test_suite', {
|
|
@@ -72,6 +91,10 @@ class MochaPlugin extends CiPlugin {
|
|
|
72
91
|
...testSuiteMetadata
|
|
73
92
|
}
|
|
74
93
|
})
|
|
94
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'suite')
|
|
95
|
+
if (this.itrConfig?.isCodeCoverageEnabled) {
|
|
96
|
+
this.telemetry.ciVisEvent(TELEMETRY_CODE_COVERAGE_STARTED, 'suite', { library: 'istanbul' })
|
|
97
|
+
}
|
|
75
98
|
this.enter(testSuiteSpan, store)
|
|
76
99
|
this._testSuites.set(testSuite, testSuiteSpan)
|
|
77
100
|
})
|
|
@@ -85,6 +108,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
85
108
|
span.setTag(TEST_STATUS, status)
|
|
86
109
|
}
|
|
87
110
|
span.finish()
|
|
111
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
|
|
88
112
|
}
|
|
89
113
|
})
|
|
90
114
|
|
|
@@ -113,6 +137,11 @@ class MochaPlugin extends CiPlugin {
|
|
|
113
137
|
span.setTag(TEST_STATUS, status)
|
|
114
138
|
|
|
115
139
|
span.finish()
|
|
140
|
+
this.telemetry.ciVisEvent(
|
|
141
|
+
TELEMETRY_EVENT_FINISHED,
|
|
142
|
+
'test',
|
|
143
|
+
{ hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
|
|
144
|
+
)
|
|
116
145
|
finishAllTraceSpans(span)
|
|
117
146
|
}
|
|
118
147
|
})
|
|
@@ -179,7 +208,9 @@ class MochaPlugin extends CiPlugin {
|
|
|
179
208
|
)
|
|
180
209
|
|
|
181
210
|
this.testModuleSpan.finish()
|
|
211
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
|
|
182
212
|
this.testSessionSpan.finish()
|
|
213
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
|
|
183
214
|
finishAllTraceSpans(this.testSessionSpan)
|
|
184
215
|
}
|
|
185
216
|
this.itrConfig = null
|
|
@@ -8,10 +8,15 @@ const {
|
|
|
8
8
|
finishAllTraceSpans,
|
|
9
9
|
getTestSuitePath,
|
|
10
10
|
getTestSuiteCommonTags,
|
|
11
|
-
TEST_SOURCE_START
|
|
11
|
+
TEST_SOURCE_START,
|
|
12
|
+
TEST_CODE_OWNERS
|
|
12
13
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
13
14
|
const { RESOURCE_NAME } = require('../../../ext/tags')
|
|
14
15
|
const { COMPONENT } = require('../../dd-trace/src/constants')
|
|
16
|
+
const {
|
|
17
|
+
TELEMETRY_EVENT_CREATED,
|
|
18
|
+
TELEMETRY_EVENT_FINISHED
|
|
19
|
+
} = require('../../dd-trace/src/ci-visibility/telemetry')
|
|
15
20
|
|
|
16
21
|
class PlaywrightPlugin extends CiPlugin {
|
|
17
22
|
static get id () {
|
|
@@ -28,7 +33,9 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
28
33
|
this.testSessionSpan.setTag(TEST_STATUS, status)
|
|
29
34
|
|
|
30
35
|
this.testModuleSpan.finish()
|
|
36
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
|
|
31
37
|
this.testSessionSpan.finish()
|
|
38
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'session')
|
|
32
39
|
finishAllTraceSpans(this.testSessionSpan)
|
|
33
40
|
this.tracer._exporter.flush(onDone)
|
|
34
41
|
})
|
|
@@ -52,6 +59,7 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
52
59
|
...testSuiteMetadata
|
|
53
60
|
}
|
|
54
61
|
})
|
|
62
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'suite')
|
|
55
63
|
this.enter(testSuiteSpan, store)
|
|
56
64
|
|
|
57
65
|
this._testSuites.set(testSuite, testSuiteSpan)
|
|
@@ -63,6 +71,7 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
63
71
|
if (!span) return
|
|
64
72
|
span.setTag(TEST_STATUS, status)
|
|
65
73
|
span.finish()
|
|
74
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
|
|
66
75
|
})
|
|
67
76
|
|
|
68
77
|
this.addSub('ci:playwright:test:start', ({ testName, testSuiteAbsolutePath, testSourceLine }) => {
|
|
@@ -104,6 +113,13 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
104
113
|
})
|
|
105
114
|
|
|
106
115
|
span.finish()
|
|
116
|
+
|
|
117
|
+
this.telemetry.ciVisEvent(
|
|
118
|
+
TELEMETRY_EVENT_FINISHED,
|
|
119
|
+
'test',
|
|
120
|
+
{ hasCodeOwners: !!span.context()._tags[TEST_CODE_OWNERS] }
|
|
121
|
+
)
|
|
122
|
+
|
|
107
123
|
finishAllTraceSpans(span)
|
|
108
124
|
})
|
|
109
125
|
}
|
|
@@ -10,5 +10,9 @@ module.exports = {
|
|
|
10
10
|
ASM_CUSTOM_RULES: 1n << 8n,
|
|
11
11
|
ASM_CUSTOM_BLOCKING_RESPONSE: 1n << 9n,
|
|
12
12
|
ASM_TRUSTED_IPS: 1n << 10n,
|
|
13
|
-
ASM_API_SECURITY_SAMPLE_RATE: 1n << 11n
|
|
13
|
+
ASM_API_SECURITY_SAMPLE_RATE: 1n << 11n,
|
|
14
|
+
APM_TRACING_SAMPLE_RATE: 1n << 12n,
|
|
15
|
+
APM_TRACING_LOGS_INJECTION: 1n << 13n,
|
|
16
|
+
APM_TRACING_HTTP_HEADER_TAGS: 1n << 14n,
|
|
17
|
+
APM_TRACING_CUSTOM_TAGS: 1n << 15n
|
|
14
18
|
}
|
|
@@ -10,6 +10,10 @@ let rc
|
|
|
10
10
|
|
|
11
11
|
function enable (config) {
|
|
12
12
|
rc = new RemoteConfigManager(config)
|
|
13
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_CUSTOM_TAGS, true)
|
|
14
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_HTTP_HEADER_TAGS, true)
|
|
15
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_LOGS_INJECTION, true)
|
|
16
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_SAMPLE_RATE, true)
|
|
13
17
|
|
|
14
18
|
const activation = Activation.fromConfig(config)
|
|
15
19
|
|
|
@@ -5,6 +5,16 @@ const { safeJSONStringify } = require('../../../exporters/common/util')
|
|
|
5
5
|
|
|
6
6
|
const { CoverageCIVisibilityEncoder } = require('../../../encode/coverage-ci-visibility')
|
|
7
7
|
const BaseWriter = require('../../../exporters/common/writer')
|
|
8
|
+
const {
|
|
9
|
+
incrementCountMetric,
|
|
10
|
+
distributionMetric,
|
|
11
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS,
|
|
12
|
+
TELEMETRY_ENDPOINT_PAYLOAD_BYTES,
|
|
13
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_MS,
|
|
14
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
|
|
15
|
+
TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
|
|
16
|
+
getErrorTypeFromStatusCode
|
|
17
|
+
} = require('../../../ci-visibility/telemetry')
|
|
8
18
|
|
|
9
19
|
class Writer extends BaseWriter {
|
|
10
20
|
constructor ({ url, evpProxyPrefix = '' }) {
|
|
@@ -34,8 +44,27 @@ class Writer extends BaseWriter {
|
|
|
34
44
|
|
|
35
45
|
log.debug(() => `Request to the intake: ${safeJSONStringify(options)}`)
|
|
36
46
|
|
|
37
|
-
|
|
47
|
+
const startRequestTime = Date.now()
|
|
48
|
+
|
|
49
|
+
incrementCountMetric(TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS, { endpoint: 'code_coverage' })
|
|
50
|
+
distributionMetric(TELEMETRY_ENDPOINT_PAYLOAD_BYTES, { endpoint: 'code_coverage' }, form.size())
|
|
51
|
+
|
|
52
|
+
request(form, options, (err, res, statusCode) => {
|
|
53
|
+
distributionMetric(
|
|
54
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_MS,
|
|
55
|
+
{ endpoint: 'code_coverage' },
|
|
56
|
+
Date.now() - startRequestTime
|
|
57
|
+
)
|
|
38
58
|
if (err) {
|
|
59
|
+
const errorType = getErrorTypeFromStatusCode(statusCode)
|
|
60
|
+
incrementCountMetric(
|
|
61
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
|
|
62
|
+
{ endpoint: 'code_coverage', errorType }
|
|
63
|
+
)
|
|
64
|
+
incrementCountMetric(
|
|
65
|
+
TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
|
|
66
|
+
{ endpoint: 'code_coverage' }
|
|
67
|
+
)
|
|
39
68
|
log.error(err)
|
|
40
69
|
done()
|
|
41
70
|
return
|
|
@@ -5,6 +5,16 @@ const log = require('../../../log')
|
|
|
5
5
|
|
|
6
6
|
const { AgentlessCiVisibilityEncoder } = require('../../../encode/agentless-ci-visibility')
|
|
7
7
|
const BaseWriter = require('../../../exporters/common/writer')
|
|
8
|
+
const {
|
|
9
|
+
incrementCountMetric,
|
|
10
|
+
distributionMetric,
|
|
11
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS,
|
|
12
|
+
TELEMETRY_ENDPOINT_PAYLOAD_BYTES,
|
|
13
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_MS,
|
|
14
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
|
|
15
|
+
TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
|
|
16
|
+
getErrorTypeFromStatusCode
|
|
17
|
+
} = require('../../../ci-visibility/telemetry')
|
|
8
18
|
|
|
9
19
|
class Writer extends BaseWriter {
|
|
10
20
|
constructor ({ url, tags, evpProxyPrefix = '' }) {
|
|
@@ -35,8 +45,27 @@ class Writer extends BaseWriter {
|
|
|
35
45
|
|
|
36
46
|
log.debug(() => `Request to the intake: ${safeJSONStringify(options)}`)
|
|
37
47
|
|
|
38
|
-
|
|
48
|
+
const startRequestTime = Date.now()
|
|
49
|
+
|
|
50
|
+
incrementCountMetric(TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS, { endpoint: 'test_cycle' })
|
|
51
|
+
distributionMetric(TELEMETRY_ENDPOINT_PAYLOAD_BYTES, { endpoint: 'test_cycle' }, data.length)
|
|
52
|
+
|
|
53
|
+
request(data, options, (err, res, statusCode) => {
|
|
54
|
+
distributionMetric(
|
|
55
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_MS,
|
|
56
|
+
{ endpoint: 'test_cycle' },
|
|
57
|
+
Date.now() - startRequestTime
|
|
58
|
+
)
|
|
39
59
|
if (err) {
|
|
60
|
+
const errorType = getErrorTypeFromStatusCode(statusCode)
|
|
61
|
+
incrementCountMetric(
|
|
62
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
|
|
63
|
+
{ endpoint: 'test_cycle', errorType }
|
|
64
|
+
)
|
|
65
|
+
incrementCountMetric(
|
|
66
|
+
TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
|
|
67
|
+
{ endpoint: 'test_cycle' }
|
|
68
|
+
)
|
|
40
69
|
log.error(err)
|
|
41
70
|
done()
|
|
42
71
|
return
|
|
@@ -15,6 +15,20 @@ const {
|
|
|
15
15
|
unshallowRepository
|
|
16
16
|
} = require('../../../plugins/util/git')
|
|
17
17
|
|
|
18
|
+
const {
|
|
19
|
+
incrementCountMetric,
|
|
20
|
+
distributionMetric,
|
|
21
|
+
TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS,
|
|
22
|
+
TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_MS,
|
|
23
|
+
TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_ERRORS,
|
|
24
|
+
TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_NUM,
|
|
25
|
+
TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES,
|
|
26
|
+
TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_MS,
|
|
27
|
+
TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_ERRORS,
|
|
28
|
+
TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_BYTES,
|
|
29
|
+
getErrorTypeFromStatusCode
|
|
30
|
+
} = require('../../../ci-visibility/telemetry')
|
|
31
|
+
|
|
18
32
|
const isValidSha1 = (sha) => /^[0-9a-f]{40}$/.test(sha)
|
|
19
33
|
const isValidSha256 = (sha) => /^[0-9a-f]{64}$/.test(sha)
|
|
20
34
|
|
|
@@ -74,8 +88,13 @@ function getCommitsToUpload ({ url, repositoryUrl, latestCommits, isEvpProxy },
|
|
|
74
88
|
}))
|
|
75
89
|
})
|
|
76
90
|
|
|
77
|
-
|
|
91
|
+
incrementCountMetric(TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS)
|
|
92
|
+
const startTime = Date.now()
|
|
93
|
+
request(localCommitData, options, (err, response, statusCode) => {
|
|
94
|
+
distributionMetric(TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_MS, {}, Date.now() - startTime)
|
|
78
95
|
if (err) {
|
|
96
|
+
const errorType = getErrorTypeFromStatusCode(statusCode)
|
|
97
|
+
incrementCountMetric(TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_ERRORS, { errorType })
|
|
79
98
|
const error = new Error(`Error fetching commits to exclude: ${err.message}`)
|
|
80
99
|
return callback(error)
|
|
81
100
|
}
|
|
@@ -83,6 +102,7 @@ function getCommitsToUpload ({ url, repositoryUrl, latestCommits, isEvpProxy },
|
|
|
83
102
|
try {
|
|
84
103
|
alreadySeenCommits = validateCommits(JSON.parse(response).data)
|
|
85
104
|
} catch (e) {
|
|
105
|
+
incrementCountMetric(TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_ERRORS, { errorType: 'network' })
|
|
86
106
|
return callback(new Error(`Can't parse commits to exclude response: ${e.message}`))
|
|
87
107
|
}
|
|
88
108
|
log.debug(`There are ${alreadySeenCommits.length} commits to exclude.`)
|
|
@@ -147,12 +167,20 @@ function uploadPackFile ({ url, isEvpProxy, packFileToUpload, repositoryUrl, hea
|
|
|
147
167
|
delete options.headers['dd-api-key']
|
|
148
168
|
}
|
|
149
169
|
|
|
170
|
+
incrementCountMetric(TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES)
|
|
171
|
+
|
|
172
|
+
const uploadSize = form.size()
|
|
173
|
+
|
|
174
|
+
const startTime = Date.now()
|
|
150
175
|
request(form, options, (err, _, statusCode) => {
|
|
176
|
+
distributionMetric(TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_MS, {}, Date.now() - startTime)
|
|
151
177
|
if (err) {
|
|
178
|
+
const errorType = getErrorTypeFromStatusCode(statusCode)
|
|
179
|
+
incrementCountMetric(TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_ERRORS, { errorType })
|
|
152
180
|
const error = new Error(`Could not upload packfiles: status code ${statusCode}: ${err.message}`)
|
|
153
|
-
return callback(error)
|
|
181
|
+
return callback(error, uploadSize)
|
|
154
182
|
}
|
|
155
|
-
callback(null)
|
|
183
|
+
callback(null, uploadSize)
|
|
156
184
|
})
|
|
157
185
|
}
|
|
158
186
|
|
|
@@ -173,10 +201,14 @@ function generateAndUploadPackFiles ({
|
|
|
173
201
|
return callback(new Error('Failed to generate packfiles'))
|
|
174
202
|
}
|
|
175
203
|
|
|
204
|
+
distributionMetric(TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_NUM, {}, packFilesToUpload.length)
|
|
176
205
|
let packFileIndex = 0
|
|
206
|
+
let totalUploadedBytes = 0
|
|
177
207
|
// This uploads packfiles sequentially
|
|
178
|
-
const uploadPackFileCallback = (err) => {
|
|
208
|
+
const uploadPackFileCallback = (err, byteLength) => {
|
|
209
|
+
totalUploadedBytes += byteLength
|
|
179
210
|
if (err || packFileIndex === packFilesToUpload.length) {
|
|
211
|
+
distributionMetric(TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_BYTES, {}, totalUploadedBytes)
|
|
180
212
|
return callback(err)
|
|
181
213
|
}
|
|
182
214
|
return uploadPackFile(
|
package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
const request = require('../../exporters/common/request')
|
|
2
2
|
const id = require('../../id')
|
|
3
3
|
const log = require('../../log')
|
|
4
|
+
const {
|
|
5
|
+
incrementCountMetric,
|
|
6
|
+
distributionMetric,
|
|
7
|
+
TELEMETRY_GIT_REQUESTS_SETTINGS,
|
|
8
|
+
TELEMETRY_GIT_REQUESTS_SETTINGS_MS,
|
|
9
|
+
TELEMETRY_GIT_REQUESTS_SETTINGS_ERRORS,
|
|
10
|
+
TELEMETRY_GIT_REQUESTS_SETTINGS_RESPONSE,
|
|
11
|
+
getErrorTypeFromStatusCode
|
|
12
|
+
} = require('../../ci-visibility/telemetry')
|
|
4
13
|
|
|
5
14
|
function getItrConfiguration ({
|
|
6
15
|
url,
|
|
@@ -62,8 +71,14 @@ function getItrConfiguration ({
|
|
|
62
71
|
}
|
|
63
72
|
})
|
|
64
73
|
|
|
65
|
-
|
|
74
|
+
incrementCountMetric(TELEMETRY_GIT_REQUESTS_SETTINGS)
|
|
75
|
+
|
|
76
|
+
const startTime = Date.now()
|
|
77
|
+
request(data, options, (err, res, statusCode) => {
|
|
78
|
+
distributionMetric(TELEMETRY_GIT_REQUESTS_SETTINGS_MS, {}, Date.now() - startTime)
|
|
66
79
|
if (err) {
|
|
80
|
+
const errorType = getErrorTypeFromStatusCode(statusCode)
|
|
81
|
+
incrementCountMetric(TELEMETRY_GIT_REQUESTS_SETTINGS_ERRORS, { errorType })
|
|
67
82
|
done(err)
|
|
68
83
|
} else {
|
|
69
84
|
try {
|
|
@@ -91,6 +106,8 @@ function getItrConfiguration ({
|
|
|
91
106
|
log.debug(() => 'Dangerously set test skipping to true')
|
|
92
107
|
}
|
|
93
108
|
|
|
109
|
+
incrementCountMetric(TELEMETRY_GIT_REQUESTS_SETTINGS_RESPONSE, settings)
|
|
110
|
+
|
|
94
111
|
done(null, settings)
|
|
95
112
|
} catch (err) {
|
|
96
113
|
done(err)
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
const request = require('../../exporters/common/request')
|
|
2
2
|
const log = require('../../log')
|
|
3
|
+
const {
|
|
4
|
+
incrementCountMetric,
|
|
5
|
+
distributionMetric,
|
|
6
|
+
TELEMETRY_ITR_SKIPPABLE_TESTS,
|
|
7
|
+
TELEMETRY_ITR_SKIPPABLE_TESTS_MS,
|
|
8
|
+
TELEMETRY_ITR_SKIPPABLE_TESTS_ERRORS,
|
|
9
|
+
TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_SUITES,
|
|
10
|
+
TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS,
|
|
11
|
+
TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES,
|
|
12
|
+
getErrorTypeFromStatusCode
|
|
13
|
+
} = require('../../ci-visibility/telemetry')
|
|
3
14
|
|
|
4
15
|
function getSkippableSuites ({
|
|
5
16
|
url,
|
|
@@ -59,8 +70,15 @@ function getSkippableSuites ({
|
|
|
59
70
|
}
|
|
60
71
|
})
|
|
61
72
|
|
|
62
|
-
|
|
73
|
+
incrementCountMetric(TELEMETRY_ITR_SKIPPABLE_TESTS)
|
|
74
|
+
|
|
75
|
+
const startTime = Date.now()
|
|
76
|
+
|
|
77
|
+
request(data, options, (err, res, statusCode) => {
|
|
78
|
+
distributionMetric(TELEMETRY_ITR_SKIPPABLE_TESTS_MS, {}, Date.now() - startTime)
|
|
63
79
|
if (err) {
|
|
80
|
+
const errorType = getErrorTypeFromStatusCode(statusCode)
|
|
81
|
+
incrementCountMetric(TELEMETRY_ITR_SKIPPABLE_TESTS_ERRORS, { errorType })
|
|
64
82
|
done(err)
|
|
65
83
|
} else {
|
|
66
84
|
let skippableSuites = []
|
|
@@ -74,6 +92,13 @@ function getSkippableSuites ({
|
|
|
74
92
|
}
|
|
75
93
|
return { suite, name }
|
|
76
94
|
})
|
|
95
|
+
incrementCountMetric(
|
|
96
|
+
testLevel === 'test'
|
|
97
|
+
? TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS : TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_SUITES,
|
|
98
|
+
{},
|
|
99
|
+
skippableSuites.length
|
|
100
|
+
)
|
|
101
|
+
distributionMetric(TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES, {}, res.length)
|
|
77
102
|
log.debug(() => `Number of received skippable ${testLevel}s: ${skippableSuites.length}`)
|
|
78
103
|
done(null, skippableSuites)
|
|
79
104
|
} catch (err) {
|