Class: RailsOrbit::Metric
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- RailsOrbit::Metric
- Defined in:
- app/models/rails_orbit/metric.rb
Class Method Summary collapse
- .bucketed_hit_rate_series(since:, bucket_minutes:) ⇒ Object
- .bucketed_series(key, since:, bucket_minutes:, aggregate: :sum) ⇒ Object
- .compute_delta(key, window:) ⇒ Object
- .compute_hit_rate_delta(window:) ⇒ Object
- .hit_rate(hits, misses) ⇒ Object
- .record(key:, value:, dimension: nil, at: Time.current) ⇒ Object
- .sums_since(time) ⇒ Object
Class Method Details
.bucketed_hit_rate_series(since:, bucket_minutes:) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'app/models/rails_orbit/metric.rb', line 65 def self.bucketed_hit_rate_series(since:, bucket_minutes:) conn = connection seconds = bucket_minutes * 60 bucket = bucket_expression(seconds) q_since = conn.quote(since.utc.strftime("%Y-%m-%d %H:%M:%S")) q_hit = conn.quote("solid_cache.read_hit") q_miss = conn.quote("solid_cache.read_miss") sql = "SELECT #{bucket} AS bucket, " \ "SUM(CASE WHEN key = #{q_hit} THEN value ELSE 0 END) AS hits, " \ "SUM(CASE WHEN key = #{q_miss} THEN value ELSE 0 END) AS misses " \ "FROM #{conn.quote_table_name(table_name)} " \ "WHERE key IN (#{q_hit}, #{q_miss}) AND recorded_at >= #{q_since} " \ "GROUP BY bucket ORDER BY bucket" conn.select_all(sql).rows.map do |row| { t: row[0].to_s, v: hit_rate(row[1].to_f, row[2].to_f) } end end |
.bucketed_series(key, since:, bucket_minutes:, aggregate: :sum) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'app/models/rails_orbit/metric.rb', line 51 def self.bucketed_series(key, since:, bucket_minutes:, aggregate: :sum) conn = connection seconds = bucket_minutes * 60 agg_fn = aggregate == :avg ? "AVG" : "SUM" bucket = bucket_expression(seconds) sql = "SELECT #{bucket} AS bucket, #{agg_fn}(value) AS val " \ "FROM #{conn.quote_table_name(table_name)} " \ "WHERE key = #{conn.quote(key)} AND recorded_at >= #{conn.quote(since.utc.strftime('%Y-%m-%d %H:%M:%S'))} " \ "GROUP BY bucket ORDER BY bucket" conn.select_all(sql).rows.map { |row| { t: row[0].to_s, v: row[1].to_f.round(1) } } end |
.compute_delta(key, window:) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 |
# File 'app/models/rails_orbit/metric.rb', line 25 def self.compute_delta(key, window:) now = Time.current current = where(recorded_at: (now - window)..now).for_key(key).sum(:value).to_i previous = where(recorded_at: (now - window * 2)..(now - window)).for_key(key).sum(:value).to_i return { value: 0, direction: :flat } if previous.zero? && current.zero? return { value: 100, direction: :up } if previous.zero? pct = (((current - previous).to_f / previous) * 100).round(0) direction = pct.positive? ? :up : (pct.negative? ? :down : :flat) { value: pct.abs, direction: direction } end |
.compute_hit_rate_delta(window:) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'app/models/rails_orbit/metric.rb', line 37 def self.compute_hit_rate_delta(window:) now = Time.current cur_hits = where(recorded_at: (now - window)..now).for_key("solid_cache.read_hit").sum(:value).to_f cur_misses = where(recorded_at: (now - window)..now).for_key("solid_cache.read_miss").sum(:value).to_f prev_hits = where(recorded_at: (now - window * 2)..(now - window)).for_key("solid_cache.read_hit").sum(:value).to_f prev_misses = where(recorded_at: (now - window * 2)..(now - window)).for_key("solid_cache.read_miss").sum(:value).to_f cur_rate = hit_rate(cur_hits, cur_misses) prev_rate = hit_rate(prev_hits, prev_misses) diff = (cur_rate - prev_rate).round(1) direction = diff.positive? ? :up : (diff.negative? ? :down : :flat) { value: diff.abs, direction: direction } end |
.hit_rate(hits, misses) ⇒ Object
16 17 18 19 |
# File 'app/models/rails_orbit/metric.rb', line 16 def self.hit_rate(hits, misses) total = hits.to_f + misses.to_f total.zero? ? 0.0 : ((hits / total) * 100).round(1) end |
.record(key:, value:, dimension: nil, at: Time.current) ⇒ Object
12 13 14 |
# File 'app/models/rails_orbit/metric.rb', line 12 def self.record(key:, value:, dimension: nil, at: Time.current) create!(key: key, value: value, dimension: dimension, recorded_at: at) end |
.sums_since(time) ⇒ Object
21 22 23 |
# File 'app/models/rails_orbit/metric.rb', line 21 def self.sums_since(time) since(time).group(:key).sum(:value) end |