dd-trace 4.18.0 → 4.23.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.
Files changed (137) hide show
  1. package/LICENSE-3rdparty.csv +3 -2
  2. package/README.md +3 -3
  3. package/ext/kinds.d.ts +1 -0
  4. package/ext/kinds.js +2 -1
  5. package/ext/tags.d.ts +2 -1
  6. package/ext/tags.js +6 -1
  7. package/index.d.ts +29 -0
  8. package/package.json +12 -11
  9. package/packages/datadog-core/src/storage/async_resource.js +1 -1
  10. package/packages/datadog-esbuild/index.js +1 -20
  11. package/packages/datadog-instrumentations/src/aerospike.js +47 -0
  12. package/packages/datadog-instrumentations/src/apollo-server-core.js +41 -0
  13. package/packages/datadog-instrumentations/src/apollo-server.js +83 -0
  14. package/packages/datadog-instrumentations/src/child-process.js +4 -5
  15. package/packages/datadog-instrumentations/src/couchbase.js +5 -4
  16. package/packages/datadog-instrumentations/src/crypto.js +2 -1
  17. package/packages/datadog-instrumentations/src/dns.js +2 -1
  18. package/packages/datadog-instrumentations/src/graphql.js +18 -4
  19. package/packages/datadog-instrumentations/src/helpers/bundler-register.js +1 -2
  20. package/packages/datadog-instrumentations/src/helpers/hooks.js +10 -2
  21. package/packages/datadog-instrumentations/src/helpers/instrument.js +9 -4
  22. package/packages/datadog-instrumentations/src/helpers/register.js +19 -3
  23. package/packages/datadog-instrumentations/src/http/client.js +12 -2
  24. package/packages/datadog-instrumentations/src/http/server.js +7 -4
  25. package/packages/datadog-instrumentations/src/http2/client.js +3 -1
  26. package/packages/datadog-instrumentations/src/http2/server.js +3 -1
  27. package/packages/datadog-instrumentations/src/jest.js +12 -6
  28. package/packages/datadog-instrumentations/src/kafkajs.js +27 -0
  29. package/packages/datadog-instrumentations/src/net.js +10 -2
  30. package/packages/datadog-instrumentations/src/next.js +18 -6
  31. package/packages/datadog-instrumentations/src/restify.js +14 -1
  32. package/packages/datadog-instrumentations/src/rhea.js +15 -9
  33. package/packages/datadog-plugin-aerospike/src/index.js +113 -0
  34. package/packages/datadog-plugin-cucumber/src/index.js +34 -2
  35. package/packages/datadog-plugin-cypress/src/plugin.js +60 -8
  36. package/packages/datadog-plugin-graphql/src/resolve.js +26 -18
  37. package/packages/datadog-plugin-http/src/client.js +19 -2
  38. package/packages/datadog-plugin-jest/src/index.js +38 -4
  39. package/packages/datadog-plugin-kafkajs/src/consumer.js +59 -6
  40. package/packages/datadog-plugin-kafkajs/src/producer.js +64 -6
  41. package/packages/datadog-plugin-mocha/src/index.js +32 -1
  42. package/packages/datadog-plugin-next/src/index.js +40 -14
  43. package/packages/datadog-plugin-playwright/src/index.js +17 -1
  44. package/packages/dd-trace/src/appsec/activation.js +29 -0
  45. package/packages/dd-trace/src/appsec/addresses.js +3 -1
  46. package/packages/dd-trace/src/appsec/api_security_sampler.js +48 -0
  47. package/packages/dd-trace/src/appsec/blocked_templates.js +4 -1
  48. package/packages/dd-trace/src/appsec/blocking.js +95 -43
  49. package/packages/dd-trace/src/appsec/channels.js +5 -2
  50. package/packages/dd-trace/src/appsec/graphql.js +146 -0
  51. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
  52. package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +105 -0
  53. package/packages/dd-trace/src/appsec/iast/iast-log.js +1 -1
  54. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +1 -1
  55. package/packages/dd-trace/src/appsec/iast/index.js +1 -1
  56. package/packages/dd-trace/src/appsec/iast/path-line.js +1 -1
  57. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +1 -1
  58. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/constants.js +7 -0
  59. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +12 -19
  60. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/header-sensitive-analyzer.js +20 -0
  61. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/json-sensitive-analyzer.js +6 -10
  62. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +18 -25
  63. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +79 -85
  64. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +27 -36
  65. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +14 -11
  66. package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
  67. package/packages/dd-trace/src/appsec/index.js +33 -32
  68. package/packages/dd-trace/src/appsec/recommended.json +1737 -120
  69. package/packages/dd-trace/src/appsec/remote_config/capabilities.js +6 -1
  70. package/packages/dd-trace/src/appsec/remote_config/index.js +40 -15
  71. package/packages/dd-trace/src/appsec/reporter.js +50 -34
  72. package/packages/dd-trace/src/appsec/rule_manager.js +9 -6
  73. package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -1
  74. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +28 -13
  75. package/packages/dd-trace/src/appsec/waf/waf_manager.js +0 -1
  76. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +30 -1
  77. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +30 -1
  78. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +17 -1
  79. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +110 -59
  80. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +40 -7
  81. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +26 -1
  82. package/packages/dd-trace/src/ci-visibility/telemetry.js +130 -0
  83. package/packages/dd-trace/src/config.js +145 -63
  84. package/packages/dd-trace/src/datastreams/processor.js +166 -26
  85. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +14 -1
  86. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +14 -0
  87. package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +4 -0
  88. package/packages/dd-trace/src/exporters/common/form-data.js +4 -0
  89. package/packages/dd-trace/src/format.js +6 -1
  90. package/packages/dd-trace/src/id.js +12 -0
  91. package/packages/dd-trace/src/iitm.js +1 -1
  92. package/packages/dd-trace/src/log/channels.js +1 -1
  93. package/packages/dd-trace/src/noop/proxy.js +4 -0
  94. package/packages/dd-trace/src/opentelemetry/span.js +95 -2
  95. package/packages/dd-trace/src/opentelemetry/tracer.js +9 -10
  96. package/packages/dd-trace/src/opentracing/propagation/text_map.js +14 -5
  97. package/packages/dd-trace/src/opentracing/span.js +6 -0
  98. package/packages/dd-trace/src/opentracing/span_context.js +5 -2
  99. package/packages/dd-trace/src/opentracing/tracer.js +2 -2
  100. package/packages/dd-trace/src/plugin_manager.js +1 -1
  101. package/packages/dd-trace/src/plugins/ci_plugin.js +46 -9
  102. package/packages/dd-trace/src/plugins/database.js +1 -1
  103. package/packages/dd-trace/src/plugins/index.js +6 -0
  104. package/packages/dd-trace/src/plugins/plugin.js +1 -1
  105. package/packages/dd-trace/src/plugins/util/ci.js +6 -19
  106. package/packages/dd-trace/src/plugins/util/exec.js +23 -2
  107. package/packages/dd-trace/src/plugins/util/git.js +98 -22
  108. package/packages/dd-trace/src/plugins/util/ip_extractor.js +7 -6
  109. package/packages/dd-trace/src/plugins/util/test.js +3 -2
  110. package/packages/dd-trace/src/plugins/util/url.js +26 -0
  111. package/packages/dd-trace/src/plugins/util/user-provided-git.js +4 -16
  112. package/packages/dd-trace/src/priority_sampler.js +30 -38
  113. package/packages/dd-trace/src/profiler.js +5 -3
  114. package/packages/dd-trace/src/profiling/config.js +26 -2
  115. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -0
  116. package/packages/dd-trace/src/profiling/profiler.js +17 -10
  117. package/packages/dd-trace/src/profiling/profilers/events.js +264 -0
  118. package/packages/dd-trace/src/profiling/profilers/shared.js +39 -0
  119. package/packages/dd-trace/src/profiling/profilers/space.js +2 -1
  120. package/packages/dd-trace/src/profiling/profilers/wall.js +121 -58
  121. package/packages/dd-trace/src/proxy.js +25 -1
  122. package/packages/dd-trace/src/ritm.js +1 -1
  123. package/packages/dd-trace/src/sampling_rule.js +130 -0
  124. package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +5 -0
  125. package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +4 -0
  126. package/packages/dd-trace/src/span_processor.js +4 -0
  127. package/packages/dd-trace/src/span_sampler.js +6 -64
  128. package/packages/dd-trace/src/spanleak.js +98 -0
  129. package/packages/dd-trace/src/startup-log.js +7 -1
  130. package/packages/dd-trace/src/telemetry/dependencies.js +56 -10
  131. package/packages/dd-trace/src/telemetry/index.js +171 -41
  132. package/packages/dd-trace/src/telemetry/logs/index.js +2 -2
  133. package/packages/dd-trace/src/telemetry/send-data.js +47 -5
  134. package/packages/dd-trace/src/tracer.js +8 -2
  135. package/scripts/install_plugin_modules.js +11 -3
  136. package/packages/diagnostics_channel/index.js +0 -3
  137. package/packages/diagnostics_channel/src/index.js +0 -121
