fnordmetric 0.3.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/Gemfile +6 -0
  2. data/Gemfile.lock +21 -0
  3. data/Procfile +1 -2
  4. data/VERSION +1 -1
  5. data/_spec/app_spec.rb +178 -0
  6. data/{spec → _spec}/cache_spec.rb +0 -0
  7. data/{spec → _spec}/combine_metric_spec.rb +0 -0
  8. data/{spec → _spec}/core_spec.rb +0 -0
  9. data/{spec → _spec}/count_metric_spec.rb +0 -0
  10. data/_spec/dashboard_spec.rb +67 -0
  11. data/_spec/event_spec.rb +46 -0
  12. data/{spec → _spec}/metric_spec.rb +0 -0
  13. data/{spec → _spec}/report_spec.rb +0 -0
  14. data/{spec → _spec}/sum_metric_spec.rb +0 -0
  15. data/_spec/widget_spec.rb +107 -0
  16. data/doc/import_dump.rb +26 -0
  17. data/em_runner.rb +33 -0
  18. data/fnordmetric.gemspec +59 -20
  19. data/haml/app.haml +26 -12
  20. data/lib/fnordmetric.rb +150 -15
  21. data/lib/fnordmetric/app.rb +70 -11
  22. data/lib/fnordmetric/cache.rb +4 -4
  23. data/lib/fnordmetric/context.rb +65 -0
  24. data/lib/fnordmetric/dashboard.rb +16 -12
  25. data/lib/fnordmetric/event.rb +65 -15
  26. data/lib/fnordmetric/gauge.rb +46 -0
  27. data/lib/fnordmetric/gauge_calculations.rb +43 -0
  28. data/lib/fnordmetric/gauge_modifiers.rb +43 -0
  29. data/lib/fnordmetric/inbound_stream.rb +66 -0
  30. data/lib/fnordmetric/logger.rb +38 -0
  31. data/lib/fnordmetric/namespace.rb +120 -0
  32. data/lib/fnordmetric/numbers_widget.rb +29 -11
  33. data/lib/fnordmetric/session.rb +131 -0
  34. data/lib/fnordmetric/standalone.rb +31 -0
  35. data/lib/fnordmetric/timeline_widget.rb +29 -9
  36. data/lib/fnordmetric/widget.rb +50 -45
  37. data/lib/fnordmetric/worker.rb +80 -0
  38. data/pub/fnordmetric/fnordmetric.css +76 -9
  39. data/pub/fnordmetric/fnordmetric.js +541 -42
  40. data/pub/raphael-min.js +8 -0
  41. data/pub/raphael-utils.js +221 -0
  42. data/readme.rdoc +172 -27
  43. data/server.rb +22 -0
  44. data/spec/app_spec.rb +359 -117
  45. data/spec/context_spec.rb +42 -0
  46. data/spec/dashboard_spec.rb +7 -47
  47. data/spec/event_spec.rb +114 -33
  48. data/spec/gauge_modifiers_spec.rb +276 -0
  49. data/spec/gauge_spec.rb +128 -0
  50. data/spec/namespace_spec.rb +104 -0
  51. data/spec/session_spec.rb +231 -0
  52. data/spec/spec_helper.rb +27 -4
  53. data/spec/widget_spec.rb +81 -75
  54. data/spec/worker_spec.rb +37 -0
  55. data/test_stream.sh +187 -0
  56. data/ulm_stats.rb +198 -0
  57. metadata +114 -35
  58. data/lib/fnordmetric/core.rb +0 -66
  59. data/lib/fnordmetric/engine.rb +0 -3
