datadog-ci 1.2.0 → 1.3.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -2
  3. data/lib/datadog/ci/configuration/components.rb +30 -3
  4. data/lib/datadog/ci/contrib/cucumber/formatter.rb +13 -9
  5. data/lib/datadog/ci/contrib/minitest/runnable.rb +5 -1
  6. data/lib/datadog/ci/contrib/minitest/runner.rb +6 -2
  7. data/lib/datadog/ci/contrib/minitest/test.rb +7 -3
  8. data/lib/datadog/ci/contrib/rspec/example.rb +6 -2
  9. data/lib/datadog/ci/contrib/rspec/example_group.rb +5 -1
  10. data/lib/datadog/ci/contrib/rspec/knapsack_pro/runner.rb +6 -2
  11. data/lib/datadog/ci/contrib/rspec/runner.rb +6 -2
  12. data/lib/datadog/ci/ext/environment/providers/appveyor.rb +1 -1
  13. data/lib/datadog/ci/ext/environment/providers/aws_code_pipeline.rb +1 -1
  14. data/lib/datadog/ci/ext/environment/providers/azure.rb +1 -1
  15. data/lib/datadog/ci/ext/environment/providers/bitbucket.rb +1 -1
  16. data/lib/datadog/ci/ext/environment/providers/bitrise.rb +1 -1
  17. data/lib/datadog/ci/ext/environment/providers/buddy.rb +1 -1
  18. data/lib/datadog/ci/ext/environment/providers/buildkite.rb +1 -1
  19. data/lib/datadog/ci/ext/environment/providers/circleci.rb +1 -1
  20. data/lib/datadog/ci/ext/environment/providers/codefresh.rb +1 -1
  21. data/lib/datadog/ci/ext/environment/providers/github_actions.rb +1 -1
  22. data/lib/datadog/ci/ext/environment/providers/gitlab.rb +1 -1
  23. data/lib/datadog/ci/ext/environment/providers/jenkins.rb +1 -1
  24. data/lib/datadog/ci/ext/environment/providers/teamcity.rb +1 -1
  25. data/lib/datadog/ci/ext/environment/providers/travis.rb +1 -1
  26. data/lib/datadog/ci/ext/environment.rb +17 -0
  27. data/lib/datadog/ci/ext/telemetry.rb +120 -0
  28. data/lib/datadog/ci/git/local_repository.rb +116 -25
  29. data/lib/datadog/ci/git/search_commits.rb +20 -1
  30. data/lib/datadog/ci/git/telemetry.rb +37 -0
  31. data/lib/datadog/ci/git/tree_uploader.rb +7 -0
  32. data/lib/datadog/ci/git/upload_packfile.rb +22 -1
  33. data/lib/datadog/ci/test.rb +5 -0
  34. data/lib/datadog/ci/test_optimisation/component.rb +16 -2
  35. data/lib/datadog/ci/test_optimisation/coverage/transport.rb +10 -1
  36. data/lib/datadog/ci/test_optimisation/skippable.rb +24 -0
  37. data/lib/datadog/ci/test_optimisation/telemetry.rb +56 -0
  38. data/lib/datadog/ci/test_visibility/component.rb +95 -235
  39. data/lib/datadog/ci/test_visibility/context.rb +274 -0
  40. data/lib/datadog/ci/test_visibility/{context → store}/global.rb +1 -1
  41. data/lib/datadog/ci/test_visibility/{context → store}/local.rb +1 -1
  42. data/lib/datadog/ci/test_visibility/telemetry.rb +69 -0
  43. data/lib/datadog/ci/test_visibility/transport.rb +8 -9
  44. data/lib/datadog/ci/transport/adapters/net.rb +42 -11
  45. data/lib/datadog/ci/transport/adapters/net_http_client.rb +17 -0
  46. data/lib/datadog/ci/transport/adapters/telemetry_webmock_safe_adapter.rb +28 -0
  47. data/lib/datadog/ci/transport/event_platform_transport.rb +42 -5
  48. data/lib/datadog/ci/transport/http.rb +49 -21
  49. data/lib/datadog/ci/transport/remote_settings_api.rb +39 -1
  50. data/lib/datadog/ci/transport/telemetry.rb +93 -0
  51. data/lib/datadog/ci/utils/identity.rb +20 -0
  52. data/lib/datadog/ci/utils/parsing.rb +2 -1
  53. data/lib/datadog/ci/utils/telemetry.rb +23 -0
  54. data/lib/datadog/ci/version.rb +1 -1
  55. data/lib/datadog/ci.rb +30 -0
  56. metadata +16 -6
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module CI
5
+ module Ext
6
+ module Telemetry
7
+ NAMESPACE = "civisibility"
8
+
9
+ METRIC_EVENT_CREATED = "event_created"
10
+ METRIC_EVENT_FINISHED = "event_finished"
11
+
12
+ METRIC_MANUAL_API_EVENTS = "manual_api_events"
13
+
14
+ METRIC_EVENTS_ENQUEUED = "events_enqueued_for_serialization"
15
+ METRIC_ENDPOINT_PAYLOAD_REQUESTS = "endpoint_payload.requests"
16
+ METRIC_ENDPOINT_PAYLOAD_REQUESTS_MS = "endpoint_payload.requests_ms"
17
+ METRIC_ENDPOINT_PAYLOAD_REQUESTS_ERRORS = "endpoint_payload.requests_errors"
18
+ METRIC_ENDPOINT_PAYLOAD_BYTES = "endpoint_payload.bytes"
19
+ METRIC_ENDPOINT_PAYLOAD_EVENTS_COUNT = "endpoint_payload.events_count"
20
+ METRIC_ENDPOINT_PAYLOAD_EVENTS_SERIALIZATION_MS = "endpoint_payload.events_serialization_ms"
21
+ METRIC_ENDPOINT_PAYLOAD_DROPPED = "endpoint_payload.dropped"
22
+
23
+ METRIC_GIT_COMMAND = "git.command"
24
+ METRIC_GIT_COMMAND_ERRORS = "git.command_errors"
25
+ METRIC_GIT_COMMAND_MS = "git.command_ms"
26
+
27
+ METRIC_GIT_REQUESTS_SEARCH_COMMITS = "git_requests.search_commits"
28
+ METRIC_GIT_REQUESTS_SEARCH_COMMITS_MS = "git_requests.search_commits_ms"
29
+ METRIC_GIT_REQUESTS_SEARCH_COMMITS_ERRORS = "git_requests.search_commits_errors"
30
+
31
+ METRIC_GIT_REQUESTS_OBJECT_PACK = "git_requests.objects_pack"
32
+ METRIC_GIT_REQUESTS_OBJECT_PACK_MS = "git_requests.objects_pack_ms"
33
+ METRIC_GIT_REQUESTS_OBJECT_PACK_ERRORS = "git_requests.objects_pack_errors"
34
+ METRIC_GIT_REQUESTS_OBJECT_PACK_BYTES = "git_requests.objects_pack_bytes"
35
+ METRIC_GIT_REQUESTS_OBJECT_PACK_FILES = "git_requests.objects_pack_files"
36
+
37
+ METRIC_GIT_REQUESTS_SETTINGS = "git_requests.settings"
38
+ METRIC_GIT_REQUESTS_SETTINGS_MS = "git_requests.settings_ms"
39
+ METRIC_GIT_REQUESTS_SETTINGS_ERRORS = "git_requests.settings_errors"
40
+ METRIC_GIT_REQUESTS_SETTINGS_RESPONSE = "git_requests.settings_response"
41
+
42
+ METRIC_ITR_SKIPPABLE_TESTS_REQUEST = "itr_skippable_tests.request"
43
+ METRIC_ITR_SKIPPABLE_TESTS_REQUEST_MS = "itr_skippable_tests.request_ms"
44
+ METRIC_ITR_SKIPPABLE_TESTS_REQUEST_ERRORS = "itr_skippable_tests.request_errors"
45
+ METRIC_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES = "itr_skippable_tests.response_bytes"
46
+ METRIC_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS = "itr_skippable_tests.response_tests"
47
+
48
+ METRIC_ITR_SKIPPED = "itr_skipped"
49
+ METRIC_ITR_UNSKIPPABLE = "itr_unskippable"
50
+ METRIC_ITR_FORCED_RUN = "itr_forced_run"
51
+
52
+ METRIC_CODE_COVERAGE_STARTED = "code_coverage_started"
53
+ METRIC_CODE_COVERAGE_FINISHED = "code_coverage_finished"
54
+ METRIC_CODE_COVERAGE_IS_EMPTY = "code_coverage.is_empty"
55
+ METRIC_CODE_COVERAGE_FILES = "code_coverage.files"
56
+
57
+ METRIC_TEST_SESSION = "test_session"
58
+
59
+ TAG_TEST_FRAMEWORK = "test_framework"
60
+ TAG_EVENT_TYPE = "event_type"
61
+ TAG_HAS_CODEOWNER = "has_codeowner"
62
+ TAG_IS_UNSUPPORTED_CI = "is_unsupported_ci"
63
+ TAG_BROWSER_DRIVER = "browser_driver"
64
+ TAG_IS_RUM = "is_rum"
65
+ TAG_LIBRARY = "library"
66
+ TAG_ENDPOINT = "endpoint"
67
+ TAG_ERROR_TYPE = "error_type"
68
+ TAG_EXIT_CODE = "exit_code"
69
+ TAG_STATUS_CODE = "status_code"
70
+ TAG_REQUEST_COMPRESSED = "rq_compressed"
71
+ TAG_RESPONSE_COMPRESSED = "rs_compressed"
72
+ TAG_COMMAND = "command"
73
+ TAG_COVERAGE_ENABLED = "coverage_enabled"
74
+ TAG_ITR_SKIP_ENABLED = "itrskip_enabled"
75
+ TAG_PROVIDER = "provider"
76
+ TAG_AUTO_INJECTED = "auto_injected"
77
+
78
+ module EventType
79
+ TEST = "test"
80
+ SUITE = "suite"
81
+ MODULE = "module"
82
+ SESSION = "session"
83
+ end
84
+
85
+ module Library
86
+ CUSTOM = "custom"
87
+ end
88
+
89
+ module Endpoint
90
+ CODE_COVERAGE = "code_coverage"
91
+ TEST_CYCLE = "test_cycle"
92
+ end
93
+
94
+ module ErrorType
95
+ NETWORK = "network"
96
+ TIMEOUT = "timeout"
97
+ STATUS_CODE = "status_code"
98
+ end
99
+
100
+ module ExitCode
101
+ MISSING = "missing"
102
+ end
103
+
104
+ module Command
105
+ GET_REPOSITORY = "get_repository"
106
+ GET_BRANCH = "get_branch"
107
+ CHECK_SHALLOW = "check_shallow"
108
+ UNSHALLOW = "unshallow"
109
+ GET_LOCAL_COMMITS = "get_local_commits"
110
+ GET_OBJECTS = "get_objects"
111
+ PACK_OBJECTS = "pack_objects"
112
+ end
113
+
114
+ module Provider
115
+ UNSUPPORTED = "unsupported"
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -3,12 +3,25 @@
3
3
  require "open3"