@@ -10,11 +10,25 @@ const {
10
10
  getLatestCommits,
11
11
  getRepositoryUrl,
12
12
  generatePackFilesForCommits,
13
- getCommitsToUpload,
13
+ getCommitsRevList,
14
14
  isShallowRepository,
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
 
@@ -46,11 +60,7 @@ function getCommonRequestOptions (url) {
46
60
  * The response are the commits for which the backend already has information
47
61
  * This response is used to know which commits can be ignored from there on
48
62
  */
49
- function getCommitsToExclude ({ url, isEvpProxy, repositoryUrl }, callback) {
50
- const latestCommits = getLatestCommits()
51
-
52
- log.debug(`There were ${latestCommits.length} commits since last month.`)
53
-
63
+ function getCommitsToUpload ({ url, repositoryUrl, latestCommits, isEvpProxy }, callback) {
54
64
  const commonOptions = getCommonRequestOptions(url)
55
65
 
56
66
  const options = {
@@ -78,18 +88,34 @@ function getCommitsToExclude ({ url, isEvpProxy, repositoryUrl }, callback) {
78
88
  }))
79
89
  })
80
90
 
81
- request(localCommitData, options, (err, response) => {
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)
82
95
  if (err) {
96
+ const errorType = getErrorTypeFromStatusCode(statusCode)
97
+ incrementCountMetric(TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_ERRORS, { errorType })
83
98
  const error = new Error(`Error fetching commits to exclude: ${err.message}`)
84
99
  return callback(error)
85
100
  }
86
- let commitsToExclude
101
+ let alreadySeenCommits
87
102
  try {
88
- commitsToExclude = validateCommits(JSON.parse(response).data)
103
+ alreadySeenCommits = validateCommits(JSON.parse(response).data)
89
104
  } catch (e) {
105
+ incrementCountMetric(TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_ERRORS, { errorType: 'network' })
90
106
  return callback(new Error(`Can't parse commits to exclude response: ${e.message}`))
91
107
  }
92
- callback(null, commitsToExclude, latestCommits)
108
+ log.debug(`There are ${alreadySeenCommits.length} commits to exclude.`)
109
+ const commitsToInclude = latestCommits.filter((commit) => !alreadySeenCommits.includes(commit))
110
+ log.debug(`There are ${commitsToInclude.length} commits to include.`)
111
+
112
+ if (!commitsToInclude.length) {
113
+ return callback(null, [])
114
+ }
115
+
116
+ const commitsToUpload = getCommitsRevList(alreadySeenCommits, commitsToInclude)
117
+
118
+ callback(null, commitsToUpload)
93
119
  })