@@ -0,0 +1,42 @@
1
+ require ::File.expand_path('../spec_helper.rb', __FILE__)
2
+
3
+ describe FnordMetric::Context do
4
+
5
+ before(:all) do
6
+ @redis = Redis.new
7
+ @redis_wrap = RedisWrap.new(@redis)
8
+ end
9
+
10
+ before(:each) do
11
+ @redis.keys("fnordmetrictest*").each { |k| @redis.del(k) }
12
+ end
13
+
14
+ it "should fetch a gauge by key"
15
+ it "should fetch a gauge by gauge"
16
+ it "should raise an error if unable to fetch a gauge"
17
+
18
+ it "should expose the current session_key" do
19
+ ns = FnordMetric::Namespace.new(
20
+ :myns_253,
21
+ :redis_prefix => "fnordmetrictest"
22
+ )
23
+ ns.opt_event(:fnordbar, {}) do
24
+ session_key.should == "145d3f6dee1a770e3a3c550b3993dc81"
25
+ end
26
+ ns.ready!(@redis_wrap).announce(
27
+ :_eid => "35r2423",
28
+ :_time => Time.now.to_i,
29
+ :_type => "fnordbar",
30
+ :_session => "sess213"
31
+ )
32
+ end
33
+
34
+ it "should instance-eval the handler on call" do
35
+ Thread.current["fnord_123"] = false
36
+ my_block = proc{ Thread.current["fnord_123"] = "35r25" }
37
+ context = FnordMetric::Context.new({}, my_block)
38
+ context.call({}, nil)
39
+ Thread.current["fnord_123"].should == "35r25"
40
+ end
41
+
42
+ end
@@ -3,12 +3,10 @@ require ::File.expand_path('../spec_helper.rb', __FILE__)
3
3
  describe FnordMetric::Dashboard do
4
4
 
5
5
  before(:each) do
6
- FnordMetric::Event.destroy_all
7
- FnordMetric.reset_metrics
8
6
  end
9
7
 
10
8
  it "should remember it's title" do
11
- dashboard = FnordMetric::Dashboard.new(:title => 'My Foobar Dashboard'){ |dash| }
9
+ dashboard = FnordMetric::Dashboard.new(:title => 'My Foobar Dashboard')
12
10
  dashboard.title.should == 'My Foobar Dashboard'
13
11
  end
14
12
 
@@ -18,50 +16,12 @@ describe FnordMetric::Dashboard do
18
16
  end
19
17
 
20
18
  it "should add a widget" do
21
- dashboard = FnordMetric::Dashboard.new(:title => 'My!F00bar-.Dash_board'){ |dash| }
22
- FnordMetric.metric(:my_metric, :sum => :my_field)
23
- widget = FnordMetric.widget(:my_widget, :metrics => :my_metric, :title => "My Widget", :type => :timeline)
24
- dashboard.add_widget(widget)
25
- dashboard.widgets.first.should == widget
26
- end
27
-
28
- it "should add a widget by name" do
29
- dashboard = FnordMetric::Dashboard.new(:title => 'My!F00bar-.Dash_board'){ |dash| }
30
- FnordMetric.metric(:my_metric, :sum => :my_field)
31
- widget = FnordMetric.widget(:my_widget, :metrics => :my_metric, :title => "My Widget", :type => :timeline)
32
- dashboard.add_widget(:my_widget)
33
- dashboard.widgets.first.should == widget
34
- end
35
-
36
- it "should add the report on init (and to all widgets)" do
37
- FnordMetric.metric(:my_metric, :sum => :my_field)
38
- report = FnordMetric.report(:range => (4.days.ago..Time.now))
39
- dashboard = FnordMetric::Dashboard.new(:title => 'My Foobar Dashboard', :report => report){ |dash|
40
- dash.add_widget FnordMetric.widget(:my_widget, :metrics => :my_metric, :title => "My Widget", :type => :timeline)
41
- }
42
- dashboard.report.should == report
43
- dashboard.widgets.last.report.should == report
44
- end
45
-
46
- it "should add the report after init (and to all widgets)" do
47
- FnordMetric.metric(:my_metric, :sum => :my_field)
48
- report = FnordMetric.report(:range => (4.days.ago..Time.now))
49
- dashboard = FnordMetric::Dashboard.new(:title => 'My Foobar Dashboard'){ |dash|
50
- dash.add_widget FnordMetric.widget(:my_widget, :metrics => :my_metric, :title => "My Widget", :type => :timeline)
51
- }
52
- dashboard.report.should == nil
53
- dashboard.add_report(report)
54
- dashboard.report.should == report
55
- dashboard.widgets.last.report.should == report
56
- end
57
-
58
- it "should call the config block" do
59
- block_called = false
60
- FnordMetric::Dashboard.new(:title => 'My Dashboard') do |dash|
61
- block_called = true
62
- dash.should be_a(FnordMetric::Dashboard)
63
- end
64
- block_called.should be_true
19
+ pending("fix this")
20
+ #dashboard = FnordMetric::Dashboard.new(:title => 'My!F00bar-.Dash_board'){ |dash| }
21
+ #FnordMetric.metric(:my_metric, :sum => :my_field)
22
+ #idget = FnordMetric.widget(:my_widget, :metrics => :my_metric, :title => "My Widget", :type => :timeline)
23
+ #dashboard.add_widget(widget)
24
+ #dashboard.widgets.first.should == widget
65
25
  end