4
4
  require "pathname"
5
5
 
6
+ require_relative "../ext/telemetry"
7
+ require_relative "telemetry"
6
8
  require_relative "user"
7
9
 
8
10
  module Datadog
9
11
  module CI
10
12
  module Git
11
13
  module LocalRepository
14
+ class GitCommandExecutionError < StandardError
15
+ attr_reader :output, :command, :status
16
+ def initialize(message, output:, command:, status:)
17
+ super(message)
18
+
19
+ @output = output
20
+ @command = command
21
+ @status = status
22
+ end
23
+ end
24
+
12
25
  COMMAND_RETRY_COUNT = 3
13
26
 
14
27
  def self.root
@@ -48,9 +61,18 @@ module Datadog
48
61
  end
49
62
 
50
63
  def self.git_repository_url
51
- exec_git_command("git ls-remote --get-url")
64
+ Telemetry.git_command(Ext::Telemetry::Command::GET_REPOSITORY)
65
+ res = nil
66
+
67
+ duration_ms = Core::Utils::Time.measure(:float_millisecond) do
68
+ res = exec_git_command("git ls-remote --get-url")
69
+ end
70
+
71
+ Telemetry.git_command_ms(Ext::Telemetry::Command::GET_REPOSITORY, duration_ms)
72
+ res
52
73
  rescue => e
