Module: Wurk::Metrics::DashboardSeries
- Included in:
- Query
- Defined in:
- lib/wurk/metrics/dashboard_series.rb
Overview
Wurk's dashboard JSON reads, extended onto Metrics::Query as class
methods: flat rows gap-filled with zeros so a chart has a continuous
x-axis, and Query::WindowTooWide instead of upstream's silent clamp so
the API can answer 400. The Sidekiq-shaped API is Query's instance side.
Constant Summary collapse
- TOTAL_FIELDS =
%w[p f ms].freeze
- TOTAL_KINDS =
{ 'p' => :p, 'f' => :f, 'ms' => :ms }.freeze
- NO_FIELD =
[nil, nil].freeze
- TOP_JOBS_SLICE =
Buckets per pipelined read in #top_jobs. A 30-day window is 4320 buckets of every class's fields; reading and folding a day at a time keeps one day's replies in memory instead of the whole month's.
144
Instance Method Summary collapse
-
#for_job(klass, minutes: nil, hours: nil, now: ::Time.now) ⇒ Object
Dashboard per-class series, oldest→newest, gap-filled:
[{at:, p:, f:, ms:}, …]. -
#history(bucket, window_seconds, now: ::Time.now) ⇒ Object
Cluster-total time-series for the dashboard throughput/failures charts, read from the compact buckets written by Wurk::Metrics::Rollup.
-
#queue_history(bucket, window_seconds, queues: nil, now: ::Time.now) ⇒ Object
Per-queue size/latency gauge time-series written by Metrics::QueueRollup.
-
#top_jobs(class_filter: nil, minutes: 60, hours: nil, now: ::Time.now) ⇒ Object
Dashboard top-N:
[[klass, {p:, f:, ms:}], …]over the window, busiest (p, which counts failures) first.
Instance Method Details
#for_job(klass, minutes: nil, hours: nil, now: ::Time.now) ⇒ Object
Dashboard per-class series, oldest→newest, gap-filled:
[{at:, p:, f:, ms:}, …]. minutes: gives one row per minute,
hours: one per 10-minute bucket.
35 36 37 38 39 |
# File 'lib/wurk/metrics/dashboard_series.rb', line 35 def for_job(klass, minutes: nil, hours: nil, now: ::Time.now) validate_for_job!(klass, minutes, hours) stamps, keys = window_buckets(minutes, hours, now) pfms_rows(stamps, pipeline_hmget(keys, TOTAL_FIELDS.map { |f| "#{klass}|#{f}" })) end |
#history(bucket, window_seconds, now: ::Time.now) ⇒ Object
Cluster-total time-series for the dashboard throughput/failures charts,
read from the compact buckets written by Wurk::Metrics::Rollup. bucket
is '1m'/'5m'/'1h'; window_seconds is clamped to that bucket's
retention. Returns [{at:, p:, f:, ms:}, ...] oldest→newest, gap-filled
with zeros so a chart has a continuous x-axis.
46 47 48 49 50 |
# File 'lib/wurk/metrics/dashboard_series.rb', line 46 def history(bucket, window_seconds, now: ::Time.now) step, ttl = bucket_spec!(bucket) starts = bucket_starts(now, step, clamp_history_window!(window_seconds, ttl)) pfms_rows(starts, pipeline_hmget(starts.map { |s| Rollup.bucket_key(bucket, s) }, TOTAL_FIELDS)) end |
#queue_history(bucket, window_seconds, queues: nil, now: ::Time.now) ⇒ Object
Per-queue size/latency gauge time-series written by
Metrics::QueueRollup. Returns one entry per live queue (or the
explicit queues: list, capped at MAX_QUEUE_SERIES) —
[{name:, points: [{at:, size:, latency:}, …]}, …] — oldest→newest,
gap-filled with zeros.
57 58 59 60 61 62 63 64 65 |
# File 'lib/wurk/metrics/dashboard_series.rb', line 57 def queue_history(bucket, window_seconds, queues: nil, now: ::Time.now) step, ttl = bucket_spec!(bucket) starts = bucket_starts(now, step, clamp_history_window!(window_seconds, ttl)) names = queue_names(queues) return [] if names.empty? rows = queue_bucket_rows(bucket, starts, names) names.each_with_index.map { |name, i| { name: name, points: queue_points(i, starts, rows) } } end |
#top_jobs(class_filter: nil, minutes: 60, hours: nil, now: ::Time.now) ⇒ Object
Dashboard top-N: [[klass, {p:, f:, ms:}], …] over the window,
busiest (p, which counts failures) first. class_filter is a
class-name prefix. Sums straight off the buckets rather than through
Query#top_jobs, whose per-bucket series a table never shows.
25 26 27 28 29 30 |
# File 'lib/wurk/metrics/dashboard_series.rb', line 25 def top_jobs(class_filter: nil, minutes: 60, hours: nil, now: ::Time.now) _stamps, keys = window_buckets(minutes, hours, now) rows = sum_totals(keys).to_a rows.select! { |(klass, _)| klass.start_with?(class_filter) } if class_filter && !class_filter.empty? rows.sort_by { |(_k, sums)| -sums[:p] } end |