94
120
  }
95
121
 
@@ -141,15 +167,74 @@ function uploadPackFile ({ url, isEvpProxy, packFileToUpload, repositoryUrl, hea
141
167
  delete options.headers['dd-api-key']
142
168
  }
143
169
 
170
+ incrementCountMetric(TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES)
171
+
172
+ const uploadSize = form.size()
173
+
174
+ const startTime = Date.now()
144
175
  request(form, options, (err, _, statusCode) => {
176
+ distributionMetric(TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_MS, {}, Date.now() - startTime)
145
177
  if (err) {
178
+ const errorType = getErrorTypeFromStatusCode(statusCode)
179
+ incrementCountMetric(TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_ERRORS, { errorType })
146
180
  const error = new Error(`Could not upload packfiles: status code ${statusCode}: ${err.message}`)
147
- return callback(error)
181
+ return callback(error, uploadSize)
148
182
  }
149
- callback(null)
183
+ callback(null, uploadSize)
150
184
  })
151
185
  }
152
186
 
187
+ function generateAndUploadPackFiles ({
188
+ url,
189
+ isEvpProxy,
190
+ commitsToUpload,
191
+ repositoryUrl,
192
+ headCommit
193
+ }, callback) {
194
+ log.debug(`There are ${commitsToUpload.length} commits to upload`)
195
+
196
+ const packFilesToUpload = generatePackFilesForCommits(commitsToUpload)
197
+
198
+ log.debug(`Uploading ${packFilesToUpload.length} packfiles.`)
199
+
200
+ if (!packFilesToUpload.length) {
201
+ return callback(new Error('Failed to generate packfiles'))
202
+ }
203
+
204
+ distributionMetric(TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_NUM, {}, packFilesToUpload.length)
205
+ let packFileIndex = 0
206
+ let totalUploadedBytes = 0
207
+ // This uploads packfiles sequentially
208
+ const uploadPackFileCallback = (err, byteLength) => {
209
+ totalUploadedBytes += byteLength
210
+ if (err || packFileIndex === packFilesToUpload.length) {
211
+ distributionMetric(TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_BYTES, {}, totalUploadedBytes)
212
+ return callback(err)
213
+ }
214
+ return uploadPackFile(
215
+ {
216
+ packFileToUpload: packFilesToUpload[packFileIndex++],
217
+ url,
218
+ isEvpProxy,
219
+ repositoryUrl,
220
+ headCommit
221
+ },
222
+ uploadPackFileCallback
223
+ )
224
+ }
225
+
226
+ uploadPackFile(
227
+ {
228
+ packFileToUpload: packFilesToUpload[packFileIndex++],
229
+ url,
230
+ isEvpProxy,
231
+ repositoryUrl,
232
+ headCommit
233
+ },
234
+ uploadPackFileCallback
235
+ )
236
+ }
237
+
153
238
  /**
154
239
  * This function uploads git metadata to CI Visibility's backend.
155
240
  */