53
74
  log_failure(e, "git repository url")
75
+ telemetry_track_error(e, Ext::Telemetry::Command::GET_REPOSITORY)
54
76
  nil
55
77
  end
56
78
 
@@ -69,9 +91,18 @@ module Datadog
69
91
  end
70
92
 
71
93
  def self.git_branch
72
- exec_git_command("git rev-parse --abbrev-ref HEAD")
94
+ Telemetry.git_command(Ext::Telemetry::Command::GET_BRANCH)
95
+ res = nil
96
+
97
+ duration_ms = Core::Utils::Time.measure(:float_millisecond) do
98
+ res = exec_git_command("git rev-parse --abbrev-ref HEAD")
99
+ end
100
+
101
+ Telemetry.git_command_ms(Ext::Telemetry::Command::GET_BRANCH, duration_ms)
102
+ res
73
103
  rescue => e
74
104
  log_failure(e, "git branch")
105
+ telemetry_track_error(e, Ext::Telemetry::Command::GET_BRANCH)
75
106
  nil
76
107
  end
77
108
 
@@ -116,29 +147,49 @@ module Datadog
116
147
 
117
148
  # returns maximum of 1000 latest commits in the last month
118
149
  def self.git_commits
119
- output = exec_git_command("git log --format=%H -n 1000 --since=\"1 month ago\"")
150
+ Telemetry.git_command(Ext::Telemetry::Command::GET_LOCAL_COMMITS)
151
+
152
+ output = nil
153
+ duration_ms = Core::Utils::Time.measure(:float_millisecond) do
154
+ output = exec_git_command("git log --format=%H -n 1000 --since=\"1 month ago\"")
155
+ end
156
+
157
+ Telemetry.git_command_ms(Ext::Telemetry::Command::GET_LOCAL_COMMITS, duration_ms)
158
+
120
159
  return [] if output.nil?