66
26
 
67
27
  end
data/spec/event_spec.rb CHANGED
@@ -1,46 +1,127 @@
1
1
  require ::File.expand_path('../spec_helper.rb', __FILE__)
2
2
 
3
- include FnordMetric
3
+ describe FnordMetric::Event do
4
4
 
5
- describe "event" do
5
+ include FnordMetric
6
6
 
7
- before(:each) do
8
- Event.destroy_all
9
- end
7
+ before(:all) do
8
+ @now = Time.utc(1992,01,13,5,23,23).to_i
9
+ @redis = Redis.new
10
+ @redis_wrap = RedisWrap.new(@redis)
10
11
 
11
- it "should track an event" do
12
- event = Event.track!('_referral', :foobar => "fnord")
13
- Event.last[:type].should == "_referral"
14
- Event.last[:foobar].should == "fnord"
15
- end
12
+ @namespace = "fnordmetric-test-ns123"
13
+ @timeline = "#{@namespace}-timeline"
16
14
 
17
- it "should track an event via the proxy method" do
18
- FnordMetric.track('blubb', :foo => "bar")
19
- FnordMetric::Event.last.foo.should == "bar"
15
+ @opts = {
16
+ :namespace_prefix => "#{@namespace}",
17
+ :redis_prefix => "fnordmetric-test",
18
+ :redis => @redis
19
+ }
20
20
  end
21
21
 
22
- it "should access info like a 'ostruct' object" do
23
- event = Event.track!('_referral', :foobar => "fnord")
24
- Event.last.type.should == "_referral"
25
- Event.last.foobar.should == "fnord"
26
- end
22
+ describe "finding events" do
27
23
 
28
- it "should insert a data point in the past" do
29
- my_time = 23.minutes.ago
30
- event = Event.track!('_referral', :foobar => "fnord", :time => my_time)
31
- Event.last[:type].should == "_referral"
32
- Event.last[:foobar].should == "fnord"
33
- Event.last[:time].should == my_time.to_i
34
- end
24
+ before(:each) do
25
+ @redis.keys("fnordmetric-test-*").each { |k| @redis.del(k) }
26
+ end
35
27
 
