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



113
114
115
116
117
118
119
120
121
122
# File 'lib/gitlab_monitor/sidekiq.rb', line 113

def probe_dead
  puts "[DEPRECATED] probe_dead is now considered obsolete and will be removed in future major versions,"\
       " please use probe_stats instead"

  return self unless connected?

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

  self
end

#probe_jobsObject

rubocop:disable Metrics/MethodLength



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

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



43
44
45
46
47
48
49
50
51
52
53
# File 'lib/gitlab_monitor/sidekiq.rb', line 43

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



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/gitlab_monitor/sidekiq.rb', line 97

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_statsObject



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/gitlab_monitor/sidekiq.rb', line 24

def probe_stats
  return self unless connected?

  stats = Sidekiq::Stats.new

  @metrics.add("sidekiq_jobs_processed_total", stats.processed)
  @metrics.add("sidekiq_jobs_failed_total", stats.failed)
  @metrics.add("sidekiq_jobs_enqueued_size", stats.enqueued)
  @metrics.add("sidekiq_jobs_scheduled_size", stats.scheduled_size)
  @metrics.add("sidekiq_jobs_retry_size", stats.retry_size)
  @metrics.add("sidekiq_jobs_dead_size", stats.dead_size)

  @metrics.add("sidekiq_default_queue_latency_seconds", stats.default_queue_latency)
  @metrics.add("sidekiq_processes_size", stats.processes_size)
  @metrics.add("sidekiq_workers_size", stats.workers_size)

  self
end

#probe_workersObject



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

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



124
125
126
# File 'lib/gitlab_monitor/sidekiq.rb', line 124

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