121
160
 
161
+ # @type var output: String
122
162
  output.split("\n")
123
163
  rescue => e
124
164
  log_failure(e, "git commits")
165
+ telemetry_track_error(e, Ext::Telemetry::Command::GET_LOCAL_COMMITS)
125
166
  []
126
167
  end
127
168
 
128
169
  def self.git_commits_rev_list(included_commits:, excluded_commits:)
170
+ Telemetry.git_command(Ext::Telemetry::Command::GET_OBJECTS)
129
171
  included_commits = filter_invalid_commits(included_commits).join(" ")
130
172
  excluded_commits = filter_invalid_commits(excluded_commits).map! { |sha| "^#{sha}" }.join(" ")
131
173
 
132
- exec_git_command(
133
- "git rev-list " \
134
- "--objects " \
135
- "--no-object-names " \
136
- "--filter=blob:none " \
137
- "--since=\"1 month ago\" " \
138
- "#{excluded_commits} #{included_commits}"
139
- )
174
+ res = nil
175
+
176
+ duration_ms = Core::Utils::Time.measure(:float_millisecond) do
177
+ res = exec_git_command(
178
+ "git rev-list " \
179
+ "--objects " \
180
+ "--no-object-names " \
181
+ "--filter=blob:none " \
182
+ "--since=\"1 month ago\" " \
183
+ "#{excluded_commits} #{included_commits}"
184
+ )
185
+ end
186
+
187
+ Telemetry.git_command_ms(Ext::Telemetry::Command::GET_OBJECTS, duration_ms)
188
+
189
+ res
140
190
  rescue => e
141
191
  log_failure(e, "git commits rev list")
192
+ telemetry_track_error(e, Ext::Telemetry::Command::GET_OBJECTS)
142
193
  nil
143
194
  end
144
195
 
@@ -150,35 +201,59 @@ module Datadog
150
201
 
151
202
  basename = SecureRandom.hex(4)
152
203
 
