Class: GitLab::Monitor::SidekiqProber

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab_monitor/sidekiq.rb

Overview

A prober for Sidekiq queues

It takes the Redis URL Sidekiq is connected to

Constant Summary collapse

QUEUE_JOB_STATS_SCRIPT =
File.read(File.expand_path("#{__FILE__}/../sidekiq_queue_job_stats.lua")).freeze
QUEUE_JOB_STATS_SHA =
Digest::SHA1.hexdigest(QUEUE_JOB_STATS_SCRIPT).freeze

Instance Method Summary collapse

Constructor Details

#initialize(opts, metrics: PrometheusMetrics.new) ⇒ SidekiqProber

Returns a new instance of SidekiqProber.



13
14
15
16
17
18
19
20
21
22
# File 'lib/gitlab_monitor/sidekiq.rb', line 13

def initialize(opts, metrics: PrometheusMetrics.new)
  @opts    = opts
  @metrics = metrics

  Sidekiq.configure_client do |config|
    config.redis = redis_options
  end

  ensure_queue_job_stats_script_loaded
end

Instance Method Details

#probe_deadObject



94
95
96
97
98
99
100
# File 'lib/gitlab_monitor/sidekiq.rb', line 94

def probe_dead
  return self unless connected?

  @metrics.add("sidekiq_dead_jobs", Sidekiq::Stats.new.dead_size)

  self
end

#probe_jobsObject

rubocop:disable Metrics/MethodLength



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/gitlab_monitor/sidekiq.rb', line 36

def probe_jobs # rubocop:disable Metrics/MethodLength
  return self unless connected?

  job_stats = {}

  Sidekiq::Queue.all.each do |queue|
    begin
      Sidekiq.redis do |conn|
        stats = conn.evalsha(QUEUE_JOB_STATS_SHA, ["queue:#{queue.name}"])
        job_stats.merge!(stats.to_h)
      end
    rescue Redis::CommandError # Could happen if the script exceeded the maximum run time (5 seconds by default)
      # FIXME: Should we call SCRIPT KILL?
      return self
    end
  end

  job_stats.each do |class_name, count|
    @metrics.add("sidekiq_enqueued_jobs", count, name: class_name)
  end

  self
end

#probe_queuesObject



24
25
26
27
28
29
30
31
32
33
34
# File 'lib/gitlab_monitor/sidekiq.rb', line 24

def probe_queues
  return self unless connected?

  Sidekiq::Queue.all.each do |queue|
    @metrics.add("sidekiq_queue_size", queue.size, name: queue.name)
    @metrics.add("sidekiq_queue_latency_seconds", queue.latency, name: queue.name)
    @metrics.add("sidekiq_queue_paused", queue.paused? ? 1 : 0, name: queue.name)
  end

  self
end

#probe_retriesObject



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/gitlab_monitor/sidekiq.rb', line 78

def probe_retries
  return self unless connected?

  retry_stats = Hash.new(0)

  Sidekiq::RetrySet.new.map do |job|
    retry_stats[job.klass] += 1
  end

  retry_stats.each do |class_name, count|
    @metrics.add("sidekiq_to_be_retried_jobs", count, name: class_name)
  end

  self
end

#probe_workersObject



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/gitlab_monitor/sidekiq.rb', line 60

def probe_workers
  return self unless connected?

  worker_stats = Hash.new(0)

  Sidekiq::Workers.new.map do |_pid, _tid, work|
    job_klass = work["payload"]["class"]

    worker_stats[job_klass] += 1
  end

  worker_stats.each do |class_name, count|
    @metrics.add("sidekiq_running_jobs", count, name: class_name)
  end

  self
end

#write_to(target) ⇒ Object



102
103
104
# File 'lib/gitlab_monitor/sidekiq.rb', line 102

def write_to(target)
  target.write(@metrics.to_s)
end