Skip to content

Instantly share code, notes, and snippets.

@eric
Created February 4, 2012 06:40
Show Gist options
  • Save eric/1735890 to your computer and use it in GitHub Desktop.
Save eric/1735890 to your computer and use it in GitHub Desktop.
require 'lazy'
require 'system_timer'
class ScoutMetric
M60_ALPHA = (1 - Math.exp(-5.minutes / 1.hour.to_f))
NS_IN_SECONDS = 1000000000
def initialize(metric_id, timeout = 5)
@metric_id = metric_id
@timeout = timeout
@start = 6.hours.ago
@cache = {}
end
def metric
@metric ||= with_timeout { Scout::Metric.first(@metric_id) }
end
def timeseries
@timeseries ||= Lazy.future do
begin
m = Lazy.demand(metric)
with_timeout { m.average(:start => @start).to_array }
rescue Exception
[]
end
end
end
def trend_value
@trend_value ||= Lazy.future do
ts = Lazy.demand(timeseries)
values = ts.collect { |(time, value)| value }
rate = change_per_hour(values)
end
end
def change_per_hour(values)
rate, rates = nil, []
values.each_cons(2) do |first, second|
current_rate = (second - first).to_f / 5.minutes / NS_IN_SECONDS
if rate
rate += (M60_ALPHA * (current_rate - rate))
else
rate = current_rate
end
rates << rate
end
rate *= NS_IN_SECONDS * 1.hour if rate
rate
end
def with_timeout(&block)
SystemTimer.timeout_after(@timeout, Timeout::Error, &block)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment