fnordmetric 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/fnordmetric.gemspec CHANGED
@@ -13,8 +13,7 @@ Gem::Specification.new do |s|
13
13
  s.summary = %q{FnordMetric is a Ruby Event-Tracking gem on steroids}
14
14
  s.description = %q{FnordMetric is a Ruby Event-Tracking gem on steroids}
15
15
  s.licenses = ["MIT"]
16
-
17
- s.add_dependency "bson_ext", ">= 1.4.0"
16
+
18
17
  s.add_dependency "sinatra", ">= 1.2.6"
19
18
  s.add_dependency "redis", ">= 2.2.2"
20
19
  s.add_dependency "eventmachine"
data/lib/fnordmetric.rb CHANGED
@@ -47,10 +47,7 @@ module FnordMetric
47
47
  end
48
48
 
49
49
  def self.mk_redis
50
- host, port = options[:redis_url].gsub("redis://", "").split(":")
51
- redis_opts = { :host => host }
52
- redis_opts.merge!(:port => port) if port
53
- Redis.new(redis_opts)
50
+ Redis.new(:url => options[:redis_url])
54
51
  end
55
52
 
56
53
  def self.default_options(opts = {})
@@ -2,7 +2,7 @@ class FnordMetric::Namespace
2
2
 
3
3
  attr_reader :handlers, :gauges, :opts, :key, :dashboards, :flags
4
4
 
5
- @@opts = [:event, :gauge, :widget, :set_title, :hide_active_users, :hide_overview]
5
+ @@opts = [:event, :gauge, :widget, :set_title, :hide_active_users, :hide_overview, :dashboard]
6
6
  @@multi_gauges = [:timeseries_gauge, :toplist_gauge, :distribution_gauge]
7
7
 
8
8
  def initialize(key, opts)
@@ -79,9 +79,9 @@ class FnordMetric::Namespace
79
79
  @active_users_available
80
80
  end
81
81
 
82
- def dashboards(name=nil)
82
+ def dashboards(name=nil, opts = {})
83
83
  return @dashboards unless name
84
- dash = FnordMetric::Dashboard.new(:title => name)
84
+ dash = FnordMetric::Dashboard.new(opts.merge(:title => name))
85
85
  @dashboards[dash.token.to_s] ||= dash
86
86
  end
87
87
 
@@ -138,6 +138,10 @@ class FnordMetric::Namespace
138
138
  dashboards(dashboard).add_widget(widget)
139
139
  end
140
140
 
141
+ def opt_dashboard(dashboard, opts)
142
+ dashboards(dashboard, opts)
143
+ end
144
+
141
145
  def build_widget(opts)
142
146
  _gauges = [opts[:gauges]].flatten.map{ |g| @gauges.fetch(g) }
143
147
  widget_klass = "FnordMetric::#{opts.fetch(:type).to_s.capitalize}Widget"
@@ -1,3 +1,3 @@
1
1
  module FnordMetric
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -22,11 +22,11 @@ class FnordMetric::App < Sinatra::Base
22
22
  include FnordMetric::AppHelpers
23
23
  end
24
24
 
25
- def initialize(opts)
26
- @opts = opts
25
+ def initialize(opts = {})
26
+ @opts = FnordMetric.default_options(opts)
27
27
 
28
28
  @namespaces = FnordMetric.namespaces
29
- @redis = Redis.connect(:url => opts[:redis_url])
29
+ @redis = Redis.connect(:url => @opts[:redis_url])
30
30
 
31
31
  super(nil)
32
32
  end
data/readme.md CHANGED
@@ -2,12 +2,11 @@ FnordMetric
2
2
  ===========
3
3
 
4
4
  FnordMetric is a highly configurable (and pretty fast) realtime app/event
