dd-trace 4.44.0 → 4.46.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 (108) hide show
  1. package/index.d.ts +2 -1
  2. package/package.json +5 -5
  3. package/packages/datadog-instrumentations/src/aerospike.js +1 -1
  4. package/packages/datadog-instrumentations/src/apollo-server.js +1 -1
  5. package/packages/datadog-instrumentations/src/aws-sdk.js +4 -4
  6. package/packages/datadog-instrumentations/src/body-parser.js +17 -5
  7. package/packages/datadog-instrumentations/src/cassandra-driver.js +2 -2
  8. package/packages/datadog-instrumentations/src/child_process.js +2 -2
  9. package/packages/datadog-instrumentations/src/connect.js +4 -4
  10. package/packages/datadog-instrumentations/src/cookie-parser.js +4 -4
  11. package/packages/datadog-instrumentations/src/couchbase.js +12 -12
  12. package/packages/datadog-instrumentations/src/cucumber.js +16 -5
  13. package/packages/datadog-instrumentations/src/dns.js +10 -10
  14. package/packages/datadog-instrumentations/src/elasticsearch.js +4 -4
  15. package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +3 -3
  16. package/packages/datadog-instrumentations/src/express.js +4 -4
  17. package/packages/datadog-instrumentations/src/fastify.js +6 -6
  18. package/packages/datadog-instrumentations/src/fetch.js +1 -1
  19. package/packages/datadog-instrumentations/src/find-my-way.js +2 -2
  20. package/packages/datadog-instrumentations/src/fs.js +2 -2
  21. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +2 -2
  22. package/packages/datadog-instrumentations/src/grpc/client.js +4 -6
  23. package/packages/datadog-instrumentations/src/grpc/server.js +2 -2
  24. package/packages/datadog-instrumentations/src/hapi.js +10 -13
  25. package/packages/datadog-instrumentations/src/helpers/hooks.js +3 -2
  26. package/packages/datadog-instrumentations/src/helpers/register.js +9 -2
  27. package/packages/datadog-instrumentations/src/http/client.js +3 -3
  28. package/packages/datadog-instrumentations/src/jest.js +5 -4
  29. package/packages/datadog-instrumentations/src/knex.js +2 -2
  30. package/packages/datadog-instrumentations/src/koa.js +5 -5
  31. package/packages/datadog-instrumentations/src/ldapjs.js +1 -1
  32. package/packages/datadog-instrumentations/src/mariadb.js +8 -8
  33. package/packages/datadog-instrumentations/src/memcached.js +2 -2
  34. package/packages/datadog-instrumentations/src/microgateway-core.js +4 -4
  35. package/packages/datadog-instrumentations/src/mocha/common.js +1 -1
  36. package/packages/datadog-instrumentations/src/mocha/main.js +91 -70
  37. package/packages/datadog-instrumentations/src/mocha/utils.js +2 -3
  38. package/packages/datadog-instrumentations/src/mocha.js +4 -0
  39. package/packages/datadog-instrumentations/src/moleculer/server.js +2 -2
  40. package/packages/datadog-instrumentations/src/mongodb-core.js +7 -7
  41. package/packages/datadog-instrumentations/src/mongoose.js +5 -6
  42. package/packages/datadog-instrumentations/src/mysql.js +3 -3
  43. package/packages/datadog-instrumentations/src/mysql2.js +6 -6
  44. package/packages/datadog-instrumentations/src/net.js +2 -2
  45. package/packages/datadog-instrumentations/src/next.js +5 -5
  46. package/packages/datadog-instrumentations/src/nyc.js +23 -0
  47. package/packages/datadog-instrumentations/src/openai.js +58 -69
  48. package/packages/datadog-instrumentations/src/oracledb.js +8 -8
  49. package/packages/datadog-instrumentations/src/passport-http.js +1 -1
  50. package/packages/datadog-instrumentations/src/passport-local.js +1 -1
  51. package/packages/datadog-instrumentations/src/passport-utils.js +1 -1
  52. package/packages/datadog-instrumentations/src/pg.js +1 -1
  53. package/packages/datadog-instrumentations/src/pino.js +4 -4
  54. package/packages/datadog-instrumentations/src/playwright.js +6 -4
  55. package/packages/datadog-instrumentations/src/redis.js +2 -2
  56. package/packages/datadog-instrumentations/src/restify.js +4 -4
  57. package/packages/datadog-instrumentations/src/rhea.js +4 -4
  58. package/packages/datadog-instrumentations/src/router.js +5 -5
  59. package/packages/datadog-instrumentations/src/sharedb.js +2 -2
  60. package/packages/datadog-instrumentations/src/vitest.js +22 -5
  61. package/packages/datadog-instrumentations/src/winston.js +2 -3
  62. package/packages/datadog-plugin-cucumber/src/index.js +12 -2
  63. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +21 -10
  64. package/packages/datadog-plugin-hapi/src/index.js +2 -2
  65. package/packages/datadog-plugin-jest/src/index.js +18 -4
  66. package/packages/datadog-plugin-mocha/src/index.js +25 -6
  67. package/packages/datadog-plugin-nyc/src/index.js +35 -0
  68. package/packages/datadog-plugin-openai/src/index.js +58 -47
  69. package/packages/datadog-plugin-playwright/src/index.js +9 -4
  70. package/packages/datadog-plugin-vitest/src/index.js +30 -4
  71. package/packages/datadog-shimmer/src/shimmer.js +144 -10
  72. package/packages/dd-trace/src/appsec/blocking.js +23 -17
  73. package/packages/dd-trace/src/appsec/graphql.js +3 -1
  74. package/packages/dd-trace/src/appsec/iast/iast-log.js +2 -1
  75. package/packages/dd-trace/src/appsec/remote_config/manager.js +4 -1
  76. package/packages/dd-trace/src/appsec/rule_manager.js +8 -0
  77. package/packages/dd-trace/src/appsec/telemetry.js +3 -3
  78. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +40 -1
  79. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -4
  80. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -4
  81. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +2 -1
  82. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +8 -7
  83. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -4
  84. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -4
  85. package/packages/dd-trace/src/ci-visibility/telemetry.js +29 -2
  86. package/packages/dd-trace/src/config.js +157 -142
  87. package/packages/dd-trace/src/lambda/handler.js +1 -0
  88. package/packages/dd-trace/src/lambda/index.js +12 -1
  89. package/packages/dd-trace/src/opentelemetry/context_manager.js +22 -39
  90. package/packages/dd-trace/src/opentelemetry/span_context.js +2 -2
  91. package/packages/dd-trace/src/opentelemetry/tracer.js +23 -14
  92. package/packages/dd-trace/src/opentelemetry/tracer_provider.js +9 -1
  93. package/packages/dd-trace/src/opentracing/propagation/log.js +1 -1
  94. package/packages/dd-trace/src/opentracing/propagation/text_map.js +61 -6
  95. package/packages/dd-trace/src/opentracing/span_context.js +1 -0
  96. package/packages/dd-trace/src/plugins/ci_plugin.js +2 -2
  97. package/packages/dd-trace/src/plugins/index.js +1 -0
  98. package/packages/dd-trace/src/plugins/util/git.js +14 -1
  99. package/packages/dd-trace/src/plugins/util/test.js +1 -5
  100. package/packages/dd-trace/src/profiler.js +15 -5
  101. package/packages/dd-trace/src/profiling/config.js +2 -4
  102. package/packages/dd-trace/src/profiling/exporter_cli.js +13 -1
  103. package/packages/dd-trace/src/profiling/exporters/agent.js +7 -1
  104. package/packages/dd-trace/src/profiling/profiler.js +0 -9
  105. package/packages/dd-trace/src/profiling/ssi-heuristics.js +49 -58
  106. package/packages/dd-trace/src/proxy.js +21 -21
  107. package/packages/dd-trace/src/telemetry/index.js +24 -7
  108. package/packages/dd-trace/src/telemetry/logs/index.js +20 -0