@@ -165,65 +250,31 @@ function sendGitMetadata (url, isEvpProxy, configRepositoryUrl, callback) {
165
250
  return callback(new Error('Repository URL is empty'))
166
251
  }
167
252
 
168
- if (isShallowRepository()) {
169
- log.debug('It is shallow clone, unshallowing...')
170
- unshallowRepository()
171
- }
253
+ const latestCommits = getLatestCommits()
254
+ log.debug(`There were ${latestCommits.length} commits since last month.`)
255
+ const [headCommit] = latestCommits
172
256
 
173
- getCommitsToExclude({ url, repositoryUrl, isEvpProxy }, (err, commitsToExclude, latestCommits) => {
257
+ const getOnFinishGetCommitsToUpload = (hasCheckedShallow) => (err, commitsToUpload) => {
174
258
  if (err) {
175
259
  return callback(err)
176
260
  }
177
- log.debug(`There are ${commitsToExclude.length} commits to exclude.`)
178
- const [headCommit] = latestCommits
179
- const commitsToInclude = latestCommits.filter((commit) => !commitsToExclude.includes(commit))
180
- log.debug(`There are ${commitsToInclude.length} commits to include.`)
181
-
182
- const commitsToUpload = getCommitsToUpload(commitsToExclude, commitsToInclude)
183
261
 
184
262
  if (!commitsToUpload.length) {
185
263
  log.debug('No commits to upload')
186
264
  return callback(null)
187
265
  }
188
- log.debug(`There are ${commitsToUpload.length} commits to upload`)
189
266
 
190
- const packFilesToUpload = generatePackFilesForCommits(commitsToUpload)
191
-
192
- log.debug(`Uploading ${packFilesToUpload.length} packfiles.`)
193
-
194
- if (!packFilesToUpload.length) {
195
- return callback(new Error('Failed to generate packfiles'))
196
- }
197
-
198
- let packFileIndex = 0
199
- // This uploads packfiles sequentially
200
- const uploadPackFileCallback = (err) => {
201
- if (err || packFileIndex === packFilesToUpload.length) {
202
- return callback(err)
203
- }
204
- return uploadPackFile(
205
- {
206
- packFileToUpload: packFilesToUpload[packFileIndex++],
207
- url,
208
- isEvpProxy,
209
- repositoryUrl,
210
- headCommit
211
- },
212
- uploadPackFileCallback
213
- )
267
+ // If it has already unshallowed or the clone is not shallow, we move on
268
+ if (hasCheckedShallow || !isShallowRepository()) {
269
+ return generateAndUploadPackFiles({ url, isEvpProxy, commitsToUpload, repositoryUrl, headCommit }, callback)
214
270
  }
271
+ // Otherwise we unshallow and get commits to upload again
272
+ log.debug('It is shallow clone, unshallowing...')
273
+ unshallowRepository()
274
+ getCommitsToUpload({ url, repositoryUrl, latestCommits, isEvpProxy }, getOnFinishGetCommitsToUpload(true))
275
+ }
215
276
 
216
- uploadPackFile(
217
- {
218
- packFileToUpload: packFilesToUpload[packFileIndex++],
219
- url,
220
- isEvpProxy,
221
- repositoryUrl,
222
- headCommit
223
- },
224
- uploadPackFileCallback
225
- )
226
- })
277
+ getCommitsToUpload({ url, repositoryUrl, latestCommits, isEvpProxy }, getOnFinishGetCommitsToUpload(false))
227
278
  }
