1# frozen_string_literal: true
2
3require 'sidekiq/api'
4
5module API
6  class SidekiqMetrics < ::API::Base
7    before { authenticated_as_admin! }
8
9    feature_category :not_owned
10
11    helpers do
12      def queue_metrics
13        Sidekiq::Queue.all.each_with_object({}) do |queue, hash|
14          hash[queue.name] = {
15            backlog: queue.size,
16            latency: queue.latency.to_i
17          }
18        end
19      end
20
21      def process_metrics
22        Sidekiq::ProcessSet.new(false).map do |process|
23          {
24            hostname:    process['hostname'],
25            pid:         process['pid'],
26            tag:         process['tag'],
27            started_at:  Time.at(process['started_at']),
28            queues:      process['queues'],
29            labels:      process['labels'],
30            concurrency: process['concurrency'],
31            busy:        process['busy']
32          }
33        end
34      end
35
36      def job_stats
37        stats = Sidekiq::Stats.new
38        {
39          processed: stats.processed,
40          failed: stats.failed,
41          enqueued: stats.enqueued,
42          dead: stats.dead_size
43        }
44      end
45    end
46
47    desc 'Get the Sidekiq queue metrics'
48    get 'sidekiq/queue_metrics' do
49      { queues: queue_metrics }
50    end
51
52    desc 'Get the Sidekiq process metrics'
53    get 'sidekiq/process_metrics' do
54      { processes: process_metrics }
55    end
56
57    desc 'Get the Sidekiq job statistics'
58    get 'sidekiq/job_stats' do
59      { jobs: job_stats }
60    end
61
62    desc 'Get the Sidekiq Compound metrics. Includes queue, process, and job statistics'
63    get 'sidekiq/compound_metrics' do
64      { queues: queue_metrics, processes: process_metrics, jobs: job_stats }
65    end
66  end
67end
68