36
- it "should save integer data" do
37
- event = Event.track!('_test', :num => 23)
38
- Event.last.num.should == 23
39
- end
28
+ it "should find all events" do
29
+ create_event("242342", {:_type => "foo", :_time => @now})
30
+ create_event("453484", {:_type => "foo", :_time => @now})
31
+ Event.all(@opts).length.should == 2
32
+ end
33
+
34
+ it "should find all events and return event objects" do
35
+ create_event("434454", {:_type => "foo", :_time => @now})
36
+ Event.all(@opts).first.should be_a(FnordMetric::Event)
37
+ end
38
+
39
+ it "should find all events and returnevent objects with time" do
40
+ create_event("352234", {:_type => "Fn0rd", :blah => :blubb, :_time => @now})
41
+ events = Event.all(@opts)
42
+ events.first.time.to_i.should == @now
43
+ end
44
+
45
+ it "should find an event and return a event object" do
46
+ create_event("756753", {:_type => "Fn0rd", :_time => @now})
47
+ event = Event.find("756753", @opts)
48
+ event.should be_a(FnordMetric::Event)
49
+ event.type.should == "Fn0rd"
50
+ end
51
+
52
+ it "should find an event and return a event object with data" do
53
+ create_event("53454", {:_type => "Fn0rd", :blah => :blubb, :_time => @now})
54
+ event = Event.find("53454", @opts)
55
+ event.data(:blah).should == "blubb"
56
+ end
57
+
58
+ it "should find an event and return a event object with id" do
59
+ create_event("5262435", {:_type => "Fn0rd", :blah => :blubb, :_time => @now})
60
+ event = Event.find("5262435", @opts)
61
+ event.id.should == "5262435"
62
+ end
63
+
64
+ it "should find all in the correct order" do
65
+ create_event("5645642", {:_type => "foo", :_time => @now-17})
66
+ create_event("2342366", {:_type => "foo", :_time => @now-23})
67
+ create_event("3452345", {:_type => "foo", :_time => @now-42})
68
+ create_event("6345345", {:_type => "foo", :_time => @now-5})
69
+ Event.all(@opts).length.should == 4
70
+ Event.all(@opts)[0].id.should == "6345345"
71
+ Event.all(@opts)[1].id.should == "5645642"
72
+ Event.all(@opts)[2].id.should == "2342366"
73
+ Event.all(@opts)[3].id.should == "3452345"
74
+ end
75
+
76
+ it "should find all events since a given time, including that exact time" do
77
+ create_event("3452345", {:_type => "foo", :_time => @now-42})
78
+ create_event("2342366", {:_type => "foo", :_time => @now-23})
79
+ create_event("5645642", {:_type => "foo", :_time => @now-17})
80
+ create_event("6345345", {:_type => "foo", :_time => @now-5})
81
+ Event.all(@opts).length.should == 4
82
+ Event.all(@opts.merge(:since => @now-42)).length.should == 4
83
+ Event.all(@opts.merge(:since => @now-23)).length.should == 3
84
+ Event.all(@opts.merge(:since => @now-22)).length.should == 2
85
+ Event.all(@opts.merge(:since => @now-17)).length.should == 2
86
+ Event.all(@opts.merge(:since => @now-16)).length.should == 1
87
+ Event.all(@opts.merge(:since => @now-5)).length.should == 1
88
+ end
89
+
90
+ it "should find a maximum number of events" do
91
+ create_event("3452345", {:_type => "foo", :_time => @now-42})
92
+ create_event("2342366", {:_type => "foo", :_time => @now-23})
93
+ create_event("5645642", {:_type => "foo", :_time => @now-17})
94
+ create_event("6345345", {:_type => "foo", :_time => @now-5})
95
+ Event.all(@opts).length.should == 4
96
+ Event.all(@opts.merge(:limit => 2)).length.should == 2
97
+ Event.all(@opts.merge(:limit => 2)).first.id.should == "6345345"
98
+ Event.all(@opts.merge(:limit => 2)).last.id.should == "5645642"
99
+ end
100
+
101
+ it "should find all events by type" do
102
+ namespace = Namespace.new(:ns123, :redis_prefix => "fnordmetric-test")
103
+ namespace.ready!(@redis_wrap).announce(
104
+ :_type => "fn0rd",
105
+ :_time => @now
106
+ )
107
+ namespace.ready!(@redis_wrap).announce(
108
+ :_type => "f00bar",
109
+ :_time => @now
110
+ )
111
+ namespace.ready!(@redis_wrap).announce(
112
+ :_type => "fn0rd",
113
+ :_time => @now
114
+ )
115
+ Event.by_type('fn0rd', @opts).length.should == 2
116
+ Event.by_type('f00bar', @opts).length.should == 1
117
+ end
118
+
119
+ def create_event(event_id, event_data)
120
+ @redis_wrap.zadd(@timeline, event_data.delete(:_time), event_id)
121
+ @redis.set("fnordmetric-test-event-#{event_id}", event_data.to_json)
122
+ end
40
123
 
