Commit a8d92d6c authored by Paul Asmuth's avatar Paul Asmuth
Browse files

gauge calculations for three-dim gauges

parent 6d55e940
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -61,7 +61,10 @@ class FnordMetric::App < Sinatra::Base

    gauge = current_namespace.gauges.fetch(params[:name].intern)

    data = if params[:at] && params[:at] =~ /^[0-9]+$/
    data = if gauge.three_dimensional?
      _t = (params[:at] || Time.now).to_i
      
    elsif params[:at] && params[:at] =~ /^[0-9]+$/
      { (_t = gauge.tick_at(params[:at].to_i)) => gauge.value_at(_t) }
    elsif params[:at] && params[:at] =~ /^([0-9]+)-([0-9]+)$/
      _range = params[:at].split("-").map(&:to_i)
+4 −0
Original line number Diff line number Diff line
@@ -35,6 +35,10 @@ class FnordMetric::Gauge
    !@opts[:three_dimensional]
  end

  def three_dimensional?
    !!@opts[:three_dimensional]
  end

  def progressive?
    !!@opts[:progressive]
  end
+15 −0
Original line number Diff line number Diff line
@@ -45,6 +45,21 @@ module FnordMetric::GaugeCalculations
    end
  end

  def field_values_at(time, opts={}, &block)
    opts[:max_fields] ||= 50
    redis.zrevrange(
      tick_key(time), 
      0, opts[:max_fields]-1, 
      :withscores => true
    ).in_groups_of(2).map do |key, val|
      [key, calculate_value(val, time, opts, block)]
    end
  end

  def field_values_total(time)
    (redis.get(tick_key(time, :count))||0).to_i
  end

  def redis
    @opts[:redis]
  end
+20 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ describe "app" do
        widget 'Blubb', nil

        gauge :testgauge, :tick => 1.hour.to_i, :progressive => true
        gauge :test3gauge, :tick => 1.hour.to_i, :three_dimensional => true

      }
    }, @opts)
@@ -456,5 +457,24 @@ describe "app" do

  end

  describe "three-dim gauges api" do

    before(:all) do
      @redis.keys("fnordmetric-foospace*").each { |k| @redis.del(k) }  
      gauge_key = "fnordmetric-foospace-gauge-test3gauge-#{1.hour.to_i}-1323691200"
      @redis.zadd(gauge_key, 18, "fnordyblubb")  
      @redis.zadd(gauge_key, 23, "uberfoo")  
      @redis.set(gauge_key+"-count", 41)
    end

    it "should return the right answer for: /metric/:name?at=timestamp" do      
      get "/foospace/gauge/test3gauge?at=1323691205"
      JSON.parse(last_response.body)["count"].to_i.should == 41
      JSON.parse(last_response.body)["values"].length.should == 2
      JSON.parse(last_response.body)["values"][0].should == ["ubefoo", 23]
      JSON.parse(last_response.body)["values"][1].should == ["fnordyblubb", 18]
    end

  end

end
 No newline at end of file
+73 −0
Original line number Diff line number Diff line
@@ -179,4 +179,77 @@ describe FnordMetric::Gauge do

  end
  
  describe "three-dim value retrival" do

    before(:each) do
      @gauge = FnordMetric::Gauge.new({
        :tick => 10, 
        :key_prefix => "fnordmetric-myns", 
        :three_dimensional => true,
        :key => "mygauge_966",
        :redis => @redis
      })
      @redis.keys("fnordmetric-myns*").each { |k| @redis.del(k) }  
      @gauge_key = "fnordmetric-myns-gauge-mygauge_966-10-1323691200"
      @redis.zadd(@gauge_key, 18, "fnordyblubb")  
      @redis.zadd(@gauge_key, 23, "uberfoo")  
      @redis.set(@gauge_key+"-count", 41)
    end

    it "should retrieve field_values at a given time" do
      @gauge.field_values_at(1323691200).should be_a(Array)
      @gauge.field_values_at(1323691200).length.should == 2
      @gauge.field_values_at(1323691200)[0].should == ["uberfoo", "23"]
      @gauge.field_values_at(1323691200)[1].should == ["fnordyblubb", "18"]
    end

    it "should retrieve the correct total count" do
      @gauge.field_values_total(1323691200).should == 41
    end

    it "should retrieve max 50 fields per default" do
      70.times{ |n| @redis.zadd(@gauge_key, 23, "field#{n}") }
      @gauge.field_values_at(1323691200).should be_a(Array)
      @gauge.field_values_at(1323691200).length.should == 50
    end

    it "should retrieve more than 50 fields if requested" do
      70.times{ |n| @redis.zadd(@gauge_key, 23, "field#{n}") }
      @gauge.field_values_at(1323691200, :max_fields => 60).should be_a(Array)
      @gauge.field_values_at(1323691200, :max_fields => 60).length.should == 60
    end

    it "should retrieve all fields if requested" do
      70.times{ |n| @redis.zadd(@gauge_key, 23, "field#{n}") }
      @gauge.field_values_at(1323691200, :max_fields => 0).should be_a(Array)
      @gauge.field_values_at(1323691200, :max_fields => 0).length.should == 72
    end

    it "should call the value calculation block and return the result" do
      vals = @gauge.field_values_at(1323691200){ |v| v.to_i + 123 }
      vals.should be_a(Array)
      vals.length.should == 2
      vals[0].should == ["uberfoo", 146]
      vals[1].should == ["fnordyblubb", 141]
    end

    it "should return the correct field_values per session with avg" do
      @redis.set(@gauge_key+"-sessions-count", "3")
      @gauge = FnordMetric::Gauge.new({
        :tick => 10, 
        :key_prefix => "fnordmetric-myns", 
        :three_dimensional => true,
        :unique => true,
        :average => true,
        :key => "mygauge_966",
        :redis => @redis
      })
      vals = @gauge.field_values_at(1323691200)
      vals.should be_a(Array)
      vals.length.should == 2
      vals[0].should == ["uberfoo", 23/3.0]
      vals[1].should == ["fnordyblubb", 18/3.0]
    end

  end
end
 No newline at end of file