107 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| require 'sidekiq/api'
 | |
| 
 | |
| module API
 | |
|   class SidekiqMetrics < ::API::Base
 | |
|     before { authenticated_as_admin! }
 | |
| 
 | |
|     feature_category :not_owned # rubocop:todo Gitlab/AvoidFeatureCategoryNotOwned
 | |
| 
 | |
|     helpers do
 | |
|       def queue_metrics
 | |
|         hash = {}
 | |
|         Gitlab::SidekiqSharding::Router.with_routed_client do
 | |
|           queue_metrics_from_shard.each do |queue_name, queue_details|
 | |
|             if hash[queue_name].nil?
 | |
|               hash[queue_name] = queue_details
 | |
|             else
 | |
|               hash[queue_name][:backlog] += queue_details[:backlog]
 | |
|               hash[queue_name][:latency] = [queue_details[:latency], hash[queue_name][:latency]].max
 | |
|             end
 | |
|           end
 | |
|         end
 | |
|         hash
 | |
|       end
 | |
| 
 | |
|       def queue_metrics_from_shard
 | |
|         ::Gitlab::SidekiqConfig.routing_queues.each_with_object({}) do |queue_name, hash|
 | |
|           queue = Sidekiq::Queue.new(queue_name)
 | |
|           hash[queue.name] = {
 | |
|             backlog: queue.size,
 | |
|             latency: queue.latency.to_i
 | |
|           }
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def process_metrics
 | |
|         metrics = []
 | |
|         Gitlab::SidekiqSharding::Router.with_routed_client do
 | |
|           metrics << process_metrics_from_shard
 | |
|         end
 | |
|         metrics.flatten
 | |
|       end
 | |
| 
 | |
|       def process_metrics_from_shard
 | |
|         Sidekiq::ProcessSet.new(false).map do |process|
 | |
|           {
 | |
|             hostname: process['hostname'],
 | |
|             pid: process['pid'],
 | |
|             tag: process['tag'],
 | |
|             started_at: Time.at(process['started_at']),
 | |
|             queues: process['queues'],
 | |
|             labels: process['labels'],
 | |
|             concurrency: process['concurrency'],
 | |
|             busy: process['busy']
 | |
|           }
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def job_stats
 | |
|         stats = {
 | |
|           processed: 0,
 | |
|           failed: 0,
 | |
|           enqueued: 0,
 | |
|           dead: 0
 | |
|         }
 | |
| 
 | |
|         Gitlab::SidekiqSharding::Router.with_routed_client do
 | |
|           job_stats_from_shard.each { |k, v| stats[k] += v }
 | |
|         end
 | |
| 
 | |
|         stats
 | |
|       end
 | |
| 
 | |
|       def job_stats_from_shard
 | |
|         stats = Sidekiq::Stats.new
 | |
|         {
 | |
|           processed: stats.processed,
 | |
|           failed: stats.failed,
 | |
|           enqueued: stats.enqueued,
 | |
|           dead: stats.dead_size
 | |
|         }
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     desc 'Get the Sidekiq queue metrics'
 | |
|     get 'sidekiq/queue_metrics' do
 | |
|       { queues: queue_metrics }
 | |
|     end
 | |
| 
 | |
|     desc 'Get the Sidekiq process metrics'
 | |
|     get 'sidekiq/process_metrics' do
 | |
|       { processes: process_metrics }
 | |
|     end
 | |
| 
 | |
|     desc 'Get the Sidekiq job statistics'
 | |
|     get 'sidekiq/job_stats' do
 | |
|       { jobs: job_stats }
 | |
|     end
 | |
| 
 | |
|     desc 'Get the Sidekiq Compound metrics. Includes queue, process, and job statistics'
 | |
|     get 'sidekiq/compound_metrics' do
 | |
|       { queues: queue_metrics, processes: process_metrics, jobs: job_stats }
 | |
|     end
 | |
|   end
 | |
| end
 |