gitlab-org--gitlab-foss/app/services/merge_requests/mergeability/logger.rb

90 lines
2.3 KiB
Ruby

# frozen_string_literal: true
module MergeRequests
module Mergeability
class Logger
include Gitlab::Utils::StrongMemoize
def initialize(merge_request:, destination: Gitlab::AppJsonLogger)
@destination = destination
@merge_request = merge_request
end
def commit
commit_logs
end
def instrument(mergeability_name:)
raise ArgumentError, 'block not given' unless block_given?
op_start_db_counters = current_db_counter_payload
op_started_at = current_monotonic_time
result = yield
observe("mergeability.#{mergeability_name}.duration_s", current_monotonic_time - op_started_at)
observe_sql_counters(mergeability_name, op_start_db_counters, current_db_counter_payload)
result
end
private
attr_reader :destination, :merge_request
def observe(name, value)
observations[name.to_s].push(value)
end
def commit_logs
attributes = Gitlab::ApplicationContext.current.merge({ mergeability_project_id: merge_request.project.id })
attributes[:mergeability_merge_request_id] = merge_request.id
attributes.merge!(observations_hash)
attributes.compact!
attributes.stringify_keys!
destination.info(attributes)
end
def observations_hash
transformed = observations.transform_values do |values|
next if values.empty?
{
'values' => values
}
end.compact
transformed.each_with_object({}) do |key, hash|
key[1].each { |k, v| hash["#{key[0]}.#{k}"] = v }
end
end
def observations
strong_memoize(:observations) do
Hash.new { |hash, key| hash[key] = [] }
end
end
def observe_sql_counters(name, start_db_counters, end_db_counters)
end_db_counters.each do |key, value|
result = value - start_db_counters.fetch(key, 0)
next if result == 0
observe("mergeability.#{name}.#{key}", result)
end
end
def current_db_counter_payload
::Gitlab::Metrics::Subscribers::ActiveRecord.db_counter_payload
end
def current_monotonic_time
::Gitlab::Metrics::System.monotonic_time
end
end
end
end