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

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