Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SDTEST-160] API metrics #206

Merged
merged 8 commits into from
Jul 29, 2024
4 changes: 1 addition & 3 deletions lib/datadog/ci/ext/telemetry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ module Telemetry
TAG_RESPONSE_COMPRESSED = "rs_compressed"
TAG_COMMAND = "command"
TAG_COVERAGE_ENABLED = "coverage_enabled"
TAG_ITR_ENABLED = "itr_enabled"
TAG_ITR_SKIP_ENABLED = "itr_skip_enabled"
TAG_REQUIRE_GIT = "require_git"
TAG_ITR_SKIP_ENABLED = "itrskip_enabled"
TAG_PROVIDER = "provider"
TAG_AUTO_INJECTED = "auto_injected"

Expand Down
21 changes: 20 additions & 1 deletion lib/datadog/ci/git/search_commits.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
require "json"
require "set"

require_relative "../ext/telemetry"
require_relative "../ext/transport"
require_relative "../transport/telemetry"
require_relative "../utils/git"
require_relative "../utils/telemetry"

module Datadog
module CI
Expand All @@ -25,7 +28,23 @@ def call(repository_url, commits)
path: Ext::Transport::DD_API_GIT_SEARCH_COMMITS_PATH,
payload: request_payload(repository_url, commits)
)
raise ApiError, "Failed to search commits: #{http_response.inspect}" unless http_response.ok?

Transport::Telemetry.api_requests(
Ext::Telemetry::METRIC_GIT_REQUESTS_SEARCH_COMMITS,
1,
compressed: http_response.request_compressed
)
Utils::Telemetry.distribution(Ext::Telemetry::METRIC_GIT_REQUESTS_SEARCH_COMMITS_MS, http_response.duration_ms)

unless http_response.ok?
Transport::Telemetry.api_requests_errors(
Ext::Telemetry::METRIC_GIT_REQUESTS_SEARCH_COMMITS_ERRORS,
1,
error_type: http_response.telemetry_error_type,
status_code: http_response.code
)
raise ApiError, "Failed to search commits: #{http_response.inspect}"
end

response_payload = parse_json_response(http_response)
extract_commits(response_payload)
Expand Down
7 changes: 7 additions & 0 deletions lib/datadog/ci/git/tree_uploader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
require_relative "upload_packfile"
require_relative "packfiles"

require_relative "../ext/telemetry"
require_relative "../utils/telemetry"

module Datadog
module CI
module Git
Expand Down Expand Up @@ -63,12 +66,16 @@ def call(repository_url)
head_commit_sha: head_commit,
repository_url: repository_url
)
packfiles_count = 0
Packfiles.generate(included_commits: new_commits, excluded_commits: known_commits) do |filepath|
packfiles_count += 1
uploader.call(filepath: filepath)
rescue UploadPackfile::ApiError => e
Datadog.logger.debug("Packfile upload failed with #{e}")
break
end

Utils::Telemetry.distribution(Ext::Telemetry::METRIC_GIT_REQUESTS_OBJECT_PACK_FILES, packfiles_count.to_f)
ensure
Datadog.logger.debug("Git tree upload finished")
end
Expand Down
23 changes: 22 additions & 1 deletion lib/datadog/ci/git/upload_packfile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
require "json"
require "securerandom"

require_relative "../ext/transport"
require_relative "../ext/telemetry"
require_relative "../transport/telemetry"
require_relative "../utils/telemetry"

module Datadog
module CI
module Git
Expand Down Expand Up @@ -34,7 +39,23 @@ def call(filepath:)
headers: {Ext::Transport::HEADER_CONTENT_TYPE => content_type}
)

raise ApiError, "Failed to upload packfile: #{http_response.inspect}" unless http_response.ok?
Transport::Telemetry.api_requests(
Ext::Telemetry::METRIC_GIT_REQUESTS_OBJECT_PACK,
1,
compressed: http_response.request_compressed
)
Utils::Telemetry.distribution(Ext::Telemetry::METRIC_GIT_REQUESTS_OBJECT_PACK_MS, http_response.duration_ms)
Utils::Telemetry.distribution(Ext::Telemetry::METRIC_GIT_REQUESTS_OBJECT_PACK_BYTES, http_response.request_size.to_f)

unless http_response.ok?
Transport::Telemetry.api_requests_errors(
Ext::Telemetry::METRIC_GIT_REQUESTS_OBJECT_PACK_ERRORS,
1,
error_type: http_response.telemetry_error_type,
status_code: http_response.code
)
raise ApiError, "Failed to upload packfile: #{http_response.inspect}"
end
end

private
Expand Down
4 changes: 4 additions & 0 deletions lib/datadog/ci/test_optimisation/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
require "datadog/core/utils/forking"

require_relative "../ext/test"
require_relative "../ext/telemetry"
require_relative "../ext/transport"

require_relative "../git/local_repository"

require_relative "../utils/parsing"
require_relative "../utils/telemetry"