153
- exec_git_command(
154
- "git pack-objects --compression=9 --max-pack-size=3m #{path}/#{basename}",
155
- stdin: commit_tree
156
- )
204
+ Telemetry.git_command(Ext::Telemetry::Command::PACK_OBJECTS)
205
+
206
+ duration_ms = Core::Utils::Time.measure(:float_millisecond) do
207
+ exec_git_command(
208
+ "git pack-objects --compression=9 --max-pack-size=3m #{path}/#{basename}",
209
+ stdin: commit_tree
210
+ )
211
+ end
212
+ Telemetry.git_command_ms(Ext::Telemetry::Command::PACK_OBJECTS, duration_ms)
157
213
 
158
214
  basename
159
215
  rescue => e
160
216
  log_failure(e, "git generate packfiles")
217
+ telemetry_track_error(e, Ext::Telemetry::Command::PACK_OBJECTS)
161
218
  nil
162
219
  end
163
220
 
164
221
  def self.git_shallow_clone?
165
- exec_git_command("git rev-parse --is-shallow-repository") == "true"
222
+ Telemetry.git_command(Ext::Telemetry::Command::CHECK_SHALLOW)
223
+ res = false
224
+
225
+ duration_ms = Core::Utils::Time.measure(:float_millisecond) do
226
+ res = exec_git_command("git rev-parse --is-shallow-repository") == "true"
227
+ end
228
+ Telemetry.git_command_ms(Ext::Telemetry::Command::CHECK_SHALLOW, duration_ms)
229
+
230
+ res
166
231
  rescue => e
167
232
  log_failure(e, "git shallow clone")
233
+ telemetry_track_error(e, Ext::Telemetry::Command::CHECK_SHALLOW)
168
234
  false
169
235
  end
170
236
 
171
237
  def self.git_unshallow
172
- exec_git_command(
173
- "git fetch " \
174
- "--shallow-since=\"1 month ago\" " \
175
- "--update-shallow " \
176
- "--filter=\"blob:none\" " \
177
- "--recurse-submodules=no " \
178
- "$(git config --default origin --get clone.defaultRemoteName) $(git rev-parse HEAD)"
179
- )
238
+ Telemetry.git_command(Ext::Telemetry::Command::UNSHALLOW)
239
+ res = nil
240
+
241
+ duration_ms = Core::Utils::Time.measure(:float_millisecond) do
242
+ res = exec_git_command(
243
+ "git fetch " \
244
+ "--shallow-since=\"1 month ago\" " \
245
+ "--update-shallow " \
246
+ "--filter=\"blob:none\" " \
247
+ "--recurse-submodules=no " \
248
+ "$(git config --default origin --get clone.defaultRemoteName) $(git rev-parse HEAD)"
249
+ )
250
+ end
251
+ Telemetry.git_command_ms(Ext::Telemetry::Command::UNSHALLOW, duration_ms)
252
+
253
+ res
180
254
  rescue => e
181
255
  log_failure(e, "git unshallow")
256
+ telemetry_track_error(e, Ext::Telemetry::Command::UNSHALLOW)
182
257
  nil
183
258
  end
184
259
 
@@ -209,7 +284,12 @@ module Datadog
209
284
  end
210
285
 
211
286
  if status.nil? || !status.success?
212
- raise "Failed to run git command [#{cmd}] with input [#{stdin}] and output [#{out}]"
287
+ raise GitCommandExecutionError.new(
288
+ "Failed to run git command [#{cmd}] with input [#{stdin}] and output [#{out}]",
289
+ output: out,
290
+ command: cmd,
291
+ status: status
292
+ )
213
293
  end
214
294
 
215
295
  # Sometimes Encoding.default_external is somehow set to US-ASCII which breaks
@@ -231,6 +311,17 @@ module Datadog
231
311
  "Unable to perform #{action}: #{e.class.name} #{e.message} at #{Array(e.backtrace).first}"
232
312
  )
233
313
  end
314
+
315
+ def telemetry_track_error(e, command)
316
+ case e
317
+ when Errno::ENOENT
318
+ Telemetry.git_command_errors(command, executable_missing: true)
319
+ when GitCommandExecutionError
320
+ Telemetry.git_command_errors(command, exit_code: e.status&.to_i)
321
+ else
322
+ Telemetry.git_command_errors(command, exit_code: -9000)
323
+ end
324
+ end
234
325
  end
235
326
  end
236
327
  end
@@ -3,8 +3,11 @@
3
3
  require "json"