5
- tracking thing based on ruby eventmachine and redis. You define your own
6
- plotting and counting functions as ruby blocks!
5
+ tracking thing based on [ruby eventmachine](http://rubyeventmachine.com/) and [redis](http://redis.io/). You define your own
6
+ plotting and counting functions as ruby blocks! [See it in action! (RailsCasts)](http://railscasts.com/episodes/378-fnordmetric)
7
7
 
8
8
  [ ![Build status - Travis-ci](https://secure.travis-ci.org/paulasmuth/fnordmetric.png) ](http://travis-ci.org/paulasmuth/fnordmetric)
9
9
 
10
-
11
10
  [ ![Screenshot](https://github.com/paulasmuth/fnordmetric/raw/v1.0-alpha/doc/preview3.png) ](http://github.com/paulasmuth/fnordmetric)
12
11
 
13
12
 
@@ -26,8 +25,9 @@ FnordMetric.namespace :myapp do
26
25
  # timeline+plot and punchcard
27
26
  timeseries_gauge :unicorns_seen_per_hour,
28
27
  :resolution => 5.minutes,
29
- :title => "Unicorns seenper Hour",
30
- :punchcard => true
28
+ :title => "Unicorns seen per Hour",
29
+ :punchcard => true,
30
+ :series => [:num_unicorns]
31
31
 
32
32
  # on every event like { _type: 'unicorn_seen' }
33
33
  event(:unicorn_seen) do
@@ -64,11 +64,13 @@ Check out the docs in [the wiki](http://github.com/paulasmuth/fnordmetric/wiki)
64
64
  + [Blog: Monitor your Python App With FnordMetric](http://stephenholiday.com/articles/2012/monitor-your-python-app-with-fnordmetric/)
65
65
  + [Blog: FnordMetric and C (Blog/Howto)](http://johnmurray.io/log/2012/01/19/FnordMetrics-and-C%23.md)
66
66
  + [Blog: FnordMetric HowTo (russian)](http://www.pvsm.ru/ruby/2723)
67
+ + [RailsCast: FnordMetric (378)](http://railscasts.com/episodes/378-fnordmetric)
67
68
 
68
69
 
69
70
  ### More Resources
70
71
 
71
- + [PHP API for FnordMetric (github.com/leemachin/fnordmetric-php-api)](https://github.com/leemachin/fnordmetric-php-api)
72
+ + [PHP API for FnordMetric (use TCP) (github.com/leemachin/fnordmetric-php-api)](https://github.com/leemachin/fnordmetric-php-api)
73
+ + [PHP API for FnordMetric directly into Redis (github.com/votintsev/fnordmetric-php-redis)](https://github.com/votintsev/fnordmetric-php-redis)
72
74
  + [Python API for FnordMetric (github.com/sholiday/pyfnordmetric)](https://github.com/sholiday/pyfnordmetric)
73
75
  + [Another Ruby API for FnordMetric](https://github.com/savonarola/fnordmetric-client)
74
76
  + [Beanstalk Monitoring with FnordMetric](https://github.com/sholiday/fnordstalk)
@@ -93,7 +95,7 @@ FnordMetric.namespace :myapp do
93
95
  timeseries_gauge :number_of_signups,
94
96
  :group => "My Group",
95
97
  :title => "Number of Signups",
96
- :key_nouns => ["Singup", "Signups"],
98
+ :key_nouns => ["Signup", "Signups"],
97
99
  :series => [:via_twitter, :via_facebook],
98
100
  :resolution => 2.minutes
99
101
 
@@ -139,7 +141,7 @@ FnordMetric.namespace :myapp do
139
141
 
140
142
  gauge :pageviews_daily_unique, :tick => 1.day.to_i, :unique => true, :title => "Unique Visits (Daily)"
141
143
  gauge :pageviews_hourly_unique, :tick => 1.hour.to_i, :unique => true, :title => "Unique Visits (Hourly)"
142
- gauge :pageviews_monthly_unique, :tick => 40.days.to_i, :unique => true, :title => "Unique Visits (Month)"
144
+ gauge :pageviews_monthly_unique, :tick => 40.days.to_i, :unique => true, :title => "Unique Visits (Monthly)"
143
145
 
144
146
  gauge :messages_sent, :tick => 1.day.to_i, :title => "Messages (sent)"
145
147
  gauge :messages_read, :tick => 1.day.to_i, :title => "Messages (read)"
@@ -184,7 +186,7 @@ FnordMetric.namespace :myapp do
184
186
 
185
187
 
186
188
  widget 'TechStats', {
187
- :title => "Events/Second",
189
+ :title => "Events per Second",
188
190
  :type => :timeline,
189
191
  :width => 50,
190
192
  :gauges => :events_per_second,
@@ -288,7 +290,7 @@ def start_example_data_generator
288
290
  loop do
289
291
  api.event(:_type => :signup, :referrer => (rand(3) == 1 ? :twitter : :facebook))
290
292
  api.event(:_type => :search, :keyword => (%w(Donau Dampf Schiff Fahrts Kaptitaens Muetzen Staender).shuffle[0..2] * ""))
291
- api.event(:_type => :user_demography, :age => rand(15..85), :gender => (rand(2)==1 ? :female : :male) )
293
+ api.event(:_type => :user_demography, :age => [*15..85].sample, :gender => (rand(2)==1 ? :female : :male) )
292
294
  sleep (rand(10)/10.to_f)
293
295
  end
294
296
  end
data/spec/spec_helper.rb CHANGED
@@ -43,4 +43,7 @@ end
43
43
 
44
44
  def key_error_klass
45
45
  RUBY_VERSION =~ /1.9.\d/ ? KeyError : IndexError
46
- end
46
+ end
47
+
48
+ include Rack::Test::Methods
49
+ include FnordMetric
data/web/fnordmetric.css CHANGED
@@ -5,7 +5,7 @@ body {
5
5
  margin:0;
6
6
  padding:0;
7
7
  overflow-y:scroll;
8
- font: 12px/20px "Gotham Narrow" "Helvetica Neue", Helvetica, Arial, sans-serif;
8
+ font: 12px/20px "Gotham Narrow", "Helvetica Neue", Helvetica, Arial, sans-serif;
9
9
  overflow-x:hidden;
10
10
  }
11
11
 
data/web/haml/app.haml CHANGED
@@ -16,7 +16,7 @@
16
16
  %script{:src => "/js/fnordmetric.pie_widget.js", :type => "text/javascript"}
17
17
  %script{:src => "/js/fnordmetric.toplist_widget.js", :type => "text/javascript"}
18
18
  %script{:src => "/js/fnordmetric.html_widget.js", :type => "text/javascript"}
19
- %script{:src => "/js/fnordmetric.realtime_value_widget.js", :type => "text/javascript"}
19
+ %script{:src => "/js/fnordmetric.realtime_timeline_widget.js", :type => "text/javascript"}
20
20
  %script{:src => "/js/fnordmetric.timeseries_widget.js", :type => "text/javascript"}
21
21
  %script{:src => "/js/fnordmetric.overview_view.js", :type => "text/javascript"}
22
22
  %script{:src => "/js/fnordmetric.gauge_view.js", :type => "text/javascript"}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fnordmetric
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-31 00:00:00.000000000 Z
12
+ date: 2013-02-08 00:00:00.000000000 Z
13
13
  dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: bson_ext
16
- requirement: &20343380 !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: 1.4.0
22
- type: :runtime
23
- prerelease: false
24
- version_requirements: *20343380
25
14
  - !ruby/object:Gem::Dependency
26
15
  name: sinatra
27
- requirement: &20342880 !ruby/object:Gem::Requirement
16
+ requirement: &21192660 !ruby/object:Gem::Requirement
28
17
  none: false
29
18
  requirements:
30
19
  - - ! '>='
@@ -32,10 +21,10 @@ dependencies:
32
21
  version: 1.2.6
33
22
  type: :runtime
34
23
  prerelease: false
35
- version_requirements: *20342880
24
+ version_requirements: *21192660
36
25
  - !ruby/object:Gem::Dependency
37
26
  name: redis
38
- requirement: &20342420 !ruby/object:Gem::Requirement
27
+ requirement: &21190360 !ruby/object:Gem::Requirement
39
28
  none: false
40
29
  requirements:
41
30
  - - ! '>='
@@ -43,10 +32,10 @@ dependencies:
43
32
  version: 2.2.2
44
33
  type: :runtime
45
34
  prerelease: false
46
- version_requirements: *20342420
35
+ version_requirements: *21190360
47
36
  - !ruby/object:Gem::Dependency
48
37
  name: eventmachine
49
- requirement: &20342040 !ruby/object:Gem::Requirement
38
+ requirement: &21188420 !ruby/object:Gem::Requirement
50
39
  none: false
51
40
  requirements:
52
41
  - - ! '>='
@@ -54,10 +43,10 @@ dependencies:
54
43
  version: '0'
55
44
  type: :runtime
56
45
  prerelease: false
57
- version_requirements: *20342040
46
+ version_requirements: *21188420
58
47
  - !ruby/object:Gem::Dependency
59
48
  name: websocket-rack
60
- requirement: &20341500 !ruby/object:Gem::Requirement
49
+ requirement: &21185340 !ruby/object:Gem::Requirement
61
50
  none: false
62
51
  requirements:
63
52
  - - =
@@ -65,10 +54,10 @@ dependencies:
65
54
  version: 0.4.0
66
55
  type: :runtime
67
56
  prerelease: false
68
- version_requirements: *20341500
57
+ version_requirements: *21185340
69
58
  - !ruby/object:Gem::Dependency
70
59
  name: em-hiredis
71
- requirement: &20357400 !ruby/object:Gem::Requirement
60
+ requirement: &21196680 !ruby/object:Gem::Requirement
72
61
  none: false
73
62
  requirements:
74
63
  - - =
@@ -76,10 +65,10 @@ dependencies:
76
65
  version: 0.1.1
77
66
  type: :runtime
78
67
  prerelease: false
79
- version_requirements: *20357400
68
+ version_requirements: *21196680
80
69
  - !ruby/object:Gem::Dependency
81
70
  name: json
82
- requirement: &20357020 !ruby/object:Gem::Requirement
71
+ requirement: &21195740 !ruby/object:Gem::Requirement
83
72
  none: false
84
73
  requirements:
85
74
  - - ! '>='
@@ -87,10 +76,10 @@ dependencies:
87
76
  version: '0'
88
77
  type: :runtime
89
78
  prerelease: false
90
- version_requirements: *20357020
79
+ version_requirements: *21195740
91
80
  - !ruby/object:Gem::Dependency
92
81
  name: i18n
93
- requirement: &20356560 !ruby/object:Gem::Requirement
82
+ requirement: &21193800 !ruby/object:Gem::Requirement
94
83
  none: false
95
84
  requirements:
96
85
  - - ! '>='
@@ -98,10 +87,10 @@ dependencies:
98
87
  version: '0'
99
88
  type: :runtime
100
89
  prerelease: false
101
- version_requirements: *20356560
90
+ version_requirements: *21193800
102
91
  - !ruby/object:Gem::Dependency
103
92
  name: haml
104
- requirement: &20356140 !ruby/object:Gem::Requirement
93
+ requirement: &21208740 !ruby/object:Gem::Requirement
105
94
  none: false
106
95
  requirements:
107
96
  - - ! '>='
@@ -109,10 +98,10 @@ dependencies:
109
98
  version: '0'
110
99
  type: :runtime
111
100
  prerelease: false
112
- version_requirements: *20356140
101
+ version_requirements: *21208740
113
102
  - !ruby/object:Gem::Dependency
114
103
  name: rack
115
- requirement: &20355720 !ruby/object:Gem::Requirement
104
+ requirement: &21207680 !ruby/object:Gem::Requirement
116
105
  none: false
117
106
  requirements:
118
107
  - - ! '>='
@@ -120,10 +109,10 @@ dependencies:
120
109
  version: '0'
121
110
  type: :runtime
122
111
  prerelease: false
123
- version_requirements: *20355720
112
+ version_requirements: *21207680
124
113
  - !ruby/object:Gem::Dependency
125
114
  name: rack-test
126
- requirement: &20355300 !ruby/object:Gem::Requirement
115
+ requirement: &21205940 !ruby/object:Gem::Requirement
127
116
  none: false
128
117
  requirements:
129
118
  - - ! '>='
@@ -131,10 +120,10 @@ dependencies:
131
120
  version: '0'
132
121
  type: :runtime
133
122
  prerelease: false
134
- version_requirements: *20355300
123
+ version_requirements: *21205940
135
124
  - !ruby/object:Gem::Dependency
136
125
  name: yajl-ruby
137
- requirement: &20354880 !ruby/object:Gem::Requirement
126
+ requirement: &21217620 !ruby/object:Gem::Requirement
138
127
  none: false
139
128
  requirements:
140
129
  - - ! '>='
@@ -142,10 +131,10 @@ dependencies:
142
131
  version: '0'
143
132
  type: :runtime
144
133
  prerelease: false
145
- version_requirements: *20354880
134
+ version_requirements: *21217620
146
135
  - !ruby/object:Gem::Dependency
147
136
  name: thin
148
- requirement: &20354380 !ruby/object:Gem::Requirement
137
+ requirement: &21216440 !ruby/object:Gem::Requirement
149
138
  none: false
150
139
  requirements:
151
140
  - - ~>
@@ -153,10 +142,10 @@ dependencies:
153
142
  version: 1.3.0
154
143
  type: :runtime
155
144
  prerelease: false
156
- version_requirements: *20354380
145
+ version_requirements: *21216440
157
146
  - !ruby/object:Gem::Dependency
158
147
  name: activesupport
159
- requirement: &20353960 !ruby/object:Gem::Requirement
148
+ requirement: &21215840 !ruby/object:Gem::Requirement
160
149
  none: false
161
150
  requirements:
162
151
  - - ! '>='
@@ -164,10 +153,10 @@ dependencies:
164
153
  version: '0'
165
154
  type: :runtime
166
155
  prerelease: false
167
- version_requirements: *20353960
156
+ version_requirements: *21215840
168
157
  - !ruby/object:Gem::Dependency
169
158
  name: delorean
170
- requirement: &20353500 !ruby/object:Gem::Requirement
159
+ requirement: &21215020 !ruby/object:Gem::Requirement
171
160
  none: false
172
161
  requirements:
173
162
  - - ! '>='
@@ -175,10 +164,10 @@ dependencies:
175
164
  version: '0'
176
165
  type: :development
177
166
  prerelease: false
178
- version_requirements: *20353500
167
+ version_requirements: *21215020
179
168
  - !ruby/object:Gem::Dependency
180
169
  name: rspec
181
- requirement: &20353000 !ruby/object:Gem::Requirement
170
+ requirement: &21214160 !ruby/object:Gem::Requirement
182
171
  none: false
183
172
  requirements:
184
173
  - - ~>
@@ -186,10 +175,10 @@ dependencies:
186
175
  version: 2.8.0
187
176
  type: :development
188
177
  prerelease: false
189
- version_requirements: *20353000
178
+ version_requirements: *21214160
190
179
  - !ruby/object:Gem::Dependency
191
180
  name: shoulda
192
- requirement: &20352580 !ruby/object:Gem::Requirement
181
+ requirement: &21213400 !ruby/object:Gem::Requirement
193
182
  none: false
194
183
  requirements:
195
184
  - - ! '>='
@@ -197,7 +186,7 @@ dependencies:
197
186
  version: '0'
198
187
  type: :development
199
188
  prerelease: false
200
- version_requirements: *20352580
189
+ version_requirements: *21213400
201
190
  description: FnordMetric is a Ruby Event-Tracking gem on steroids
202
191
  email:
203
192
  - paul@paulasmuth.com
@@ -258,7 +247,6 @@ files:
258
247
  - lib/fnordmetric/worker.rb
259
248
  - readme.md
260
249
  - spec/api_spec.rb
261
- - spec/app_spec.rb
262
250
  - spec/context_spec.rb
263
251
  - spec/dashboard_spec.rb
264
252
  - spec/event_spec.rb
@@ -343,7 +331,6 @@ specification_version: 3
343
331
  summary: FnordMetric is a Ruby Event-Tracking gem on steroids
344
332
  test_files:
345
333
  - spec/api_spec.rb
346
- - spec/app_spec.rb
347
334
  - spec/context_spec.rb
348
335
  - spec/dashboard_spec.rb
349
336
  - spec/event_spec.rb
data/spec/app_spec.rb DELETED
@@ -1,486 +0,0 @@
1
- require ::File.expand_path('../spec_helper.rb', __FILE__)
2
-
3
- include Rack::Test::Methods
4
- include FnordMetric
5
-
6
- =begin
7
- describe "app" do
8
-
9
- before(:all) do
10
- redis = Redis.new
11
- @redis = RedisWrap.new(redis, false)
12
- @opts = {
13
- :redis_prefix => "fnordmetric",
14
- :session_data_ttl => 120,
15
- }
16
- @now = Time.utc(1992,01,13,5,23,23).to_i
17
- @namespace = Namespace.new(:foospace, @opts)
18
- @redis_wrap = RedisWrap.new(@redis)
19
- end
20
-
21
- def app
22
- @app ||= FnordMetric::App.new({
23
- :foospace => proc{
24
- widget 'Blubb', nil
25
-
26
- gauge :testgauge, :tick => 1.hour.to_i, :progressive => true
27
- gauge :test3gauge, :tick => 1.hour.to_i, :three_dimensional => true
28
-
29
- }
30
- }, @opts)
31
- end
32
-
33
- it "should redirect to the first namespace" do
34
- get "/"
35
- last_response.status.should == 302
36
- last_response.location.should == "http://example.org/foospace"
37
- end
38
-
39
- it "should render the namespace" do
40
- get "/foospace"
41
- last_response.status.should == 200
42
- end
43
-
44
- it "should render the dashboards" do
45
- @app ||= FnordMetric::App.new({
46
- :foospace => proc{
47
- widget 'Blubb', nil
48
- }
49
- }, @opts)
50
- get "/foospace"
51
- last_response.status.should == 200
52
- last_response.body.should include("Blubb")
53
- end
54
-
55
- it "should render the dashboards" do
56
- @app ||= FnordMetric::App.new({
57
- :foospace => proc{
58
- widget 'Blubb', nil
59
- widget 'Fnord', nil
60
- }
61
- }, @opts)
62
- get "/foospace"
63
- last_response.status.should == 200
64
- last_response.body.should include("Blubb")
65
- last_response.body.should include("Fnord")
66
- end
67
-
68
- describe "sessions api" do
69
-
70
- before(:each) do
71
- @redis.keys("fnordmetric-foospace*").each { |k| @redis.del(k) }
72
- end
73
-
74
- it "should render a list of all active sessions" do
75
- @namespace.ready!(@redis_wrap).announce(
76
- :_time => Time.now.to_i,
77
- :_type => "foobar",
78
- :_session => "sess213"
79
- )
80
- get "/foospace/sessions"
81
- JSON.parse(last_response.body).should have_key("sessions")
82
- JSON.parse(last_response.body)["sessions"].length.should == 1
83
- end
84
-
85
- it "should render a list of all active sessions with timestamps" do
86
- @namespace.ready!(@redis_wrap).announce(
87
- :_time => @now-5,
88
- :_type => "foobar",
89
- :_session => "sess213"
90
- )
91
- get "/foospace/sessions"
92
- sess = JSON.parse(last_response.body)["sessions"].first
93
- sess["_updated_at"].should == (@now-5).to_s
94
- end
95
-
96
- it "should render a list of all active sessions with usernames" do
97
- @namespace.ready!(@redis_wrap).announce(
98
- :_time => @now,
99
- :_type => "_set_name",
100
- :_session => "sess213",
101
- :name => "Hans Peter"
102
- )
103
- get "/foospace/sessions"
104
- sess = JSON.parse(last_response.body)["sessions"].first
105
- sess["_name"].should == "Hans Peter"
106
- end
107
-
108
- it "should render a list of all active sessions with user pictures" do
109
- @namespace.ready!(@redis_wrap).announce(
110
- :_time => @now,
111
- :_type => "_set_picture",
112
- :_session => "sess213",
113
- :url => "http://myhost.com/mypic.jpg"
114
- )
115
- get "/foospace/sessions"
116
- sess = JSON.parse(last_response.body)["sessions"].first
117
- sess["_picture"].should == "http://myhost.com/mypic.jpg"
118
- end
119
-
120
- it "should render a list of all active sessions with hashed keys" do
121
- @namespace.ready!(@redis_wrap).announce(
122
- :_time => @now-5,
123
- :_type => "foobar",
124
- :_session => "sess133"
125
- )
126
- get "/foospace/sessions"
127
- sess = JSON.parse(last_response.body)["sessions"].first
128
- sess["session_key"].should == Digest::MD5.hexdigest("sess133")
129
- end
130
-
131
- it "should not render more than 100 sessions at once" do
132
- 123.times do |n|
133
- @namespace.ready!(@redis_wrap).announce(
134
- :_time => Time.now.to_i,
135
- :_type => "foobar",
136
- :_session => "sess213-#{n}"
137
- )
138
- end
139
- get "/foospace/sessions"
140
- JSON.parse(last_response.body).should have_key("sessions")
141
- JSON.parse(last_response.body)["sessions"].length.should == 100
142
- end
143
-
144
- it "should render sessions ordered by last_updated_at" do
145
- context = @namespace.ready!(@redis_wrap)
146
- context.announce(
147
- :_time => Time.now.to_i,
148
- :_type => "foobar",
149
- :_session => "sessfoo"
150
- )
151
- context.announce(
152
- :_time => Time.now.to_i-23,
153
- :_type => "foobar",
154
- :_session => "sessbar"
155
- )
156
- context.announce(
157
- :_time => Time.now.to_i-5,
158
- :_type => "foobar",
159
- :_session => "sessfnord"
160
- )
161
- get "/foospace/sessions"
162
- sessions = JSON.parse(last_response.body)["sessions"]
163
- sessions.length.should == 3
164
- sessions[0]["session_key"].should == Digest::MD5.hexdigest("sessfoo")
165
- sessions[1]["session_key"].should == Digest::MD5.hexdigest("sessfnord")
166
- sessions[2]["session_key"].should == Digest::MD5.hexdigest("sessbar")
167
- end
168
-
169
- end
170
-
171
- describe "events api: rendering events" do
172
-
173
- before(:each) do
174
- @redis.keys("fnordmetric-foospace*").each { |k| @redis.del(k) }
175
- end
176
-
177
- it "should render a list of all events" do
178
- @namespace.ready!(@redis_wrap).announce(
179
- :_eid => "sdkjgh9sd8f",
180
- :_time => Time.now.to_i,
181
- :_type => "foobar!!!"
182
- )
183
- get "/foospace/events"
184
- JSON.parse(last_response.body).should have_key("events")
185
- JSON.parse(last_response.body)["events"].length.should == 1
186
- end
187
-
188
- it "should render a list of all events including event-times" do
189
- @namespace.ready!(@redis_wrap).announce(
190
- :_eid => "sdkjgh9sd8f",
191
- :_time => @now-23,
192
- :_type => "foobar!!!"
193
- )
194
- get "/foospace/events"
195
- JSON.parse(last_response.body).should have_key("events")
196
- JSON.parse(last_response.body)["events"].length.should == 1
197
- JSON.parse(last_response.body)["events"].first["_time"].to_i.should == @now-23
198
- end
199
-
200
- it "should render a list of all events including event-ids" do
201
- @namespace.ready!(@redis_wrap).announce(
202
- :_eid => "sdkjgh9sd8f",
203
- :_time => Time.now.to_i,
204
- :_type => "foobar!!!"
205
- )
206
- get "/foospace/events"
207
- JSON.parse(last_response.body).should have_key("events")
208
- JSON.parse(last_response.body)["events"].length.should == 1
209
- JSON.parse(last_response.body)["events"].first["_eid"].should == "sdkjgh9sd8f"
210
- end
211
-
212
-
213
- it "should render a list of all events including event-types" do
214
- create_event("sdkjgh9sd8f", {
215
- :_eid => "sdkjgh9sd8f",
216
- :_time => Time.now.to_i,
217
- :_type => "foobar!!!"
218
- })
219
- get "/foospace/events"
220
- JSON.parse(last_response.body).should have_key("events")
221
- JSON.parse(last_response.body)["events"].length.should == 1
222
- JSON.parse(last_response.body)["events"].first["_type"].should == "foobar!!!"
223
- end
224
-
225
- it "should render a list of all events including _session-data" do
226
- create_event("65785678634", {
227
- :_eid => "65785678634",
228
- :_time => @now-23,
229
- :_type => "foobar!!!",
230
- :_session => "blubb123"
231
- })
232
- get "/foospace/events"
233
- JSON.parse(last_response.body).should have_key("events")
234
- JSON.parse(last_response.body)["events"].length.should == 1
235
- JSON.parse(last_response.body)["events"].first["_session"].should == "blubb123"
236
- end
237
-
238
- it "should render a list of all events including _session-data" do
239
- create_event("4234234634", {
240
- :_eid => "4234234634",
241
- :_time => @now-23,
242
- :_type => "foobar!!!",
243
- :_session => "blubb123",
244
- :fnord => "yeah"
245
- })
246
- get "/foospace/events"
247
- JSON.parse(last_response.body).should have_key("events")
248
- JSON.parse(last_response.body)["events"].length.should == 1
249
- blubb123_md5 = "e5fa475b26873af5ec6c77668f9975a5"
250
- JSON.parse(last_response.body)["events"].first["_session_key"].should == blubb123_md5
251
- end
252
-
253
- it "should render a list of all events in the correct chronological order" do
254
- create_event("daasdasd", {
255
- :_eid => "daasdasd",
256
- :_time => @now-23,
257
- :_type => "foobar!!!"
258
- })
259
- create_event("345345345", {
260
- :_eid => "345345345",
261
- :_time => @now-5,
262
- :_type => "foobar!!!"
263
- })
264
- create_event("sdygsygsdg", {
265
- :_eid => "sdygsygsdg",
266
- :_time => @now-16,
267
- :_type => "foobar!!!"
268
- })
269
- get "/foospace/events"
270
- JSON.parse(last_response.body).should have_key("events")
271
- JSON.parse(last_response.body)["events"].length.should == 3
272
- JSON.parse(last_response.body)["events"][0]["_eid"].should == "345345345"
273
- JSON.parse(last_response.body)["events"][1]["_eid"].should == "sdygsygsdg"
274
- JSON.parse(last_response.body)["events"][2]["_eid"].should == "daasdasd"
275
- end
276
-
277
- it "should not render more than 100 events at a time" do
278
- 120.times do |n|
279
- create_event("sdygsygsdg-#{n}", {
280
- :_eid => "sdygsygsdg-#{n}",
281
- :_time => @now-16,
282
- :_type => "foobar!!!"
283
- })
284
- end
285
- get "/foospace/events"
286
- JSON.parse(last_response.body).should have_key("events")
287
- JSON.parse(last_response.body)["events"].length.should == 100
288
- end
289
-
290
- it "should render all events since a time, not including events at that exact time" do
291
- create_event("daasdasd", {
292
- :_eid => "daasdasd",
293
- :_time => @now-23,
294
- :_type => "foobar!!!"
295
- })
296
- create_event("345345345", {
297
- :_eid => "345345345",
298
- :_time => @now-5,
299
- :_type => "foobar!!!"
300
- })
301
- create_event("sdygsygsdg", {
302
- :_eid => "sdygsygsdg",
303
- :_time => @now-16,
304
- :_type => "foobar!!!"
305
- })
306
- get "/foospace/events?since=#{@now-24}"
307
- JSON.parse(last_response.body)["events"].length.should == 3
308
- get "/foospace/events?since=#{@now-17}"
309
- JSON.parse(last_response.body)["events"].length.should == 2
310
- get "/foospace/events?since=#{@now-16}"
311
- JSON.parse(last_response.body)["events"].length.should == 1
312
- get "/foospace/events?since=#{@now-2}"
313
- JSON.parse(last_response.body)["events"].length.should == 0
314
- end
315
-
316
- it "should render all events for a single event type" do
317
- @namespace.ready!(@redis_wrap).announce(
318
- :_type => "fn0rd",
319
- :_time => @now,
320
- :_eid => "124234"
321
- )
322
- @namespace.ready!(@redis_wrap).announce(
323
- :_type => "f00bar",
324
- :_time => @now,
325
- :_eid => "12235234"
326
- )
327
- @namespace.ready!(@redis_wrap).announce(
328
- :_type => "fn0rd",
329
- :_time => @now,
330
- :_eid => "124234234"
331
- )
332
- get "/foospace/events?type=fn0rd"
333
- JSON.parse(last_response.body)["events"].length.should == 2
334
- get "/foospace/events?type=f00bar"
335
- JSON.parse(last_response.body)["events"].length.should == 1
336
- end
337
-
338
- it "should render all events for a single session key" do
339
- @namespace.ready!(@redis_wrap).announce(
340
- :_time => @now,
341
- :_session => "max_session",
342
- :_eid => "124234"
343
- )
344
- @namespace.ready!(@redis_wrap).announce(
345
- :_time => @now,
346
- :_session => "kate_session",
347
- :_eid => "12235234"
348
- )
349
- @namespace.ready!(@redis_wrap).announce(
350
- :_time => @now,
351
- :_session => "kate_session",
352
- :_eid => "124234234"
353
- )
354
- @namespace.ready!(@redis_wrap).announce(
355
- :_time => @now,
356
- :_eid => "124234234"
357
- )
358
- max_session_key = Digest::MD5.hexdigest "max_session"
359
- kate_session_key = Digest::MD5.hexdigest "kate_session"
360
-
361
- get "/foospace/events?session_key=#{max_session_key}"
362
- events = JSON.parse(last_response.body)["events"]
363
- events.length.should == 1
364
-
365
- get "/foospace/events?session_key=#{kate_session_key}"
366
- events = JSON.parse(last_response.body)["events"]
367
- events.length.should == 2
368
- end
369
-
370
- it "should render a list of event types" do
371
- @namespace.ready!(@redis_wrap).announce(
372
- :_type => "fn0rd",
373
- :_time => @now,
374
- :_eid => "124234"
375
- )
376
- @namespace.ready!(@redis_wrap).announce(
377
- :_type => "f00bar",
378
- :_time => @now,
379
- :_eid => "12235234"
380
- )
381
- @namespace.ready!(@redis_wrap).announce(
382
- :_type => "fn0rd",
383
- :_time => @now,
384
- :_eid => "124234234"
385
- )
386
- get "/foospace/event_types"
387
- JSON.parse(last_response.body)["types"].length.should == 2
388
- JSON.parse(last_response.body)["types"].should include("fn0rd")
389
- JSON.parse(last_response.body)["types"].should include("f00bar")
390
- end
391
-
392
- it "should render all events for a single session"
393
-
394
- it "should render all events for a single session since a unix timestamp"
395
-
396
- it "should render all events for a single session, but not more than 100"
397
-
398
- def create_event(event_id, event_data)
399
- @redis_wrap.zadd(@namespace.key_prefix(:timeline), event_data.delete(:_time), event_id)
400
- @redis_wrap.set("fnordmetric-event-#{event_id}", event_data.to_json)
401
- end
402
-
403
- end
404
-
405
- describe "events api: creating events" do
406
-
407
- it "should track an event without auth" do
408
- post "/events", :_type => "myevent", :fnord => "foobar"
409
- last_response.status.should == 200
410
- end
411
-
412
- it "should return 400 if no type is provided" do
413
- pending("fix this")
414
- post "/events", :fnord => "foobar"
415
- last_response.status.should == 400
416
- last_response.body.should == "please specify the event_type"
417
- end
418
-
419
- end
420
-
421
- describe "gauges api" do
422
-
423
- before(:all) do
424
- @redis.keys("fnordmetric-foospace*").each { |k| @redis.del(k) }
425
- gauge_key = "fnordmetric-foospace-gauge-testgauge-#{1.hour.to_i}"
426
- @redis.hset(gauge_key, 1323687600, "18")
427
- @redis.hset(gauge_key, 1323691200, "23")
428
- end
429
-
430
- it "should return the right answer for: /metric/:name?at=timestamp" do
431
- get "/foospace/gauge/testgauge?at=1323691205"
432
- JSON.parse(last_response.body).first.last.to_i.should == 23
433
- end
434
-
435
- it "should return the right answer for: /metric/:name?at=timestamp" do
436
- get "/foospace/gauge/testgauge?at=1323691200"
437
- JSON.parse(last_response.body).first.last.to_i.should == 23
438
- end
439
-
440
- it "should return the right answer for: /metric/:name?at=timestamp-timstamp" do
441
- get "/foospace/gauge/testgauge?at=1323691200-1323691205"
442
- JSON.parse(last_response.body).first.last.to_i.should == 18
443
- end
444
-
445
- it "should return the right answer for: /metric/:name?at=timestamp-timstamp" do
446
- get "/foospace/gauge/testgauge?at=1323691201-1323695205"
447
- JSON.parse(last_response.body).keys.length
448
- end
449
-
450
- it "should return the right answer for: /metric/:name?at=timestamp-timstamp" do
451
- get "/foospace/gauge/testgauge?at=1323691199-1323701201"
452
- JSON.parse(last_response.body).keys.length.should == 4
453
- JSON.parse(last_response.body)["1323687600"].to_i.should == 18
454
- JSON.parse(last_response.body)["1323691200"].to_i.should == 23
455
- end
456
-
457
- it "should return the right answer for: /metric/:name?at=timestamp-timstamp&sum=true" do
458
- get "/foospace/gauge/testgauge?at=1323691199-1323701201&sum=true"
459
- JSON.parse(last_response.body).keys.length.should == 1
460
- JSON.parse(last_response.body)["sum"].to_i.should == 18+23
461
- end
462
-
463
- end
464
-
465
- describe "three-dim gauges api" do
466
-
467
- before(:all) do
468
- @redis.keys("fnordmetric-foospace*").each { |k| @redis.del(k) }
469
- gauge_key = "fnordmetric-foospace-gauge-test3gauge-#{1.hour.to_i}-1323691200"
470
- @redis.zadd(gauge_key, 18, "fnordyblubb")
471
- @redis.zadd(gauge_key, 23, "uberfoo")
472
- @redis.set(gauge_key+"-count", 41)
473
- end
474
-
475
- it "should return the right answer for: /metric/:name?at=timestamp" do
476
- get "/foospace/gauge/test3gauge?at=1323691205"
477
- JSON.parse(last_response.body)["count"].to_i.should == 41
478
- JSON.parse(last_response.body)["values"].length.should == 2
479
- JSON.parse(last_response.body)["values"][0].should == ["uberfoo", "23"]
480
- JSON.parse(last_response.body)["values"][1].should == ["fnordyblubb", "18"]
481
- end
482
-
483
- end
484
-
485
- end
486
- =end