1
0
Fork 0
mirror of https://github.com/mperham/sidekiq.git synced 2022-11-09 13:52:34 -05:00
mperham--sidekiq/test/test_metrics.rb
Mike Perham f220897db9
Per-job execution metrics (#5384)
* New execution stats data format, #5283

We store time and counts per-queue, per-class and totals, daily.

* break metrics into separate jobs and queues hashes

* tweak

* Move metrics tracking to middleware, start work on Query API

* Add support for labeled points in time

* Add fetch method for deploy marks

* rejigger metrics file layout

* fix tests

* Remove per-queue metrics, adds a lot of complexity with little value IMO

* store per-minute histograms

* Keep basic stats hardwired as is

The idea being that metrics are optional middleware as they have significantly more overhead in CPU time and Redis space.

* Implement top N metrics dashboard

* Add topN and job-specific metric pages

* Supply histogram data to job metrics page

* cant use local time as CI is in a different tz

* Add basic metrics graph, refactor dashboard JS to make Rickshaw reuseable

* prepare for public beta
2022-07-28 12:21:42 -07:00

141 lines
4.3 KiB
Ruby

# frozen_string_literal: true
require_relative "helper"
require "sidekiq/component"
require "sidekiq/metrics/tracking"
require "sidekiq/metrics/query"
require "sidekiq/metrics/deploy"
require "sidekiq/api"
describe Sidekiq::Metrics do
before do
Sidekiq.redis { |c| c.flushdb }
end
def fixed_time
@whence ||= Time.utc(2022, 7, 22, 22, 3, 0)
end
def create_known_metrics(time = fixed_time)
smet = Sidekiq::Metrics::ExecutionTracker.new(Sidekiq)
smet.track("critical", "App::SomeJob") { sleep 0.001 }
smet.track("critical", "App::FooJob") { sleep 0.001 }
assert_raises RuntimeError do
smet.track("critical", "App::SomeJob") do
raise "boom"
end
end
smet.flush(time)
smet.track("critical", "App::FooJob") { sleep 0.001 }
smet.track("critical", "App::FooJob") { sleep 0.025 }
smet.track("critical", "App::FooJob") { sleep 0.001 }
smet.track("critical", "App::SomeJob") { sleep 0.001 }
smet.flush(time - 60)
end
it "tracks metrics" do
count = create_known_metrics
assert_equal 12, count
end
describe "marx" do
it "owns the means of production" do
whence = Time.local(2022, 7, 17, 18, 43, 15)
floor = whence.utc.rfc3339.sub(":15", ":00")
d = Sidekiq::Metrics::Deploy.new
d.mark(at: whence, label: "cafed00d - some git summary line")
q = Sidekiq::Metrics::Query.new(now: whence)
rs = q.for_job("FooJob")
refute_nil rs[:marks]
assert_equal 1, rs[:marks].size
assert_equal "cafed00d - some git summary line", rs[:marks][floor], rs.inspect
d = Sidekiq::Metrics::Deploy.new
rs = d.fetch(whence)
refute_nil rs
assert_equal 1, rs.size
assert_equal "cafed00d - some git summary line", rs[floor]
end
end
describe "histograms" do
it "buckets a bunch of times" do
h = Sidekiq::Metrics::Histogram.new("App::FooJob")
assert_equal 0, h.sum
h.record_time(10)
h.record_time(46)
h.record_time(47)
h.record_time(48)
h.record_time(300)
h.record_time(301)
h.record_time(302)
h.record_time(300000000)
assert_equal 8, h.sum
key = Sidekiq.redis do |conn|
h.persist(conn, fixed_time)
end
assert_equal 0, h.sum
refute_nil key
assert_equal "App::FooJob-22-22:3", key
h = Sidekiq::Metrics::Histogram.new("App::FooJob")
data = Sidekiq.redis { |c| h.fetch(c, fixed_time) }
{0 => 1, 3 => 3, 7 => 3, 25 => 1}.each_pair do |idx, val|
assert_equal val, data[idx]
end
end
end
describe "querying" do
it "handles empty metrics" do
q = Sidekiq::Metrics::Query.new(now: fixed_time)
rs = q.top_jobs
refute_nil rs
assert_equal 8, rs.size
q = Sidekiq::Metrics::Query.new(now: fixed_time)
rs = q.for_job("DoesntExist")
refute_nil rs
assert_equal 7, rs.size
end
it "fetches top job data" do
create_known_metrics
q = Sidekiq::Metrics::Query.new(now: fixed_time)
rs = q.top_jobs
assert_equal Date.new(2022, 7, 22), rs[:date]
assert_equal 2, rs[:job_classes].size
assert_equal "App::SomeJob", rs[:job_classes].first
bucket = rs[:totals]
refute_nil bucket
assert_equal bucket.keys.sort, ["App::FooJob|ms", "App::FooJob|p", "App::SomeJob|f", "App::SomeJob|ms", "App::SomeJob|p"]
assert_equal 3, bucket["App::SomeJob|p"]
assert_equal 4, bucket["App::FooJob|p"]
assert_equal 1, bucket["App::SomeJob|f"]
end
it "fetches job-specific data" do
create_known_metrics
d = Sidekiq::Metrics::Deploy.new
d.mark(at: fixed_time - 300, label: "cafed00d - some git summary line")
q = Sidekiq::Metrics::Query.new(now: fixed_time)
rs = q.for_job("App::FooJob")
assert_equal Date.new(2022, 7, 22), rs[:date]
assert_equal 60, rs[:data].size
assert_equal ["2022-07-22T21:58:00Z", "cafed00d - some git summary line"], rs[:marks].first
data = rs[:data]
assert_equal({time: "2022-07-22T22:03:00Z", p: 1, f: 0}, data[0].slice(:time, :p, :f))
assert_equal({time: "2022-07-22T22:02:00Z", p: 3, f: 0}, data[1].slice(:time, :p, :f))
assert_equal "cafed00d - some git summary line", data[5][:mark]
# from create_known_data
hist = data[1][:hist]
assert_equal 2, hist[0]
assert_equal 1, hist[1]
end
end
end