4
4
  require "set"
5
5
 
6
+ require_relative "../ext/telemetry"
6
7
  require_relative "../ext/transport"
8
+ require_relative "../transport/telemetry"
7
9
  require_relative "../utils/git"
10
+ require_relative "../utils/telemetry"
8
11
 
9
12
  module Datadog
10
13
  module CI
@@ -25,7 +28,23 @@ module Datadog
25
28
  path: Ext::Transport::DD_API_GIT_SEARCH_COMMITS_PATH,
26
29
  payload: request_payload(repository_url, commits)
27
30
  )
28
- raise ApiError, "Failed to search commits: #{http_response.inspect}" unless http_response.ok?
31
+
32
+ Transport::Telemetry.api_requests(
33
+ Ext::Telemetry::METRIC_GIT_REQUESTS_SEARCH_COMMITS,
34
+ 1,
35
+ compressed: http_response.request_compressed
36
+ )
37
+ Utils::Telemetry.distribution(Ext::Telemetry::METRIC_GIT_REQUESTS_SEARCH_COMMITS_MS, http_response.duration_ms)
38
+
39
+ unless http_response.ok?
40
+ Transport::Telemetry.api_requests_errors(
41
+ Ext::Telemetry::METRIC_GIT_REQUESTS_SEARCH_COMMITS_ERRORS,
42
+ 1,
43
+ error_type: http_response.telemetry_error_type,
44
+ status_code: http_response.code
45
+ )
46
+ raise ApiError, "Failed to search commits: #{http_response.inspect}"
47
+ end
29
48
 
30
49
  response_payload = parse_json_response(http_response)
31
50
  extract_commits(response_payload)
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module CI
5
+ module Git
6
+ module Telemetry
7
+ def self.git_command(command)
8
+ Utils::Telemetry.inc(Ext::Telemetry::METRIC_GIT_COMMAND, 1, tags_for_command(command))
9
+ end
10
+
11
+ def self.git_command_errors(command, exit_code: nil, executable_missing: false)
12
+ tags = tags_for_command(command)
13
+
14
+ exit_code_tag_value = exit_code_for(exit_code: exit_code, executable_missing: executable_missing)
15
+ tags[Ext::Telemetry::TAG_EXIT_CODE] = exit_code_tag_value if exit_code_tag_value
16
+
17
+ Utils::Telemetry.inc(Ext::Telemetry::METRIC_GIT_COMMAND_ERRORS, 1, tags)
18
+ end
19
+
20
+ def self.git_command_ms(command, duration_ms)
21
+ Utils::Telemetry.distribution(Ext::Telemetry::METRIC_GIT_COMMAND_MS, duration_ms, tags_for_command(command))
22
+ end
23
+
24
+ def self.tags_for_command(command)
25
+ {Ext::Telemetry::TAG_COMMAND => command}
26
+ end
27
+
28
+ def self.exit_code_for(exit_code: nil, executable_missing: false)
29
+ return Ext::Telemetry::ExitCode::MISSING if executable_missing
30
+ return exit_code.to_s if exit_code
31
+
32
+ nil
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -8,6 +8,9 @@ require_relative "search_commits"
8
8
  require_relative "upload_packfile"
9
9
  require_relative "packfiles"
10
10
 
11
+ require_relative "../ext/telemetry"
12
+ require_relative "../utils/telemetry"
13
+
11
14
  module Datadog
12
15
  module CI
13
16
  module Git
@@ -63,12 +66,16 @@ module Datadog
63
66
  head_commit_sha: head_commit,
64
67
  repository_url: repository_url
65
68
  )
69
+ packfiles_count = 0
66
70
  Packfiles.generate(included_commits: new_commits, excluded_commits: known_commits) do |filepath|
71
+ packfiles_count += 1
67
72
  uploader.call(filepath: filepath)
68
73
  rescue UploadPackfile::ApiError => e
69
74
  Datadog.logger.debug("Packfile upload failed with #{e}")
70
75
  break
71
76
  end
77
+
78
+ Utils::Telemetry.distribution(Ext::Telemetry::METRIC_GIT_REQUESTS_OBJECT_PACK_FILES, packfiles_count.to_f)
72
79
  ensure