@@ -9,6 +9,8 @@ let templateHtml = blockedTemplates.html
9
9
  let templateJson = blockedTemplates.json
10
10
  let templateGraphqlJson = blockedTemplates.graphqlJson
11
11
 
12
+ let defaultBlockingActionParameters
13
+
12
14
  const responseBlockedSet = new WeakSet()
13
15
 
14
16
  const specificBlockingTypes = {
@@ -23,7 +25,7 @@ function addSpecificEndpoint (method, url, type) {
23
25
  detectedSpecificEndpoints[getSpecificKey(method, url)] = type
24
26
  }
25
27
 
26
- function getBlockWithRedirectData (rootSpan, actionParameters) {
28
+ function getBlockWithRedirectData (actionParameters) {
27
29
  let statusCode = actionParameters.status_code
28
30
  if (!statusCode || statusCode < 300 || statusCode >= 400) {
29
31
  statusCode = 303
@@ -32,10 +34,6 @@ function getBlockWithRedirectData (rootSpan, actionParameters) {
32
34
  Location: actionParameters.location
33
35
  }
34
36
 
35
- rootSpan.addTags({
36
- 'appsec.blocked': 'true'
37
- })
38
-
39
37
  return { headers, statusCode }
40
38
  }
41
39
 
@@ -49,7 +47,7 @@ function getSpecificBlockingData (type) {
49
47
  }
50
48
  }
51
49
 
52
- function getBlockWithContentData (req, specificType, rootSpan, actionParameters) {
50
+ function getBlockWithContentData (req, specificType, actionParameters) {
53
51
  let type
54
52
  let body
55
53
 
@@ -90,28 +88,28 @@ function getBlockWithContentData (req, specificType, rootSpan, actionParameters)
90
88
  'Content-Length': Buffer.byteLength(body)
91
89
  }
92
90
 
93
- rootSpan.addTags({
94
- 'appsec.blocked': 'true'
95
- })
96
-
97
91
  return { body, statusCode, headers }
98
92
  }
99
93
 
100
- function getBlockingData (req, specificType, rootSpan, actionParameters) {
94
+ function getBlockingData (req, specificType, actionParameters) {
101
95
  if (actionParameters?.location) {
102
- return getBlockWithRedirectData(rootSpan, actionParameters)
96
+ return getBlockWithRedirectData(actionParameters)
103
97
  } else {
104
- return getBlockWithContentData(req, specificType, rootSpan, actionParameters)
98
+ return getBlockWithContentData(req, specificType, actionParameters)
105
99
  }
106
100
  }
107
101
 
108
- function block (req, res, rootSpan, abortController, actionParameters) {
102
+ function block (req, res, rootSpan, abortController, actionParameters = defaultBlockingActionParameters) {
109
103
  if (res.headersSent) {
110
104
  log.warn('Cannot send blocking response when headers have already been sent')
111
105
  return
112
106
  }
113
107
 
114
- const { body, headers, statusCode } = getBlockingData(req, null, rootSpan, actionParameters)
108
+ const { body, headers, statusCode } = getBlockingData(req, null, actionParameters)
109
+
110
+ rootSpan.addTags({
111
+ 'appsec.blocked': 'true'
112
+ })
115
113
 
116
114
  for (const headerName of res.getHeaderNames()) {
117
115
  res.removeHeader(headerName)
@@ -125,7 +123,8 @@ function block (req, res, rootSpan, abortController, actionParameters) {
125
123
  }
126
124
 
127
125
  function getBlockingAction (actions) {
128
- return actions?.block_request || actions?.redirect_request
126
+ // waf only returns one action, but it prioritizes redirect over block
127
+ return actions?.redirect_request || actions?.block_request
129
128
  }
130
129
 
131
130
  function setTemplates (config) {
@@ -152,6 +151,12 @@ function isBlocked (res) {
152
151
  return responseBlockedSet.has(res)
153
152
  }
154
153
 
154
+ function setDefaultBlockingActionParameters (actions) {
155
+ const blockAction = actions?.find(action => action.id === 'block')
156
+
157
+ defaultBlockingActionParameters = blockAction?.parameters
158
+ }
159
+
155
160
  module.exports = {
156
161
  addSpecificEndpoint,
157
162
  block,
@@ -159,5 +164,6 @@ module.exports = {
159
164
  getBlockingData,
160
165
  getBlockingAction,
161
166
  setTemplates,
162
- isBlocked
167
+ isBlocked,
168
+ setDefaultBlockingActionParameters
163
169
  }
@@ -94,11 +94,13 @@ function beforeWriteApolloGraphqlResponse ({ abortController, abortData }) {
94
94
  const rootSpan = web.root(req)
95
95
  if (!rootSpan) return
96
96
 
97
- const blockingData = getBlockingData(req, specificBlockingTypes.GRAPHQL, rootSpan, requestData.wafAction)
97
+ const blockingData = getBlockingData(req, specificBlockingTypes.GRAPHQL, requestData.wafAction)
98
98
  abortData.statusCode = blockingData.statusCode
99
99
  abortData.headers = blockingData.headers
100
100
  abortData.message = blockingData.body
101
101
 
102
+ rootSpan.setTag('appsec.blocked', 'true')
103
+
102
104
  abortController?.abort()
103
105
  }
104
106
 
@@ -78,7 +78,8 @@ const iastLog = {
78
78
 
79
79
  errorAndPublish (data) {
80
80
  this.error(data)
81
- return this.publish(data, 'ERROR')
81
+ // publish is done automatically by log.error()
82
+ return this
82
83
  }
83
84
  }
84
85
 
@@ -120,7 +120,10 @@ class RemoteConfigManager extends EventEmitter {
120
120
  const options = {
121
121
  url: this.url,
122
122
  method: 'POST',
123
- path: '/v0.7/config'
123
+ path: '/v0.7/config',
124
+ headers: {
125
+ 'Content-Type': 'application/json; charset=utf-8'
126
+ }
124
127
  }
125
128
 
126
129
  request(this.getPayload(), options, (err, data, statusCode) => {
@@ -4,6 +4,8 @@ const fs = require('fs')
4
4
  const waf = require('./waf')
5
5
  const { ACKNOWLEDGED, ERROR } = require('./remote_config/apply_states')
6
6
 
7
+ const blocking = require('./blocking')
8
+
7
9
  let defaultRules
8
10
 
9
11
  let appliedRulesData = new Map()
@@ -19,6 +21,8 @@ function loadRules (config) {
19
21
  : require('./recommended.json')
20
22
 
21
23
  waf.init(defaultRules, config)
24
+
25
+ blocking.setDefaultBlockingActionParameters(defaultRules?.actions)
22
26
  }
23
27
 
24
28
  function updateWafFromRC ({ toUnapply, toApply, toModify }) {
@@ -141,6 +145,8 @@ function updateWafFromRC ({ toUnapply, toApply, toModify }) {
141
145
  }
142
146
  if (newActions.modified) {
143
147
  appliedActions = newActions
148
+
149
+ blocking.setDefaultBlockingActionParameters(concatArrays(newActions))
144
150
  }
145
151
  } catch (err) {
146
152
  newApplyState = ERROR
@@ -242,6 +248,8 @@ function clearAllRules () {
242
248
  appliedExclusions.clear()
243
249
  appliedCustomRules.clear()
244
250
  appliedActions.clear()
251
+
252
+ blocking.setDefaultBlockingActionParameters(undefined)
245
253
  }
246
254
 
247
255
  module.exports = {
@@ -90,14 +90,14 @@ function updateRaspRequestsMetricTags (metrics, req, raspRuleType) {
90
90
  if (!enabled) return
91
91
 
92
92
  const tags = { rule_type: raspRuleType, waf_version: metrics.wafVersion }
93
- appsecMetrics.count('appsec.rasp.rule.eval', tags).inc(1)
93
+ appsecMetrics.count('rasp.rule.eval', tags).inc(1)
94
94
 
95
95
  if (metrics.wafTimeout) {
96
- appsecMetrics.count('appsec.rasp.timeout', tags).inc(1)
96
+ appsecMetrics.count('rasp.timeout', tags).inc(1)
97
97
  }
98
98
 
99
99
  if (metrics.ruleTriggered) {
100
- appsecMetrics.count('appsec.rasp.rule.match', tags).inc(1)
100
+ appsecMetrics.count('rasp.rule.match', tags).inc(1)
101
101
  }
102
102
  }
103
103
 
@@ -1,5 +1,30 @@
1
1
  const request = require('../../exporters/common/request')
2
2
  const id = require('../../id')
3
+ const log = require('../../log')
4
+
5
+ const {
6
+ incrementCountMetric,
7
+ distributionMetric,
8
+ TELEMETRY_KNOWN_TESTS,
9
+ TELEMETRY_KNOWN_TESTS_MS,
10
+ TELEMETRY_KNOWN_TESTS_ERRORS,
11
+ TELEMETRY_KNOWN_TESTS_RESPONSE_TESTS,
12
+ TELEMETRY_KNOWN_TESTS_RESPONSE_BYTES
13
+ } = require('../../ci-visibility/telemetry')
14
+
15
+ function getNumTests (knownTests) {
16
+ let totalNumTests = 0
17
+
18
+ for (const testModule of Object.values(knownTests)) {
19
+ for (const testSuite of Object.values(testModule)) {
20
+ for (const testList of Object.values(testSuite)) {
21
+ totalNumTests += testList.length
22
+ }
23
+ }
24
+ }
25
+
26
+ return totalNumTests
27
+ }
3
28
 
4
29
  function getKnownTests ({
5
30
  url,
@@ -64,12 +89,26 @@ function getKnownTests ({
64
89
  }
65
90
  })
66
91
 
67
- request(data, options, (err, res) => {
92
+ incrementCountMetric(TELEMETRY_KNOWN_TESTS)
93
+
94
+ const startTime = Date.now()
95
+
96
+ request(data, options, (err, res, statusCode) => {
97
+ distributionMetric(TELEMETRY_KNOWN_TESTS_MS, {}, Date.now() - startTime)
68
98
  if (err) {
99
+ incrementCountMetric(TELEMETRY_KNOWN_TESTS_ERRORS, { statusCode })
69
100
  done(err)
70
101
  } else {
71
102
  try {
72
103
  const { data: { attributes: { tests: knownTests } } } = JSON.parse(res)
104
+
105
+ const numTests = getNumTests(knownTests)
106
+
107
+ incrementCountMetric(TELEMETRY_KNOWN_TESTS_RESPONSE_TESTS, {}, numTests)
108
+ distributionMetric(TELEMETRY_KNOWN_TESTS_RESPONSE_BYTES, {}, res.length)
109
+
110
+ log.debug(() => `Number of received known tests: ${numTests}`)
111
+
73
112
  done(null, knownTests)
74
113
  } catch (err) {
75
114
  done(err)
@@ -12,8 +12,7 @@ const {
12
12
  TELEMETRY_ENDPOINT_PAYLOAD_BYTES,
13
13
  TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_MS,
14
14
  TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
15
- TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
16
- getErrorTypeFromStatusCode
15
+ TELEMETRY_ENDPOINT_PAYLOAD_DROPPED
17
16
  } = require('../../../ci-visibility/telemetry')
18
17
 
19
18
  class Writer extends BaseWriter {
@@ -56,10 +55,9 @@ class Writer extends BaseWriter {
56
55
  Date.now() - startRequestTime
57
56
  )
58
57
  if (err) {
59
- const errorType = getErrorTypeFromStatusCode(statusCode)
60
58
  incrementCountMetric(
61
59
  TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
62
- { endpoint: 'code_coverage', errorType }
60
+ { endpoint: 'code_coverage', statusCode }
63
61
  )
64
62
  incrementCountMetric(
65
63
  TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
@@ -12,8 +12,7 @@ const {
12
12
  TELEMETRY_ENDPOINT_PAYLOAD_BYTES,
13
13
  TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_MS,
14
14
  TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
15
- TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
16
- getErrorTypeFromStatusCode
15
+ TELEMETRY_ENDPOINT_PAYLOAD_DROPPED
17
16
  } = require('../../../ci-visibility/telemetry')
18
17
 
19
18
  class Writer extends BaseWriter {
@@ -57,10 +56,9 @@ class Writer extends BaseWriter {
57
56
  Date.now() - startRequestTime
58
57
  )
59
58
  if (err) {
60
- const errorType = getErrorTypeFromStatusCode(statusCode)
61
59
  incrementCountMetric(
62
60
  TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
63
- { endpoint: 'test_cycle', errorType }
61
+ { endpoint: 'test_cycle', statusCode }
64
62
  )
65
63
  incrementCountMetric(
66
64
  TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
@@ -201,7 +201,8 @@ class CiVisibilityExporter extends AgentInfoExporter {
201
201
  isEarlyFlakeDetectionEnabled: isEarlyFlakeDetectionEnabled && this._config.isEarlyFlakeDetectionEnabled,
202
202
  earlyFlakeDetectionNumRetries,
203
203
  earlyFlakeDetectionFaultyThreshold,
204
- isFlakyTestRetriesEnabled
204
+ isFlakyTestRetriesEnabled: isFlakyTestRetriesEnabled && this._config.isFlakyTestRetriesEnabled,
205
+ flakyTestRetriesCount: this._config.flakyTestRetriesCount
205
206
  }
206
207
  }
207
208
 
@@ -11,7 +11,8 @@ const {
11
11
  generatePackFilesForCommits,
12
12
  getCommitsRevList,
13
13
  isShallowRepository,
14
- unshallowRepository
14
+ unshallowRepository,
15
+ isGitAvailable
15
16
  } = require('../../../plugins/util/git')
16
17
 
17
18
  const {
@@ -24,8 +25,7 @@ const {
24
25
  TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES,
25
26
  TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_MS,
26
27
  TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_ERRORS,
27
- TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_BYTES,
28
- getErrorTypeFromStatusCode
28
+ TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_BYTES
29
29
  } = require('../../../ci-visibility/telemetry')
30
30
 
31
31
  const isValidSha1 = (sha) => /^[0-9a-f]{40}$/.test(sha)
@@ -92,8 +92,7 @@ function getCommitsToUpload ({ url, repositoryUrl, latestCommits, isEvpProxy, ev
92
92
  request(localCommitData, options, (err, response, statusCode) => {
93
93
  distributionMetric(TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_MS, {}, Date.now() - startTime)
94
94
  if (err) {
95
- const errorType = getErrorTypeFromStatusCode(statusCode)
96
- incrementCountMetric(TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_ERRORS, { errorType })
95
+ incrementCountMetric(TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_ERRORS, { statusCode })
97
96
  const error = new Error(`Error fetching commits to exclude: ${err.message}`)
98
97
  return callback(error)
99
98
  }
@@ -178,8 +177,7 @@ function uploadPackFile ({ url, isEvpProxy, evpProxyPrefix, packFileToUpload, re
178
177
  request(form, options, (err, _, statusCode) => {
179
178
  distributionMetric(TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_MS, {}, Date.now() - startTime)
180
179
  if (err) {
181
- const errorType = getErrorTypeFromStatusCode(statusCode)
182
- incrementCountMetric(TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_ERRORS, { errorType })
180
+ incrementCountMetric(TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_ERRORS, { statusCode })
183
181
  const error = new Error(`Could not upload packfiles: status code ${statusCode}: ${err.message}`)
184
182
  return callback(error, uploadSize)
185
183
  }
@@ -245,6 +243,9 @@ function generateAndUploadPackFiles ({
245
243
  * This function uploads git metadata to CI Visibility's backend.
246
244
  */
247
245
  function sendGitMetadata (url, { isEvpProxy, evpProxyPrefix }, configRepositoryUrl, callback) {
246
+ if (!isGitAvailable()) {
247
+ return callback(new Error('Git is not available'))
248
+ }
248
249
  let repositoryUrl = configRepositoryUrl
249
250
  if (!repositoryUrl) {
250
251
  repositoryUrl = getRepositoryUrl()
@@ -8,8 +8,7 @@ const {
8
8
  TELEMETRY_ITR_SKIPPABLE_TESTS_ERRORS,
9
9
  TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_SUITES,
10
10
  TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS,
11
- TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES,
12
- getErrorTypeFromStatusCode
11
+ TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES
13
12
  } = require('../../ci-visibility/telemetry')
14
13
 
15
14
  function getSkippableSuites ({
@@ -83,8 +82,7 @@ function getSkippableSuites ({
83
82
  request(data, options, (err, res, statusCode) => {
84
83
  distributionMetric(TELEMETRY_ITR_SKIPPABLE_TESTS_MS, {}, Date.now() - startTime)
85
84
  if (err) {
86
- const errorType = getErrorTypeFromStatusCode(statusCode)
87
- incrementCountMetric(TELEMETRY_ITR_SKIPPABLE_TESTS_ERRORS, { errorType })
85
+ incrementCountMetric(TELEMETRY_ITR_SKIPPABLE_TESTS_ERRORS, { statusCode })
88
86
  done(err)
89
87
  } else {
90
88
  let skippableSuites = []
@@ -7,8 +7,7 @@ const {
7
7
  TELEMETRY_GIT_REQUESTS_SETTINGS,
8
8
  TELEMETRY_GIT_REQUESTS_SETTINGS_MS,
9
9
  TELEMETRY_GIT_REQUESTS_SETTINGS_ERRORS,
10
- TELEMETRY_GIT_REQUESTS_SETTINGS_RESPONSE,
11
- getErrorTypeFromStatusCode
10
+ TELEMETRY_GIT_REQUESTS_SETTINGS_RESPONSE
12
11
  } = require('../telemetry')
13
12
 
14
13
  const DEFAULT_EARLY_FLAKE_DETECTION_NUM_RETRIES = 2
@@ -81,8 +80,7 @@ function getLibraryConfiguration ({
81
80
  request(data, options, (err, res, statusCode) => {
82
81
  distributionMetric(TELEMETRY_GIT_REQUESTS_SETTINGS_MS, {}, Date.now() - startTime)
83
82
  if (err) {
84
- const errorType = getErrorTypeFromStatusCode(statusCode)
85
- incrementCountMetric(TELEMETRY_GIT_REQUESTS_SETTINGS_ERRORS, { errorType })
83
+ incrementCountMetric(TELEMETRY_GIT_REQUESTS_SETTINGS_ERRORS, { statusCode })
86
84
  done(err)
87
85
  } else {
88
86
  try {
@@ -10,13 +10,24 @@ const formattedTags = {
10
10
  isCodeCoverageEnabled: 'coverage_enabled',
11
11
  isSuitesSkippingEnabled: 'itrskip_enabled',
12
12
  hasCodeOwners: 'has_code_owners',
13
- isUnsupportedCIProvider: 'is_unsupported_ci'
13
+ isUnsupportedCIProvider: 'is_unsupported_ci',
14
+ isNew: 'is_new',
15
+ isRum: 'is_rum',
16
+ browserDriver: 'browser_driver'
14
17
  }
15
18
 
16
19
  // Transform tags dictionary to array of strings.
17
20
  // If tag value is true, then only tag key is added to the array.
18
21
  function formatMetricTags (tagsDictionary) {
19
22
  return Object.keys(tagsDictionary).reduce((acc, tagKey) => {
23
+ if (tagKey === 'statusCode') {
24
+ const statusCode = tagsDictionary[tagKey]
25
+ if (isStatusCode400(statusCode)) {
26
+ acc.push(`status_code:${statusCode}`)
27
+ }
28
+ acc.push(`error_type:${getErrorTypeFromStatusCode(statusCode)}`)
29
+ return acc
30
+ }
20
31
  const formattedTagKey = formattedTags[tagKey] || tagKey
21
32
  if (tagsDictionary[tagKey] === true) {
22
33
  acc.push(formattedTagKey)
@@ -36,6 +47,7 @@ function distributionMetric (name, tags, measure) {
36
47
  }
37
48
 
38
49
  // CI Visibility telemetry events
50
+ const TELEMETRY_TEST_SESSION = 'test_session'
39
51
  const TELEMETRY_EVENT_CREATED = 'event_created'
40
52
  const TELEMETRY_EVENT_FINISHED = 'event_finished'
41
53
  const TELEMETRY_CODE_COVERAGE_STARTED = 'code_coverage_started'
@@ -74,6 +86,16 @@ const TELEMETRY_ITR_SKIPPABLE_TESTS_ERRORS = 'itr_skippable_tests.request_errors
74
86
  const TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_SUITES = 'itr_skippable_tests.response_suites'
75
87
  const TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS = 'itr_skippable_tests.response_tests'
76
88
  const TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES = 'itr_skippable_tests.response_bytes'
89
+ // early flake detection
90
+ const TELEMETRY_KNOWN_TESTS = 'early_flake_detection.request'
91
+ const TELEMETRY_KNOWN_TESTS_MS = 'early_flake_detection.request_ms'
92
+ const TELEMETRY_KNOWN_TESTS_ERRORS = 'early_flake_detection.request_errors'
93
+ const TELEMETRY_KNOWN_TESTS_RESPONSE_TESTS = 'early_flake_detection.response_tests'
94
+ const TELEMETRY_KNOWN_TESTS_RESPONSE_BYTES = 'early_flake_detection.response_bytes'
95
+
96
+ function isStatusCode400 (statusCode) {
97
+ return statusCode >= 400 && statusCode < 500
98
+ }
77
99
 
78
100
  function getErrorTypeFromStatusCode (statusCode) {
79
101
  if (statusCode >= 400 && statusCode < 500) {
@@ -88,6 +110,7 @@ function getErrorTypeFromStatusCode (statusCode) {
88
110
  module.exports = {
89
111
  incrementCountMetric,
90
112
  distributionMetric,
113
+ TELEMETRY_TEST_SESSION,
91
114
  TELEMETRY_EVENT_CREATED,
92
115
  TELEMETRY_EVENT_FINISHED,
93
116
  TELEMETRY_CODE_COVERAGE_STARTED,
@@ -126,5 +149,9 @@ module.exports = {
126
149
  TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_SUITES,
127
150
  TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS,
128
151
  TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES,
129
- getErrorTypeFromStatusCode
152
+ TELEMETRY_KNOWN_TESTS,
153
+ TELEMETRY_KNOWN_TESTS_MS,
154
+ TELEMETRY_KNOWN_TESTS_ERRORS,
155
+ TELEMETRY_KNOWN_TESTS_RESPONSE_TESTS,
156
+ TELEMETRY_KNOWN_TESTS_RESPONSE_BYTES
130
157
  }