228
279
 
229
280
  module.exports = {
@@ -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,
@@ -15,6 +24,7 @@ function getItrConfiguration ({
15
24
  runtimeName,
16
25
  runtimeVersion,
17
26
  branch,
27
+ testLevel = 'suite',
18
28
  custom
19
29
  }, done) {
20
30
  const options = {
@@ -23,7 +33,8 @@ function getItrConfiguration ({
23
33
  headers: {
24
34
  'Content-Type': 'application/json'
25
35
  },
26
- url
36
+ url,
37
+ timeout: 20000
27
38
  }
28
39
 
29
40
  if (isEvpProxy) {
@@ -42,7 +53,7 @@ function getItrConfiguration ({
42
53
  id: id().toString(10),
43
54
  type: 'ci_app_test_service_libraries_settings',
44
55
  attributes: {
45
- test_level: 'suite',
56
+ test_level: testLevel,
46
57
  configurations: {
47
58
  'os.platform': osPlatform,
48
59
  'os.version': osVersion,
@@ -60,8 +71,14 @@ function getItrConfiguration ({
60
71
  }
61
72
  })
62
73
 
63
- request(data, options, (err, res) => {
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)
64
79
  if (err) {
80
+ const errorType = getErrorTypeFromStatusCode(statusCode)
81
+ incrementCountMetric(TELEMETRY_GIT_REQUESTS_SETTINGS_ERRORS, { errorType })
65
82
  done(err)
66
83
  } else {
67
84
  try {
@@ -69,13 +86,29 @@ function getItrConfiguration ({
69
86
  data: {
70
87
  attributes: {
71
88
  code_coverage: isCodeCoverageEnabled,
72
- tests_skipping: isSuitesSkippingEnabled
89
+ tests_skipping: isSuitesSkippingEnabled,
90
+ itr_enabled: isItrEnabled,
91
+ require_git: requireGit
73
92
  }
74
93
  }
75
94
  } = JSON.parse(res)
76
- const config = { isCodeCoverageEnabled, isSuitesSkippingEnabled }
77
- log.debug(() => `Received settings: ${config}`)
78
- done(null, config)
95
+
96
+ const settings = { isCodeCoverageEnabled, isSuitesSkippingEnabled, isItrEnabled, requireGit }
97
+
98
+ log.debug(() => `Remote settings: ${JSON.stringify(settings)}`)
99
+
100
+ if (process.env.DD_CIVISIBILITY_DANGEROUSLY_FORCE_COVERAGE) {
101
+ settings.isCodeCoverageEnabled = true
102
+ log.debug(() => 'Dangerously set code coverage to true')
103
+ }
104
+ if (process.env.DD_CIVISIBILITY_DANGEROUSLY_FORCE_TEST_SKIPPING) {
105
+ settings.isSuitesSkippingEnabled = true
106
+ log.debug(() => 'Dangerously set test skipping to true')
107
+ }
108
+
109
+ incrementCountMetric(TELEMETRY_GIT_REQUESTS_SETTINGS_RESPONSE, settings)
110
+
111
+ done(null, settings)
79
112
  } catch (err) {
80
113
  done(err)
81
114
  }
@@ -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
- request(data, options, (err, res) => {
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) {
@@ -0,0 +1,130 @@
1
+ const telemetryMetrics = require('../telemetry/metrics')
2
+
3
+ const ciVisibilityMetrics = telemetryMetrics.manager.namespace('civisibility')
4
+
5
+ const formattedTags = {
6
+ testLevel: 'event_type',
7
+ testFramework: 'test_framework',
8
+ errorType: 'error_type',
9
+ exitCode: 'exit_code',
10
+ isCodeCoverageEnabled: 'coverage_enabled',
11
+ isSuitesSkippingEnabled: 'itrskip_enabled',
12
+ hasCodeOwners: 'has_code_owners',
13
+ isUnsupportedCIProvider: 'is_unsupported_ci'
14
+ }
15
+
16
+ // Transform tags dictionary to array of strings.
17
+ // If tag value is true, then only tag key is added to the array.
18
+ function formatMetricTags (tagsDictionary) {
19
+ return Object.keys(tagsDictionary).reduce((acc, tagKey) => {
20
+ const formattedTagKey = formattedTags[tagKey] || tagKey
21
+ if (tagsDictionary[tagKey] === true) {
22
+ acc.push(formattedTagKey)
23
+ } else if (tagsDictionary[tagKey] !== undefined && tagsDictionary[tagKey] !== null) {
24
+ acc.push(`${formattedTagKey}:${tagsDictionary[tagKey]}`)
25
+ }
26
+ return acc
27
+ }, [])
28
+ }
29
+
30
+ function incrementCountMetric (name, tags = {}, value = 1) {
31
+ ciVisibilityMetrics.count(name, formatMetricTags(tags)).inc(value)
32
+ }
33
+
34
+ function distributionMetric (name, tags, measure) {
35
+ ciVisibilityMetrics.distribution(name, formatMetricTags(tags)).track(measure)
36
+ }
37
+
38
+ // CI Visibility telemetry events
39
+ const TELEMETRY_EVENT_CREATED = 'event_created'
40
+ const TELEMETRY_EVENT_FINISHED = 'event_finished'
41
+ const TELEMETRY_CODE_COVERAGE_STARTED = 'code_coverage_started'
42
+ const TELEMETRY_CODE_COVERAGE_FINISHED = 'code_coverage_finished'
43
+ const TELEMETRY_ITR_SKIPPED = 'itr_skipped'
44
+ const TELEMETRY_ITR_UNSKIPPABLE = 'itr_unskippable'
45
+ const TELEMETRY_ITR_FORCED_TO_RUN = 'itr_forced_run'
46
+ const TELEMETRY_CODE_COVERAGE_EMPTY = 'code_coverage.is_empty'
47
+ const TELEMETRY_CODE_COVERAGE_NUM_FILES = 'code_coverage.files'
48
+ const TELEMETRY_EVENTS_ENQUEUED_FOR_SERIALIZATION = 'events_enqueued_for_serialization'
49
+ const TELEMETRY_ENDPOINT_PAYLOAD_SERIALIZATION_MS = 'endpoint_payload.events_serialization_ms'
50
+ const TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS = 'endpoint_payload.requests'
51
+ const TELEMETRY_ENDPOINT_PAYLOAD_BYTES = 'endpoint_payload.bytes'
52
+ const TELEMETRY_ENDPOINT_PAYLOAD_EVENTS_COUNT = 'endpoint_payload.events_count'
53
+ const TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_MS = 'endpoint_payload.requests_ms'
54
+ const TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS = 'endpoint_payload.requests_errors'
55
+ const TELEMETRY_ENDPOINT_PAYLOAD_DROPPED = 'endpoint_payload.dropped'
56
+ const TELEMETRY_GIT_COMMAND = 'git.command'
57
+ const TELEMETRY_GIT_COMMAND_MS = 'git.command_ms'
58
+ const TELEMETRY_GIT_COMMAND_ERRORS = 'git.command_errors'
59
+ const TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS = 'git_requests.search_commits'
60
+ const TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_MS = 'git_requests.search_commits_ms'
61
+ const TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_ERRORS = 'git_requests.search_commits_errors'
62
+ const TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES = 'git_requests.objects_pack'
63
+ const TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_MS = 'git_requests.objects_pack_ms'
64
+ const TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_ERRORS = 'git_requests.objects_pack_errors'
65
+ const TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_NUM = 'git_requests.objects_pack_files'
66
+ const TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_BYTES = 'git_requests.objects_pack_bytes'
67
+ const TELEMETRY_GIT_REQUESTS_SETTINGS = 'git_requests.settings'
68
+ const TELEMETRY_GIT_REQUESTS_SETTINGS_MS = 'git_requests.settings_ms'
69
+ const TELEMETRY_GIT_REQUESTS_SETTINGS_ERRORS = 'git_requests.settings_errors'
70
+ const TELEMETRY_GIT_REQUESTS_SETTINGS_RESPONSE = 'git_requests.settings_response'
71
+ const TELEMETRY_ITR_SKIPPABLE_TESTS = 'itr_skippable_tests.request'
72
+ const TELEMETRY_ITR_SKIPPABLE_TESTS_MS = 'itr_skippable_tests.request_ms'
73
+ const TELEMETRY_ITR_SKIPPABLE_TESTS_ERRORS = 'itr_skippable_tests.request_errors'
74
+ const TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_SUITES = 'itr_skippable_tests.response_suites'
75
+ const TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS = 'itr_skippable_tests.response_tests'
76
+ const TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES = 'itr_skippable_tests.response_bytes'
77
+
78
+ function getErrorTypeFromStatusCode (statusCode) {
79
+ if (statusCode >= 400 && statusCode < 500) {
80
+ return 'status_code_4xx_response'
81
+ }
82
+ if (statusCode >= 500) {
83
+ return 'status_code_5xx_response'
84
+ }
85
+ return 'network'
86
+ }
87
+
88
+ module.exports = {
89
+ incrementCountMetric,
90
+ distributionMetric,
91
+ TELEMETRY_EVENT_CREATED,
92
+ TELEMETRY_EVENT_FINISHED,
93
+ TELEMETRY_CODE_COVERAGE_STARTED,
94
+ TELEMETRY_CODE_COVERAGE_FINISHED,
95
+ TELEMETRY_ITR_SKIPPED,
96
+ TELEMETRY_ITR_UNSKIPPABLE,
97
+ TELEMETRY_ITR_FORCED_TO_RUN,
98
+ TELEMETRY_CODE_COVERAGE_EMPTY,
99
+ TELEMETRY_CODE_COVERAGE_NUM_FILES,
100
+ TELEMETRY_EVENTS_ENQUEUED_FOR_SERIALIZATION,
101
+ TELEMETRY_ENDPOINT_PAYLOAD_SERIALIZATION_MS,
102
+ TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS,
103
+ TELEMETRY_ENDPOINT_PAYLOAD_BYTES,
104
+ TELEMETRY_ENDPOINT_PAYLOAD_EVENTS_COUNT,
105
+ TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_MS,
106
+ TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
107
+ TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
108
+ TELEMETRY_GIT_COMMAND,
109
+ TELEMETRY_GIT_COMMAND_MS,
110
+ TELEMETRY_GIT_COMMAND_ERRORS,
111
+ TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS,
112
+ TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_MS,
113
+ TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_ERRORS,
114
+ TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_NUM,
115
+ TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_BYTES,
116
+ TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES,
117
+ TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_MS,
118
+ TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_ERRORS,
119
+ TELEMETRY_GIT_REQUESTS_SETTINGS,
120
+ TELEMETRY_GIT_REQUESTS_SETTINGS_MS,
121
+ TELEMETRY_GIT_REQUESTS_SETTINGS_ERRORS,
122
+ TELEMETRY_GIT_REQUESTS_SETTINGS_RESPONSE,
123
+ TELEMETRY_ITR_SKIPPABLE_TESTS,
124
+ TELEMETRY_ITR_SKIPPABLE_TESTS_MS,
125
+ TELEMETRY_ITR_SKIPPABLE_TESTS_ERRORS,
126
+ TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_SUITES,
127
+ TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS,
128
+ TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES,
129
+ getErrorTypeFromStatusCode
130
+ }