# 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