Class: SidekiqPrometheus::PeriodicMetrics
- Inherits:
-
Object
- Object
- SidekiqPrometheus::PeriodicMetrics
- Defined in:
- lib/sidekiq_prometheus/periodic_metrics.rb
Overview
Report Sidekiq::Stats to prometheus on a defined interval
Global Metrics reporting requires Sidekiq::Enterprise as it uses the leader election functionality to ensure that the global metrics are only reported by one worker.
Defined Under Namespace
Classes: Senate
Constant Summary collapse
- GLOBAL_STATS =
%i[failed processed retry_size dead_size scheduled_size workers_size].freeze
- GC_STATS =
{ counters: %i[major_gc_count minor_gc_count total_allocated_objects], gauges: %i[heap_live_slots heap_free_slots], }.freeze
- REDIS_STATS =
%w[connected_clients used_memory used_memory_peak].freeze
Instance Attribute Summary collapse
-
#done ⇒ Boolean
When
true
will stop the reporting loop. -
#interval ⇒ Integer
readonly
Interval in seconds to record metrics.
-
#senate ⇒ Object
readonly
Returns the value of attribute senate.
-
#sidekiq_queue ⇒ Object
readonly
Returns the value of attribute sidekiq_queue.
-
#sidekiq_stats ⇒ Object
readonly
Returns the value of attribute sidekiq_stats.
Class Method Summary collapse
-
.reporter ⇒ SidekiqPrometheus:PeriodicMetrics
Instance of SidekiqPrometheus::PeriodicMetrics.
Instance Method Summary collapse
-
#initialize(interval: SidekiqPrometheus.periodic_reporting_interval, sidekiq_stats: Sidekiq::Stats, sidekiq_queue: Sidekiq::Queue, senate: nil) ⇒ PeriodicMetrics
constructor
A new instance of PeriodicMetrics.
-
#report_gc_metrics ⇒ Object
Record GC and RSS metrics.
-
#report_global_metrics ⇒ Object
Records Sidekiq global metrics.
-
#report_redis_metrics ⇒ Object
Records metrics from Redis.
-
#rss ⇒ Object
Fetch rss from proc filesystem.
-
#run ⇒ Object
Report metrics and sleep for @interval seconds in a loop.
-
#start ⇒ Object
Start the period mettric reporter.
-
#stop ⇒ Object
Stop the periodic metric reporter.
Constructor Details
#initialize(interval: SidekiqPrometheus.periodic_reporting_interval, sidekiq_stats: Sidekiq::Stats, sidekiq_queue: Sidekiq::Queue, senate: nil) ⇒ PeriodicMetrics
Returns a new instance of PeriodicMetrics.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/sidekiq_prometheus/periodic_metrics.rb', line 39 def initialize(interval: SidekiqPrometheus.periodic_reporting_interval, sidekiq_stats: Sidekiq::Stats, sidekiq_queue: Sidekiq::Queue, senate: nil) self.done = false @interval = interval @sidekiq_stats = sidekiq_stats @sidekiq_queue = sidekiq_queue @senate = if senate.nil? if Object.const_defined?('Sidekiq::Senate') Sidekiq::Senate else Senate end else senate end end |
Instance Attribute Details
#done ⇒ Boolean
Returns When true
will stop the reporting loop.
15 16 17 |
# File 'lib/sidekiq_prometheus/periodic_metrics.rb', line 15 def done @done end |
#interval ⇒ Integer (readonly)
Returns Interval in seconds to record metrics. Default: [SidekiqPrometheus.periodic_reporting_interval].
18 19 20 |
# File 'lib/sidekiq_prometheus/periodic_metrics.rb', line 18 def interval @interval end |
#senate ⇒ Object (readonly)
Returns the value of attribute senate.
19 20 21 |
# File 'lib/sidekiq_prometheus/periodic_metrics.rb', line 19 def senate @senate end |
#sidekiq_queue ⇒ Object (readonly)
Returns the value of attribute sidekiq_queue.
19 20 21 |
# File 'lib/sidekiq_prometheus/periodic_metrics.rb', line 19 def sidekiq_queue @sidekiq_queue end |
#sidekiq_stats ⇒ Object (readonly)
Returns the value of attribute sidekiq_stats.
19 20 21 |
# File 'lib/sidekiq_prometheus/periodic_metrics.rb', line 19 def sidekiq_stats @sidekiq_stats end |
Class Method Details
.reporter ⇒ SidekiqPrometheus:PeriodicMetrics
Instance of SidekiqPrometheus::PeriodicMetrics
31 32 33 |
# File 'lib/sidekiq_prometheus/periodic_metrics.rb', line 31 def self.reporter @reporter ||= new end |
Instance Method Details
#report_gc_metrics ⇒ Object
Record GC and RSS metrics
71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/sidekiq_prometheus/periodic_metrics.rb', line 71 def report_gc_metrics stats = GC.stat GC_STATS[:counters].each do |stat| SidekiqPrometheus["sidekiq_#{stat}"]&.increment(labels: {}, by: stats[stat]) end GC_STATS[:gauges].each do |stat| SidekiqPrometheus["sidekiq_#{stat}"]&.set(stats[stat], labels: {}) end SidekiqPrometheus[:sidekiq_rss]&.set(rss, labels: {}) end |
#report_global_metrics ⇒ Object
Records Sidekiq global metrics
85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/sidekiq_prometheus/periodic_metrics.rb', line 85 def report_global_metrics current_stats = sidekiq_stats.new GLOBAL_STATS.each do |stat| SidekiqPrometheus["sidekiq_#{stat}"]&.set(current_stats.send(stat), labels: {}) end sidekiq_queue.all.each do |queue| SidekiqPrometheus[:sidekiq_enqueued]&.set(queue.size, labels: { queue: queue.name }) SidekiqPrometheus[:sidekiq_queue_latency]&.observe(queue.latency, labels: { queue: queue.name }) end end |
#report_redis_metrics ⇒ Object
Records metrics from Redis
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/sidekiq_prometheus/periodic_metrics.rb', line 99 def report_redis_metrics redis_info = begin Sidekiq.redis_info rescue Redis::BaseConnectionError nil end return if redis_info.nil? REDIS_STATS.each do |stat| SidekiqPrometheus["sidekiq_redis_#{stat}"]&.set(redis_info[stat].to_i, labels: {}) end db_stats = redis_info.select { |k, _v| k.match(/^db/) } db_stats.each do |db, stat| label = { database: db } values = stat.scan(/\d+/) SidekiqPrometheus[:sidekiq_redis_keys]&.set(values[0].to_i, labels: label) SidekiqPrometheus[:sidekiq_redis_expires]&.set(values[1].to_i, labels: label) end end |
#rss ⇒ Object
Fetch rss from proc filesystem
124 125 126 127 128 |
# File 'lib/sidekiq_prometheus/periodic_metrics.rb', line 124 def rss pid = Process.pid @pagesize ||= `getconf PAGESIZE`.to_i rescue 4096 File.read("/proc/#{pid}/statm").split(' ')[1].to_i * @pagesize rescue 0 end |
#run ⇒ Object
Report metrics and sleep for @interval seconds in a loop. Runs until @done is true
133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/sidekiq_prometheus/periodic_metrics.rb', line 133 def run until done begin report_global_metrics if SidekiqPrometheus.global_metrics_enabled? && senate.leader? report_redis_metrics if SidekiqPrometheus.global_metrics_enabled? && senate.leader? report_gc_metrics if SidekiqPrometheus.gc_metrics_enabled? rescue StandardError => e Sidekiq.logger.error e ensure sleep interval end end end |
#start ⇒ Object
Start the period mettric reporter
58 59 60 61 |
# File 'lib/sidekiq_prometheus/periodic_metrics.rb', line 58 def start Sidekiq.logger.info('SidekiqPrometheus: Starting periodic metrics reporting') @thread = Thread.new(&method(:run)) end |
#stop ⇒ Object
Stop the periodic metric reporter
65 66 67 |
# File 'lib/sidekiq_prometheus/periodic_metrics.rb', line 65 def stop self.done = true end |