41
- it "should save float data" do
42
- event = Event.track!('_test', :num => 42.5)
43
- Event.last.num.should == 42.5
44
124
  end
45
-
125
+
126
+
46
127
  end
@@ -0,0 +1,276 @@
1
+ require ::File.expand_path('../spec_helper.rb', __FILE__)
2
+
3
+ describe FnordMetric::GaugeModifiers do
4
+
5
+ before(:all) do
6
+ @now = Time.utc(1992,01,13,5,23,23).to_i
7
+ @redis = Redis.new
8
+ @redis_wrap = RedisWrap.new(@redis)
9
+ end
10
+
11
+ before(:each) do
12
+ @redis.keys("fnordmetrics-myns*").each { |k| @redis.del(k) }
13
+ end
14
+
15
+ describe "increment non-progressive gauges" do
16
+
17
+ it "should increment a non-progressive gauge by 1" do
18
+ gauge_key = "fnordmetrics-myns-gauge-mygauge_234-10"
19
+ @redis.hset(gauge_key, "695280200", "12")
20
+ create_gauge_context({
21
+ :key => "mygauge_234",
22
+ :tick => 10,
23
+ }, proc{
24
+ incr(:mygauge_234, 1)
25
+ }).tap do |context|
26
+ event = { :_time => @now }
27
+ context.call(event, @redis_wrap)
28
+ end
29
+ @redis.hget(gauge_key, "695280200").should == "13"
30
+ end
31
+
32
+ it "should increment a non-progressive gauge by 5" do
33
+ gauge_key = "fnordmetrics-myns-gauge-mygauge_224-10"
34
+ @redis.hset(gauge_key, "695280200", "18")
35
+ create_gauge_context({
36
+ :key => "mygauge_224",
37
+ :tick => 10,
38
+ }, proc{
39
+ incr(:mygauge_224, 5)
40
+ }).tap do |context|
41
+ event = { :_time => @now }
42
+ context.call(event, @redis_wrap)
43
+ end
44
+ @redis.hget(gauge_key, "695280200").should == "23"
45
+ end
46
+
47
+ it "should increment a non-progressive gauge by event_value" do
48
+ gauge_key = "fnordmetrics-myns-gauge-mygauge_253-10"
49
+ @redis.hset(gauge_key, "695280200", "11")
50
+ create_gauge_context({
51
+ :key => "mygauge_253",
52
+ :tick => 10,
53
+ }, proc{
54
+ incr(:mygauge_253, data[:myval].to_i)
55
+ }).tap do |context|
56
+ event = { :_time => @now, :myval => "25" }
57
+ context.call(event, @redis_wrap)
58
+ end
59
+ @redis.hget(gauge_key, "695280200").should == "36"
60
+ end
61
+
62
+ end
63
+
64
+
65
+ describe "increment progressive gauges" do
66
+
67
+ it "should increment a progressive gauge by 1" do
68
+ gauge_key = "fnordmetrics-myns-gauge-mygauge_123-10"
69
+ @redis.hset(gauge_key, "695280200", "23")
70
+ @redis.set(gauge_key+"-head", "23")
71
+ create_gauge_context({
72
+ :key => "mygauge_123",
73
+ :tick => 10,
74
+ :progressive => true
75
+ }, proc{
76
+ incr(:mygauge_123, 1)
77
+ }).tap do |context|
78
+ event = { :_time => @now }
79
+ context.call(event, @redis_wrap)
80
+ end
81
+ @redis.hget(gauge_key, "695280200").should == "24"
82
+ @redis.get(gauge_key+"-head").should == "24"
83
+ end
84
+
85
+ it "should increment a progressive gauge by 5" do
86
+ gauge_key = "fnordmetrics-myns-gauge-mygauge_125-10"
87
+ @redis.hset(gauge_key, "695280200", "22")
88
+ @redis.set(gauge_key+"-head", "22")
89
+ create_gauge_context({
90
+ :key => "mygauge_125",
91
+ :tick => 10,
92
+ :progressive => true
93
+ }, proc{
94
+ incr(:mygauge_125, 5)
95
+ }).tap do |context|
96
+ event = { :_time => @now }
97
+ context.call(event, @redis_wrap)
98
+ end
99
+ @redis.hget(gauge_key, "695280200").should == "27"
100
+ @redis.get(gauge_key+"-head").should == "27"
101
+ end
102
+
103
+ it "should increment a progressive gauge by 1 and copy head" do
104
+ gauge_key = "fnordmetrics-myns-gauge-mygauge_128-10"
105
+ @redis.hdel(gauge_key, "695280200")
106
+ @redis.set(gauge_key+"-head", "17")
107
+ create_gauge_context({
108
+ :key => "mygauge_128",
109
+ :tick => 10,
110
+ :progressive => true
111
+ }, proc{
112
+ incr(:mygauge_128, 3)
113
+ }).tap do |context|
114
+ event = { :_time => @now }
115
+ context.call(event, @redis_wrap)
116
+ end
117
+ @redis.hget(gauge_key, "695280200").should == "20"
118
+ @redis.get(gauge_key+"-head").should == "20"
119
+ end
120
+
121
+ it "should increment a progressive gauge by 5 and copy head" do
122
+ gauge_key = "fnordmetrics-myns-gauge-mygauge_121-10"
123
+ @redis.hdel(gauge_key, "695280200")
124
+ @redis.set(gauge_key+"-head", "19")
125
+ create_gauge_context({
126
+ :key => "mygauge_121",
127
+ :tick => 10,
128
+ :progressive => true
129
+ }, proc{
130
+ incr(:mygauge_121, 6)
131
+ }).tap do |context|
132
+ event = { :_time => @now }
133
+ context.call(event, @redis_wrap)
134
+ end
135
+ @redis.hget(gauge_key, "695280200").should == "25"
136
+ @redis.get(gauge_key+"-head").should == "25"
137
+ end
138
+
139
+ it "should raise an error if incr is called on a 3d gauge" do
140
+ create_gauge_context({
141
+ :key => "mygauge_167",
142
+ :tick => 10,
143
+ :three_dimensional => true
144
+ }, proc{
145
+ incr(:mygauge_167, 1)
146
+ }).tap do |context|
147
+ event = { :_time => @now }
148
+ lambda{
149
+ context.call(event, @redis_wrap)
150
+ }.should raise_error(RuntimeError)
151
+ end
152
+ end
153
+
154
+ end
155
+
156
+ describe "increment uniquely by session_key" do
157
+
158
+ it "should increment_unique a non-progressive gauge" do
159
+ gauge_key = "fnordmetrics-myns-gauge-mygauge_963-10"
160
+ @redis.hset(gauge_key, "695280200", "54")
161
+ @redis.set(gauge_key+"-695280200-sessions-count", 5)
162
+ create_gauge_context({
163
+ :key => "mygauge_963",
164
+ :unique => true,
165
+ :tick => 10
166
+ }, proc{
167
+ incr(:mygauge_963, 30)
168
+ }).tap do |context|
169
+ event = { :_time => @now, :_session_key => "mysesskey" }
170
+ context.call(event, @redis_wrap)
171
+ end
172
+ @redis.hget(gauge_key, "695280200").should == "84"
173
+ @redis.get(gauge_key+"-695280200-sessions-count").should == "6"
174
+ @redis.smembers(gauge_key+"-695280200-sessions").should == ["mysesskey"]
175
+ end
176
+
177
+ it "should not increment_unique a non-progressive gauge if session is known" do
178
+ gauge_key = "fnordmetrics-myns-gauge-mygauge_966"
179
+ @redis.hset(gauge_key, "695280200", "54")
180
+ @redis.set(gauge_key+"-695280200-sessions-count", 5)
181
+ @redis.sadd(gauge_key+"-695280200-sessions", "mysesskey")
182
+ create_gauge_context({
183
+ :key => "mygauge_966",
184
+ :unique => true,
185
+ :tick => 10
186
+ }, proc{
187
+ incr(:mygauge_966, 30)
188
+ }).tap do |context|
189
+ event = { :_time => @now, :_session_key => "mysesskey" }
190
+ context.call(event, @redis_wrap)
191
+ end
192
+ @redis.hget(gauge_key, "695280200").should == "54"
193
+ @redis.get(gauge_key+"-695280200-sessions-count").should == "5"
194
+ @redis.smembers(gauge_key+"-695280200-sessions").should == ["mysesskey"]
195
+ end
196
+
197
+ it "should not increment_unique a non-progressive gauge w/o session" do
198
+ gauge_key = "fnordmetrics-myns-gauge-mygauge_966"
199
+ @redis.hset(gauge_key, "695280200", "54")
200
+ @redis.set(gauge_key+"-695280200-sessions-count", 5)
201
+ create_gauge_context({
202
+ :key => "mygauge_966",
203
+ :unique => true,
204
+ :tick => 10
205
+ }, proc{
206
+ incr(:mygauge_966, 30)
207
+ }).tap do |context|
208
+ event = { :_time => @now }
209
+ context.call(event, @redis_wrap)
210
+ end
211
+ @redis.hget(gauge_key, "695280200").should == "54"
212
+ @redis.get(gauge_key+"-695280200-sessions-count").should == "5"
213
+ @redis.smembers(gauge_key+"-695280200-sessions").should == []
214
+ end
215
+
216
+
217
+ it "should increment_unique a non-progressive gauge" do
218
+ gauge_key = "fnordmetrics-myns-gauge-mygauge_963-10"
219
+ @redis.hset(gauge_key, "695280200", "54")
220
+ @redis.set(gauge_key+"-progressive-sessions-count", 5)
221
+ create_gauge_context({
222
+ :key => "mygauge_963",
223
+ :tick => 10,
224
+ :unique => true,
225
+ :progressive => true
226
+ }, proc{
227
+ incr(:mygauge_963, 30)
228
+ }).tap do |context|
229
+ event = { :_time => @now, :_session_key => "mysesskey" }
230
+ context.call(event, @redis_wrap)
231
+ end
232
+ @redis.hget(gauge_key, "695280200").should == "84"
233
+ @redis.get(gauge_key+"-progressive-sessions-count").should == "6"
234
+ @redis.smembers(gauge_key+"-progressive-sessions").should == ["mysesskey"]
235
+ end
236
+
237
+ it "should not increment_unique a non-progressive gauge if session is known" do
238
+ gauge_key = "fnordmetrics-myns-gauge-mygauge_966"
239
+ @redis.hset(gauge_key, "695280200", "54")
240
+ @redis.set(gauge_key+"-progressive-sessions-count", 5)
241
+ @redis.sadd(gauge_key+"-progressive-sessions", "mysesskey")
242
+ create_gauge_context({
243
+ :key => "mygauge_966",
244
+ :tick => 10,
245
+ :unique => true,
246
+ :progressive => true
247
+ }, proc{
248
+ incr(:mygauge_966, 30)
249
+ }).tap do |context|
250
+ event = { :_time => @now, :_session_key => "mysesskey" }
251
+ context.call(event, @redis_wrap)
252
+ end
253
+ @redis.hget(gauge_key, "695280200").should == "54"
254
+ @redis.get(gauge_key+"-progressive-sessions-count").should == "5"
255
+ @redis.smembers(gauge_key+"-progressive-sessions").should == ["mysesskey"]
256
+ end
257
+
258
+ end
259
+
260
+ it "should increment a field on a three-dimensional gauge by 1"
261
+ it "should increment a field on a three-dimensional gauge by 5"
262
+ it "should raise an error if incr_field is called on a 2d gauge"
263
+
264
+ private
265
+
266
+ def create_gauge_context(opts, block)
267
+ gauge = FnordMetric::Gauge.new({
268
+ :key_prefix => "fnordmetrics-myns"
269
+ }.merge(opts))
270
+ FnordMetric::Context.new({
271
+ :gauges => { opts[:key].intern => gauge }
272
+ }, block)
273
+ end
274
+
275
+
276
+ end