class Sidekiq::Metrics::Query

Allows caller to query for Sidekiq execution metrics within Redis. Caller sets a set of attributes to act as filters. {#fetch} will call Redis and return a Hash of results.

NB: all metrics and times/dates are UTC only. We specifically do not support timezones.

Public Class Methods

new(pool: Sidekiq.redis_pool, now: Time.now) click to toggle source
# File lib/sidekiq/metrics/query.rb, line 16
def initialize(pool: Sidekiq.redis_pool, now: Time.now)
  @time = now.utc
  @pool = pool
  @klass = nil
end

Public Instance Methods

for_job(klass, minutes: 60) click to toggle source
# File lib/sidekiq/metrics/query.rb, line 52
def for_job(klass, minutes: 60)
  result = Result.new

  time = @time
  redis_results = @pool.with do |conn|
    conn.pipelined do |pipe|
      minutes.times do |idx|
        key = "j|#{time.strftime("%Y%m%d")}|#{time.hour}:#{time.min}"
        pipe.hmget key, "#{klass}|ms", "#{klass}|p", "#{klass}|f"
        result.prepend_bucket time
        time -= 60
      end
    end
  end

  time = @time
  @pool.with do |conn|
    redis_results.each do |(ms, p, f)|
      result.job_results[klass].add_metric "ms", time, ms.to_i if ms
      result.job_results[klass].add_metric "p", time, p.to_i if p
      result.job_results[klass].add_metric "f", time, f.to_i if f
      result.job_results[klass].add_hist time, Histogram.new(klass).fetch(conn, time)
      time -= 60
    end
  end

  result.marks = fetch_marks(result.starts_at..result.ends_at)

  result
end
top_jobs(minutes: 60) click to toggle source

Get metric data for all jobs from the last hour

# File lib/sidekiq/metrics/query.rb, line 23
def top_jobs(minutes: 60)
  result = Result.new

  time = @time
  redis_results = @pool.with do |conn|
    conn.pipelined do |pipe|
      minutes.times do |idx|
        key = "j|#{time.strftime("%Y%m%d")}|#{time.hour}:#{time.min}"
        pipe.hgetall key
        result.prepend_bucket time
        time -= 60
      end
    end
  end

  time = @time
  redis_results.each do |hash|
    hash.each do |k, v|
      kls, metric = k.split("|")
      result.job_results[kls].add_metric metric, time, v.to_i
    end
    time -= 60
  end

  result.marks = fetch_marks(result.starts_at..result.ends_at)

  result
end

Private Instance Methods

fetch_marks(time_range) click to toggle source
# File lib/sidekiq/metrics/query.rb, line 139
def fetch_marks(time_range)
  [].tap do |result|
    marks = @pool.with { |c| c.hgetall("#{@time.strftime("%Y%m%d")}-marks") }

    marks.each do |timestamp, label|
      time = Time.parse(timestamp)
      if time_range.cover? time
        result << MarkResult.new(time, label)
      end
    end
  end
end