require_relative "coverage/event"
require_relative "skippable"
Expand Down Expand Up @@ -239,6 +241,8 @@ def fetch_skippable_tests(test_session:, git_tree_upload_worker:)
Datadog.logger.debug { "Fetched skippable tests: \n #{@skippable_tests}" }
Datadog.logger.debug { "Found #{@skippable_tests.count} skippable tests." }
Datadog.logger.debug { "ITR correlation ID: #{@correlation_id}" }

Utils::Telemetry.inc(Ext::Telemetry::METRIC_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS, @skippable_tests.count)
end

def code_coverage_mode
Expand Down
24 changes: 24 additions & 0 deletions lib/datadog/ci/test_optimisation/skippable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

require "json"

require_relative "../ext/telemetry"
require_relative "../ext/transport"
require_relative "../ext/test"
require_relative "../transport/telemetry"
require_relative "../utils/test_run"
require_relative "../utils/telemetry"

module Datadog
module CI
Expand Down Expand Up @@ -75,6 +78,27 @@ def fetch_skippable_tests(test_session)
payload: request_payload
)

Transport::Telemetry.api_requests(
Ext::Telemetry::METRIC_ITR_SKIPPABLE_TESTS_REQUEST,
1,
compressed: http_response.request_compressed
)
Utils::Telemetry.distribution(Ext::Telemetry::METRIC_ITR_SKIPPABLE_TESTS_REQUEST_MS, http_response.duration_ms)
Utils::Telemetry.distribution(
Ext::Telemetry::METRIC_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES,
http_response.response_size.to_f,
{Ext::Telemetry::TAG_RESPONSE_COMPRESSED => http_response.gzipped_content?.to_s}
)

unless http_response.ok?
Transport::Telemetry.api_requests_errors(
Ext::Telemetry::METRIC_ITR_SKIPPABLE_TESTS_REQUEST_ERRORS,
1,
error_type: http_response.telemetry_error_type,
status_code: http_response.code
)
end

Response.new(http_response)
end

Expand Down
6 changes: 5 additions & 1 deletion lib/datadog/ci/transport/adapters/net.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class Response

attr_reader :http_response
# Stats for telemetry
attr_accessor :request_compressed, :request_size
attr_accessor :duration_ms, :request_compressed, :request_size

def initialize(http_response)
@http_response = http_response
Expand All @@ -81,6 +81,10 @@ def payload
@decompressed_payload = Gzip.decompress(http_response.body)
end

def response_size
http_response.body.bytesize
end

def header(name)
http_response[name]
end
Expand Down
10 changes: 2 additions & 8 deletions lib/datadog/ci/transport/event_platform_transport.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

require "datadog/core/encoding"
require "datadog/core/chunker"
require "datadog/core/utils/time"

require_relative "telemetry"

Expand Down Expand Up @@ -49,18 +48,13 @@ def send_events(events)
end
Telemetry.endpoint_payload_events_count(chunk.count, endpoint: telemetry_endpoint_tag)

response = nil
# @type var request_duration_ms: Float
request_duration_ms = Core::Utils::Time.measure(:float_millisecond) do
response = send_payload(encoded_payload)
end
# @type var response: Datadog::CI::Transport::Adapters::Net::Response
response = send_payload(encoded_payload)

Telemetry.endpoint_payload_requests(
1,
endpoint: telemetry_endpoint_tag, compressed: response.request_compressed
)
Telemetry.endpoint_payload_requests_ms(request_duration_ms, endpoint: telemetry_endpoint_tag)
Telemetry.endpoint_payload_requests_ms(response.duration_ms, endpoint: telemetry_endpoint_tag)
Telemetry.endpoint_payload_bytes(response.request_size, endpoint: telemetry_endpoint_tag)

# HTTP layer could send events and exhausted retries (if any)
Expand Down
38 changes: 24 additions & 14 deletions lib/datadog/ci/transport/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
require "delegate"
require "socket"

require "datadog/core/utils/time"

require_relative "gzip"
require_relative "adapters/net"
require_relative "../ext/transport"
Expand Down Expand Up @@ -39,29 +41,37 @@ def request(
backoff: INITIAL_BACKOFF,
accept_compressed_response: false
)
if compress
headers[Ext::Transport::HEADER_CONTENT_ENCODING] = Ext::Transport::CONTENT_ENCODING_GZIP
payload = Gzip.compress(payload)
end
response = nil

if accept_compressed_response
headers[Ext::Transport::HEADER_ACCEPT_ENCODING] = Ext::Transport::CONTENT_ENCODING_GZIP
end
duration_ms = Core::Utils::Time.measure(:float_millisecond) do
if compress
headers[Ext::Transport::HEADER_CONTENT_ENCODING] = Ext::Transport::CONTENT_ENCODING_GZIP
payload = Gzip.compress(payload)
end

Datadog.logger.debug do
"Sending #{verb} request: host=#{host}; port=#{port}; ssl_enabled=#{ssl}; " \
"compression_enabled=#{compress}; path=#{path}; payload_size=#{payload.size}"
end
if accept_compressed_response
headers[Ext::Transport::HEADER_ACCEPT_ENCODING] = Ext::Transport::CONTENT_ENCODING_GZIP
end