73
80
  Datadog.logger.debug("Git tree upload finished")
74
81
  end
@@ -3,6 +3,11 @@
3
3
  require "json"
4
4
  require "securerandom"
5
5
 
6
+ require_relative "../ext/transport"
7
+ require_relative "../ext/telemetry"
8
+ require_relative "../transport/telemetry"
9
+ require_relative "../utils/telemetry"
10
+
6
11
  module Datadog
7
12
  module CI
8
13
  module Git
@@ -34,7 +39,23 @@ module Datadog
34
39
  headers: {Ext::Transport::HEADER_CONTENT_TYPE => content_type}
35
40
  )
36
41
 
37
- raise ApiError, "Failed to upload packfile: #{http_response.inspect}" unless http_response.ok?
42
+ Transport::Telemetry.api_requests(
43
+ Ext::Telemetry::METRIC_GIT_REQUESTS_OBJECT_PACK,
44
+ 1,
45
+ compressed: http_response.request_compressed
46
+ )
47
+ Utils::Telemetry.distribution(Ext::Telemetry::METRIC_GIT_REQUESTS_OBJECT_PACK_MS, http_response.duration_ms)
48
+ Utils::Telemetry.distribution(Ext::Telemetry::METRIC_GIT_REQUESTS_OBJECT_PACK_BYTES, http_response.request_size.to_f)
49
+
50
+ unless http_response.ok?
51
+ Transport::Telemetry.api_requests_errors(
52
+ Ext::Telemetry::METRIC_GIT_REQUESTS_OBJECT_PACK_ERRORS,
53
+ 1,
54
+ error_type: http_response.telemetry_error_type,
55
+ status_code: http_response.code
56
+ )
57
+ raise ApiError, "Failed to upload packfile: #{http_response.inspect}"
58
+ end
38
59
  end
39
60
 
40
61
  private
@@ -3,6 +3,7 @@
3
3
  require "json"
4
4
 
5
5
  require_relative "span"
6
+ require_relative "test_optimisation/telemetry"
6
7
  require_relative "utils/test_run"
7
8
 
8
9
  module Datadog
@@ -80,9 +81,13 @@ module Datadog
80
81
  #
81
82
  # @return [void]
82
83
  def itr_unskippable!
84
+ TestOptimisation::Telemetry.itr_unskippable
83
85
  set_tag(Ext::Test::TAG_ITR_UNSKIPPABLE, "true")
86
+
84
87
  if skipped_by_itr?
85
88
  clear_tag(Ext::Test::TAG_ITR_SKIPPED_BY_ITR)
89
+
90
+ TestOptimisation::Telemetry.itr_forced_run
86
91
  set_tag(Ext::Test::TAG_ITR_FORCED_RUN, "true")
87
92
  end
88
93
  end
@@ -5,14 +5,17 @@ require "pp"
5
5
  require "datadog/core/utils/forking"
6
6
 
7
7
  require_relative "../ext/test"
8
+ require_relative "../ext/telemetry"
8
9
  require_relative "../ext/transport"
9
10
 
10
11
  require_relative "../git/local_repository"
11
12
 
12
13
  require_relative "../utils/parsing"
14
+ require_relative "../utils/telemetry"
13
15
 
14
16
  require_relative "coverage/event"
15
17
  require_relative "skippable"
18
+ require_relative "telemetry"
16
19
 
17
20
  module Datadog
18
21
  module CI
@@ -104,15 +107,20 @@ module Datadog
104
107
 
105
108
  def start_coverage(test)
106
109
  return if !enabled? || !code_coverage?
107
-
110
+ Telemetry.code_coverage_started(test)
108
111
  coverage_collector&.start
109
112
  end
110
113
 
111
114
  def stop_coverage(test)
112
115
  return if !enabled? || !code_coverage?
113
116
 
117
+ Telemetry.code_coverage_finished(test)
118
+
114
119
  coverage = coverage_collector&.stop
115
- return if coverage.nil? || coverage.empty?
120
+ if coverage.nil? || coverage.empty?
121
+ Telemetry.code_coverage_is_empty
122
+ return
123
+ end
116
124
 
117
125
  return if test.skipped?
118
126
 
