76 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			76 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| require 'prometheus/pid_provider'
 | |
| 
 | |
| module Gitlab
 | |
|   module Utils
 | |
|     class Measuring
 | |
|       class << self
 | |
|         attr_writer :logger
 | |
| 
 | |
|         def logger
 | |
|           @logger ||= Logger.new($stdout)
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def initialize(base_log_data = {})
 | |
|         @base_log_data = base_log_data
 | |
|       end
 | |
| 
 | |
|       def with_measuring
 | |
|         result = nil
 | |
|         with_gc_stats do
 | |
|           with_count_queries do
 | |
|             with_measure_time do
 | |
|               result = yield
 | |
|             end
 | |
|           end
 | |
|         end
 | |
| 
 | |
|         log_info(
 | |
|           gc_stats: gc_stats,
 | |
|           time_to_finish: time_to_finish,
 | |
|           number_of_sql_calls: sql_calls_count,
 | |
|           memory_usage: "#{Gitlab::Metrics::System.memory_usage_rss[:total].to_f / 1024 / 1024} MiB",
 | |
|           label: ::Prometheus::PidProvider.worker_id
 | |
|         )
 | |
| 
 | |
|         result
 | |
|       end
 | |
| 
 | |
|       private
 | |
| 
 | |
|       attr_reader :gc_stats, :time_to_finish, :sql_calls_count, :base_log_data
 | |
| 
 | |
|       def with_count_queries(&block)
 | |
|         @sql_calls_count = 0
 | |
| 
 | |
|         counter_f = ->(_name, _started, _finished, _unique_id, payload) {
 | |
|           @sql_calls_count += 1 unless payload[:name].in? %w[CACHE SCHEMA]
 | |
|         }
 | |
| 
 | |
|         ActiveSupport::Notifications.subscribed(counter_f, "sql.active_record", &block)
 | |
|       end
 | |
| 
 | |
|       def with_gc_stats
 | |
|         stats = ::Gitlab::Memory::Instrumentation.start_thread_memory_allocations
 | |
|         yield
 | |
|       ensure
 | |
|         @gc_stats = ::Gitlab::Memory::Instrumentation.measure_thread_memory_allocations(stats)
 | |
|       end
 | |
| 
 | |
|       def with_measure_time
 | |
|         @time_to_finish = Benchmark.realtime do
 | |
|           yield
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def log_info(details)
 | |
|         details = base_log_data.merge(details)
 | |
|         details = details.to_yaml if ActiveSupport::Logger.logger_outputs_to?(Measuring.logger, $stdout)
 | |
|         Measuring.logger.info(details)
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| end
 |