datadog-ci 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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