@@ -121,6 +129,8 @@ module Datadog
121
129
  # cucumber's gherkin files are not covered by the code coverage collector
122
130
  ensure_test_source_covered(test_source_file, coverage) unless test_source_file.nil?
123
131
 
132
+ Telemetry.code_coverage_files(coverage.size)
133
+
124
134
  event = Coverage::Event.new(
125
135
  test_id: test.id.to_s,
126
136
  test_suite_id: test.test_suite_id.to_s,
@@ -162,6 +172,8 @@ module Datadog
162
172
  end
163
173
 
164
174
  @mutex.synchronize do
175
+ Telemetry.itr_skipped
176
+
165
177
  @skipped_tests_count += 1
166
178
  end
167
179
  end
@@ -229,6 +241,8 @@ module Datadog
229
241
  Datadog.logger.debug { "Fetched skippable tests: \n #{@skippable_tests}" }
230
242
  Datadog.logger.debug { "Found #{@skippable_tests.count} skippable tests." }
231
243
  Datadog.logger.debug { "ITR correlation ID: #{@correlation_id}" }
244
+
245
+ Utils::Telemetry.inc(Ext::Telemetry::METRIC_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS, @skippable_tests.count)
232
246
  end
233
247
 
234
248
  def code_coverage_mode
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "event"
4
+ require_relative "../../ext/telemetry"
4
5
  require_relative "../../transport/event_platform_transport"
6
+ require_relative "../../transport/telemetry"
5
7
 
6
8
  module Datadog
7
9
  module CI
@@ -10,6 +12,10 @@ module Datadog
10
12
  class Transport < Datadog::CI::Transport::EventPlatformTransport
11
13
  private
12
14
 
15
+ def telemetry_endpoint_tag
16
+ Ext::Telemetry::Endpoint::CODE_COVERAGE
17
+ end
18
+
13
19
  def send_payload(encoded_payload)
14
20
  api.citestcov_request(
15
21
  path: Ext::Transport::TEST_COVERAGE_INTAKE_PATH,
@@ -19,7 +25,10 @@ module Datadog
19
25
 
20
26
  def encode_events(events)
21
27
  events.filter_map do |event|
22
- next unless event.valid?
28
+ unless event.valid?
29
+ CI::Transport::Telemetry.endpoint_payload_dropped(1, endpoint: telemetry_endpoint_tag)
30
+ next
31
+ end
23
32
 
24
33
  encoded = encoder.encode(event)
25
34
  next if event_too_large?(event, encoded)
@@ -2,9 +2,12 @@
2
2
 
3
3
  require "json"
4
4
 
5
+ require_relative "../ext/telemetry"
5
6
  require_relative "../ext/transport"
6
7
  require_relative "../ext/test"
8
+ require_relative "../transport/telemetry"
7
9
  require_relative "../utils/test_run"
10
+ require_relative "../utils/telemetry"
8
11
 
9
12
  module Datadog
10
13
  module CI
@@ -75,6 +78,27 @@ module Datadog
75
78
  payload: request_payload
76
79
  )
77
80
 
81
+ Transport::Telemetry.api_requests(
82
+ Ext::Telemetry::METRIC_ITR_SKIPPABLE_TESTS_REQUEST,
83
+ 1,
84
+ compressed: http_response.request_compressed
85
+ )
86
+ Utils::Telemetry.distribution(Ext::Telemetry::METRIC_ITR_SKIPPABLE_TESTS_REQUEST_MS, http_response.duration_ms)
87
+ Utils::Telemetry.distribution(
88
+ Ext::Telemetry::METRIC_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES,
89
+ http_response.response_size.to_f,
90
+ {Ext::Telemetry::TAG_RESPONSE_COMPRESSED => http_response.gzipped_content?.to_s}
91
+ )
92
+
93
+ unless http_response.ok?
94
+ Transport::Telemetry.api_requests_errors(
95
+ Ext::Telemetry::METRIC_ITR_SKIPPABLE_TESTS_REQUEST_ERRORS,
96
+ 1,
97
+ error_type: http_response.telemetry_error_type,
98
+ status_code: http_response.code
99
+ )
100
+ end
101
+
78
102
  Response.new(http_response)
79
103
  end
80
104