Datadog.logger.debug do
"Sending #{verb} request: host=#{host}; port=#{port}; ssl_enabled=#{ssl}; " \
"compression_enabled=#{compress}; path=#{path}; payload_size=#{payload.size}"
end

response = perform_http_call(path: path, payload: payload, headers: headers, verb: verb, retries: retries, backoff: backoff)
response = perform_http_call(path: path, payload: payload, headers: headers, verb: verb, retries: retries, backoff: backoff)

Datadog.logger.debug do
"Received server response: #{response.inspect}"
Datadog.logger.debug do
"Received server response: #{response.inspect}"
end
end
# @type var response: Datadog::CI::Transport::Adapters::Net::Response
# @type var duration_ms: Float

# set some stats about the request
response.request_compressed = compress
response.request_size = payload.bytesize
response.duration_ms = duration_ms

response
end

Expand Down
40 changes: 39 additions & 1 deletion lib/datadog/ci/transport/remote_settings_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

require "datadog/core/environment/identity"

require_relative "../ext/telemetry"
require_relative "../ext/transport"
require_relative "../transport/telemetry"
require_relative "../utils/parsing"
require_relative "../utils/telemetry"

module Datadog
module CI
Expand Down Expand Up @@ -36,6 +39,14 @@ def payload
default_payload
rescue JSON::ParserError => e
Datadog.logger.error("Failed to parse settings response payload: #{e}. Payload was: #{resp.payload}")

Transport::Telemetry.api_requests_errors(
Ext::Telemetry::METRIC_GIT_REQUESTS_SETTINGS_ERRORS,
1,
error_type: "invalid_json",
status_code: nil
)

@json = default_payload
end
end
Expand Down Expand Up @@ -69,7 +80,34 @@ def fetch_library_settings(test_session)
payload: request_payload
)

Response.new(http_response)
Transport::Telemetry.api_requests(
Ext::Telemetry::METRIC_GIT_REQUESTS_SETTINGS,
1,
compressed: http_response.request_compressed
)
Utils::Telemetry.distribution(Ext::Telemetry::METRIC_GIT_REQUESTS_SETTINGS_MS, http_response.duration_ms)

unless http_response.ok?
Transport::Telemetry.api_requests_errors(
Ext::Telemetry::METRIC_GIT_REQUESTS_SETTINGS_ERRORS,
1,
error_type: http_response.telemetry_error_type,
status_code: http_response.code
)
end

response = Response.new(http_response)

Utils::Telemetry.inc(
Ext::Telemetry::METRIC_GIT_REQUESTS_SETTINGS_RESPONSE,
1,
{
Ext::Telemetry::TAG_COVERAGE_ENABLED => response.payload[Ext::Transport::DD_API_SETTINGS_RESPONSE_CODE_COVERAGE_KEY],
Ext::Telemetry::TAG_ITR_SKIP_ENABLED => response.payload[Ext::Transport::DD_API_SETTINGS_RESPONSE_TESTS_SKIPPING_KEY]
}
)

response
end

private
Expand Down
23 changes: 20 additions & 3 deletions lib/datadog/ci/transport/telemetry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,33 @@ def self.endpoint_payload_bytes(bytesize, endpoint:)

def self.endpoint_payload_requests_errors(count, endpoint:, error_type:, status_code:)
tags = tags(endpoint: endpoint)

tags[Ext::Telemetry::TAG_ERROR_TYPE] = error_type if error_type
tags[Ext::Telemetry::TAG_STATUS_CODE] = status_code.to_s if status_code
set_error_tags(tags, error_type: error_type, status_code: status_code)

Utils::Telemetry.inc(Ext::Telemetry::METRIC_ENDPOINT_PAYLOAD_REQUESTS_ERRORS, count, tags)
end

def self.api_requests(metric_name, count, compressed:)
tags = {}
tags[Ext::Telemetry::TAG_REQUEST_COMPRESSED] = "true" if compressed

Utils::Telemetry.inc(metric_name, count, tags)
end

def self.api_requests_errors(metric_name, count, error_type:, status_code:)
tags = {}
set_error_tags(tags, error_type: error_type, status_code: status_code)

Utils::Telemetry.inc(metric_name, count, tags)
end

def self.tags(endpoint:)
{Ext::Telemetry::TAG_ENDPOINT => endpoint}
end

def self.set_error_tags(tags, error_type:, status_code:)
tags[Ext::Telemetry::TAG_ERROR_TYPE] = error_type if error_type
tags[Ext::Telemetry::TAG_STATUS_CODE] = status_code.to_s if status_code
end
end
end
end
Expand Down
6 changes: 1 addition & 5 deletions sig/datadog/ci/ext/telemetry.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,7 @@ module Datadog

TAG_COVERAGE_ENABLED: "coverage_enabled"

TAG_ITR_ENABLED: "itr_enabled"

TAG_ITR_SKIP_ENABLED: "itr_skip_enabled"

TAG_REQUIRE_GIT: "require_git"
TAG_ITR_SKIP_ENABLED: "itrskip_enabled"

TAG_PROVIDER: "provider"

Expand Down
Loading
Loading