fnordmetric 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/.travis.yml +1 -0
  2. data/VERSION +1 -1
  3. data/doc/preview1.png +0 -0
  4. data/doc/preview2.png +0 -0
  5. data/doc/ulm_stats.rb +622 -0
  6. data/doc/version +1 -0
  7. data/fnordmetric.gemspec +16 -38
  8. data/haml/app.haml +12 -5
  9. data/lib/fnordmetric.rb +3 -0
  10. data/lib/fnordmetric/app.rb +19 -10
  11. data/lib/fnordmetric/bars_widget.rb +26 -0
  12. data/lib/fnordmetric/context.rb +3 -3
  13. data/lib/fnordmetric/gauge.rb +20 -0
  14. data/lib/fnordmetric/gauge_calculations.rb +28 -4
  15. data/lib/fnordmetric/gauge_modifiers.rb +39 -6
  16. data/lib/fnordmetric/logger.rb +19 -0
  17. data/lib/fnordmetric/numbers_widget.rb +5 -15
  18. data/lib/fnordmetric/pie_widget.rb +23 -0
  19. data/lib/fnordmetric/standalone.rb +1 -1
  20. data/lib/fnordmetric/timeline_widget.rb +16 -23
  21. data/lib/fnordmetric/toplist_widget.rb +25 -0
  22. data/lib/fnordmetric/widget.rb +3 -3
  23. data/pub/{fnordmetric/fnordmetric.css → fnordmetric.css} +46 -36
  24. data/pub/fnordmetric.js +1069 -0
  25. data/pub/loader.gif +0 -0
  26. data/pub/{highcharts → vendor}/highcharts.js +0 -0
  27. data/pub/{jquery-1.6.1.min.js → vendor/jquery-1.6.1.min.js} +0 -0
  28. data/readme.rdoc +228 -311
  29. data/spec/app_spec.rb +63 -3
  30. data/spec/gauge_modifiers_spec.rb +157 -2
  31. data/spec/gauge_spec.rb +143 -12
  32. data/spec/widget_spec.rb +18 -18
  33. metadata +33 -58
  34. data/.document +0 -5
  35. data/_spec/app_spec.rb +0 -178
  36. data/_spec/cache_spec.rb +0 -53
  37. data/_spec/combine_metric_spec.rb +0 -19
  38. data/_spec/core_spec.rb +0 -50
  39. data/_spec/count_metric_spec.rb +0 -32
  40. data/_spec/dashboard_spec.rb +0 -67
  41. data/_spec/event_spec.rb +0 -46
  42. data/_spec/metric_spec.rb +0 -118
  43. data/_spec/report_spec.rb +0 -87
  44. data/_spec/sum_metric_spec.rb +0 -33
  45. data/_spec/widget_spec.rb +0 -107
  46. data/doc/example_server.rb +0 -56
  47. data/doc/import_dump.rb +0 -26
  48. data/pub/fnordmetric/fnordmetric.js +0 -543
  49. data/pub/fnordmetric/widget_numbers.js +0 -71
  50. data/pub/fnordmetric/widget_timeline.css +0 -0
  51. data/pub/fnordmetric/widget_timeline.js +0 -110
  52. data/pub/highcharts/adapters/mootools-adapter.js +0 -12
  53. data/pub/highcharts/adapters/mootools-adapter.src.js +0 -243
  54. data/pub/highcharts/adapters/prototype-adapter.js +0 -14
  55. data/pub/highcharts/adapters/prototype-adapter.src.js +0 -284
  56. data/pub/highcharts/highcharts.src.js +0 -11103
  57. data/pub/highcharts/modules/exporting.js +0 -22
  58. data/pub/highcharts/modules/exporting.src.js +0 -703
  59. data/pub/highcharts/themes/dark-blue.js +0 -268
  60. data/pub/highcharts/themes/dark-green.js +0 -268
  61. data/pub/highcharts/themes/gray.js +0 -262
  62. data/pub/highcharts/themes/grid.js +0 -97
  63. data/pub/raphael-min.js +0 -8
  64. data/pub/raphael-utils.js +0 -221
  65. data/ulm_stats.rb +0 -198
Binary file
File without changes
@@ -1,47 +1,81 @@
1
1
  = FnordMetric
2
2
 
3
- FnordMetric is a highly configurable realtime app tracking thing.
3
+ FnordMetric is a highly configurable (and pretty fast) realtime app/event tracking thing based on ruby eventmachine and redis. You define your own plotting and counting functions as ruby blocks!
4
4
 
5
- Step 1: You send send json events from your web/facebook app. eg:
5
+ {<img src="https://secure.travis-ci.org/paulasmuth/fnordmetric.png" />}[http://travis-ci.org/paulasmuth/fnordmetric]
6
6
 
7
- // track a pageview
8
- { "_type": "_pageview", "url": "/blob/my_super_seo_article", "_session": "mysessiontoken" }
7
+ SCREENCAST: http://www.screenr.com/KiJs - the FnordMetric-instance we use to track our social dating app
9
8
 
10
- // track a waypoint (see below)
11
- { "_type": "_waypoint", "waypoint": "thank_you_site", "map": "checkout_flow", "_session": "mysessiontoken" }
9
+ ---
12
10
 
13
- // track a custom action
14
- { "_type": "my_foo_type", "my_foo_action": "wink", "other_user": "myuserid" }
11
+ FnordMetric keeps track of your data and draws nice timeline plots.
15
12
 
16
- // set the user name
17
- { "_type": "_set_name", "name": "Tingle Tangle Bob", "_session": "mysessiontoken" }
13
+ {<img src="https://raw.github.com/paulasmuth/fnordmetric/master/doc/preview1.png" />}[https://raw.github.com/paulasmuth/fnordmetric/master/doc/preview1.png]
18
14
 
19
- // set the user picture
20
- { "_type": "_set_picture", "url": "http://myhost/123.jpg", "_session": "mysessiontoken" }
15
+ FnordMetric gives you a live dashboard, that shows who is using your app in realtime. You can select a single user and follow them step by step.
16
+
17
+ {<img src="https://raw.github.com/paulasmuth/fnordmetric/master/doc/preview2.png" />}[https://raw.github.com/paulasmuth/fnordmetric/master/doc/preview1.png]
18
+
19
+
20
+ == Getting Started
21
+
22
+ Copy doc/ulm_stats.rb (that's the configuration from the screenshots and screencast) or the simple example from below to 'my_stats_app.rb'
23
+
24
+ Simple Example: This will listen for json-events with type=unicorn_seen and render a timeline-plot showing the number of received events per hour.
25
+
26
+ require "fnordmetric"
27
+
28
+ FnordMetric.namespace :myapp do
29
+
30
+ # numeric (delta) gauge, 1-hour tick
31
+ gauge :unicorns_seen_per_hour,
32
+ :tick => 1.hour.to_i,
33
+ :title => "Unicorns seenper Hour"
34
+
35
+ # on every event like { _type: 'unicorn_seen' }
36
+ event(:unicorn_seen) do
37
+ # increment the unicorns_seen_per_hour gauge by 1
38
+ incr :unicorns_seen_per_hour
39
+ end
21
40
 
41
+ # draw a timeline showing the gauges value, auto-refresh every 30s
42
+ widget 'Overview', {
43
+ :title => "Unicorn-Sightings per Hour",
44
+ :type => :timeline,
45
+ :gauges => :unicorns_seen_per_hour,
46
+ :autoupdate => 30
47
+ }
22
48
 
23
- Step 2: FnordMetric gives you a live dashboard, that shows who is using your app in realtime. You can select a single user and follow them step by step.
49
+ end
50
+
51
+ FnordMetric.standalone
52
+
53
+ Start the app (requires ruby >= 1.9.2):
54
+
55
+ $ ruby my_stats_app.rb run
24
56
 
25
- (pic here)
57
+ Log all incoming events:
26
58
 
27
- Step 3: FnordMetric keeps track of your data and draws nice timeline plots. (You can define your own plotting and counting functions as ruby blocks!)
59
+ $ ruby my_stats_app.rb log
28
60
 
29
- (pic here)
61
+ This is the easiest way to submit an event:
30
62
 
31
- Step 4: FnordMetric draws nice "user-flow" maps (Use them to optimize your navigation!)
63
+ echo "{'_type': 'unicorn_seen'}\n" | nc localhost 1337
32
64
 
33
- (pic here)
34
65
 
35
- Step 5: Even more shiny stuff!
66
+ == Installation
36
67
 
37
- (pic)
68
+ gem install fnordmetric
38
69
 
70
+ or in your Gemfile:
39
71
 
40
- === Installation
72
+ gem 'fnordmetric', '>= 0.5.1'
41
73
 
42
- === Configuration
43
74
 
44
- === Sending data: Connection
75
+ == Documentation
76
+
77
+
78
+ === Sending Events
45
79
 
46
80
  The slow way: HTTP-Post the json event to the fnordmetric webinterface
47
81
 
@@ -62,85 +96,198 @@ The fast way: Add your event directly to the redis-based queue:
62
96
  redis.set("fnordmetric-event-#{my_uuid}", event)
63
97
  redis.expire("fnordmetric-event-#{my_uuid}", 60)
64
98
 
99
+ ---
65
100
 
66
- === Sending data: Special Keys
101
+ === Special Events
67
102
 
68
- -> "_type": The event class/type. (mandatory)
103
+ // track a pageview
104
+ { "_type": "_pageview", "url": "/blob/my_super_seo_article", "_session": "mysessiontoken" }
69
105
 
70
- -> "_namespace": The namespace (if you have more than one)
106
+ // set the user name
107
+ { "_type": "_set_name", "name": "Tingle Tangle Bob", "_session": "mysessiontoken" }
71
108
 
72
- -> "_session": Your session identifier (recommended)
109
+ // set the user picture
110
+ { "_type": "_set_picture", "url": "http://myhost/123.jpg", "_session": "mysessiontoken" }
73
111
 
74
- -> "_time": The event time (do not use!)
75
112
 
76
- -> "_eid": The event id (do not use!)
113
+ ---
77
114
 
115
+ === DSL Methods
78
116
 
79
- === Sending data: Special Event Types
117
+ gauge
80
118
 
81
- -> "_pageview": Track a pageview (should have a "url" attr!)
119
+ widget
82
120
 
83
- -> "_set_name": Set the username for the current session (should have a "name" attr)
121
+ event
84
122
 
85
- -> "_set_picture": Set the user picture for the current session (should have a "url" attr)
86
123
 
87
- -> "_set_data": Store all event attributes in the current session
124
+ ---
88
125
 
126
+ === Event Handlers
89
127
 
128
+ call these methods from the event-handler block
90
129
 
91
- == Configuration
130
+ incr(gauge_name, value=1):
131
+ Increment the given (two-dimensional) gauge by value at the tick specified by event-time
92
132
 
93
- === Gauge Modifiers
133
+ incr_field(gauge_name, field_name, value=1):
134
+ Increment the given field on a three-dimensional gauge by value at the tick specified by event-time
94
135
 
95
- incr(gauge_name, value=1): Increment the given (two-dimensional) gauge by value
136
+ set_value(gauge_name, value)
137
+ Set the given (two-dimensional) to value at the tick specified by event-time (overwrite existing value)
96
138
 
97
- incr_uniq(gauge_name, value=1): Increment the given (two-dimensional) gauge by value unless incr_uniq was already called for this session and tick (using incr_uniq on a progressive gauge is propably a bad idea)
139
+ set_field(gauge_name, field_name, value)
140
+ Set the given field on a three-dimensional gauge to value at the tick specified by event-time (overwrite existing value)
98
141
 
99
- not yet implemented
100
142
 
101
- incr_field(gauge_name, field_name, value=1): Increment the given (three-dimensional) gauge by value
143
+ ---
102
144
 
145
+ === Gauges
103
146
 
104
- === Limitations
147
+ ---
105
148
 
106
- -> It will drop events if it gets over capacity (prevent this by setting high timeouts)
149
+ === Widgets
107
150
 
108
- -> All gauge values are calculated in a 'stateful'/'progressive' manner. Most of the modifiactor methods (incr, etc) assume that time can only go in one direction: forward. that means Events can't be added retroactively:
151
+ [autoupdate] auto-refresh the timeline every n secs (0 turns autoupdate off)
109
152
 
110
- -> If you loose your redis db, you'll need to replay all recorded events in the correct chronological order.
153
+ ==== Widget-Options: TimelineWidget
111
154
 
112
- -> If the events were captured on a single machine you can just replay the logfile fnordmetric creates by default.
155
+ [plot_style] one of: line, areaspline
156
+ [include_current] show the current tick?
157
+ [ticks] number of ticks to show (defaults to 24/30)
113
158
 
114
- -> If the events were captured on multiple machines you need to merge and sort(!) the log-files first before they can be replayed.
159
+ ==== Widget-Options: BarsWidget
115
160
 
116
- -> If you run fnordmetric on multiple machines, you need to make shure the system clocks are in sync!
161
+ [plot_style] one of: vertical, horizontal
162
+ [order_by]: order bars/columns by: value, field
117
163
 
118
- -> If you wan't a new query/graph for history data, you'll have to replay your logs...
164
+ ==== Widget-Options: Numbers-Widget
119
165
 
166
+ ==== Widget-Options: ToplistWidget
120
167
 
121
168
 
122
- == TODOS
169
+ ---
123
170
 
124
- -> change /dashboard/mydashboard and add /widget/mywidget -> defer widget.render until a n-th ajax call (the dashboard-json should not contain the rendered widget)
171
+ === JSON API
125
172
 
126
- -> bug: include_current=false does what include_current=true is supposed to do and include_current=true is always one tick in the future
127
173
 
128
- -> opt_event options: :increment => gauge_name
129
174
 
130
- -> timelinewidget + numberswidget => should use redis hmget
175
+ == Examples
176
+
177
+ (link1), (link2), (link3), (link4)
131
178
 
132
- -> OverviewDashboard (uniques day/week/month, events per min, online users, events per user)
133
179
 
134
- -> ReferralDashboard (last 100 uniq googlequeries+refs, top refs, top googlequeries)
135
180
 
136
- -> SalesDashboard (arpu, avgsale, sales, tot. revenue)
181
+ == Full Example
137
182
 
138
- -> prune the namespace-sessions-timline (remove event_ids older than x)
183
+ require "fnordmetric"
139
184
 
140
- -> prune the namespace-event-types-list (trim to max items)
185
+ FnordMetric.namespace :myapp do
186
+
187
+ # numeric (delta) gauge, 1-hour tick
188
+ gauge :messages_sent,
189
+ :tick => 1.hour.to_i,
190
+ :title => "Messages (sent) per Hour"
191
+
192
+ # numeric (delta) gauge, 1-hour tick
193
+ gauge :messages_read,
194
+ :tick => 1.hour.to_i,
195
+ :title => "Messages (read) per Hour"
196
+
197
+ # numeric (progressive) gauge, 1-hour tick
198
+ gauge :events_total,
199
+ :tick => 1.day.to_i,
200
+ :progressive => true,
201
+ :title => "Events (total)"
202
+
203
+ # numeric (delta) gauge, increments uniquely by session_key
204
+ gauge :pageviews_daily_unique,
205
+ :tick => 1.day.to_i,
206
+ :unique => true,
207
+ :title => "Unique Visits (Daily)"
208
+
209
+ # numeric (delta) gauge, increments uniquely by session_key, returns average
210
+ gauge :avg_age_per_session,
211
+ :tick => 1.day.to_i,
212
+ :unique => true,
213
+ :average => true,
214
+ :title => "Avg. User Age"
215
+
216
+ # three-dimensional (delta) gauge (time->key->value)
217
+ gauge :pageviews_per_url_daily,
218
+ :tick => 1.day.to_i,
219
+ :title => "Daily Pageviews per URL",
220
+ :three_dimensional => true
221
+
222
+
223
+ # on every event like { _type: 'message_sent' }
224
+ event(:message_sent) do
225
+ # increment the messages_sent gauge by 1
226
+ incr :messages_sent
227
+ end
228
+
229
+ # on every event like { _type: 'message_read' }
230
+ event(:message_read) do
231
+ # increment the messages_read gauge by 1
232
+ incr :messages_read
233
+ end
234
+
235
+ # on _every_ event
236
+ event :"*" do
237
+ # increment the events_total gauge by 1
238
+ incr :events_total
239
+ end
240
+
241
+ # on every event like { _type: '_pageview', _session: 'sbz7jset', _url: '/page2' }
242
+ event :_pageview do
243
+ # increment the daily_uniques gauge by 1 if session_key hasn't been seen in this tick yet
244
+ incr :pageviews_daily_unique
245
+ # increment the pageviews_per_url_daily gauge by 1 where key = 'page2'
246
+ incr_field :pageviews_per_url_daily, data[:url]
247
+ end
248
+
249
+ # on every event like { _type: '_pageview', my_set_age: '23' }
250
+ event(:my_set_age) do
251
+ # add the value of my_set_age to the avg_age_per_session gauge if session_key
252
+ # hasn't been seen in this tick yet
253
+ incr :avg_age_per_session, data[:my_age_field]
254
+ end
255
+
256
+ # draw a timeline showing the pageviews_daily_unique, auto-refresh every 30s
257
+ widget 'Overview', {
258
+ :title => "Unique Visits per Day",
259
+ :type => :timeline,
260
+ :width => 70,
261
+ :gauges => :pageviews_daily_unique,
262
+ :include_current => true,
263
+ :autoupdate => 30
264
+ }
265
+
266
+ # draw the values of the messages_sent and messages_read gauge at the current tick, three ticks ago, and
267
+ # the sum of the last 10 ticks, auto-refresh every 20s
268
+ widget 'Overview', {
269
+ :title => "Messages Sent / Read",
270
+ :type => :numbers,
271
+ :width => 30,
272
+ :autoupdate => 20,
273
+ :offsets => [0,3,"10s"]
274
+ :gauges => [ :messages_sent, :messages_read ]
275
+ }
276
+
277
+ # draw a list of the most visited urls (url, visits + percentage), auto-refresh every 20s
278
+ widget 'Overview', {
279
+ :title => "Top Pages",
280
+ :type => :toplist,
281
+ :autoupdate => 20,
282
+ :gauges => [ :pageviews_per_url_daily ]
283
+ }
141
284
 
285
+ end
286
+
287
+ FnordMetric.standalone
142
288
 
143
- == License (It's free!)
289
+
290
+ == License
144
291
 
145
292
  Copyright (c) 2011 Paul Asmuth
146
293
 
@@ -161,259 +308,29 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
161
308
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
162
309
 
163
310
 
164
-
165
-
166
-
167
-
168
-
169
-
170
-
171
-
172
-
173
-
174
-
175
-
176
- = Old stuff
177
-
178
- == Usage: Standalone service
179
-
180
- you can run the fnordmetric webapp as a standalone service. Your 'fnordmetric_server.rb' would propably look something like this:
181
-
182
- require "rubygems"
183
- require "fnordmetric"
184
- require "thin"
185
-
186
- FnordMetric.metric(:cars_total, :count => :true, :types => [:car_seen])
187
- FnordMetric.metric(:passengers_total, :sum => :passengers, :types => [:car_seen])
188
- FnordMetric.metric(:passengers_red_car, :sum => :passengers, :filter => { :color => :red }, :types => [:car_seen])
189
- FnordMetric.metric(:passengers_blue_car, :sum => :passengers, :filter => { :color => :blue }, :types => [:car_seen])
190
- FnordMetric.metric(:blue_to_red_ratio, :combine => lambda{ |x| x.passengers_blue_car / x.passengers_red_car })
191
-
192
- FnordMetric.dashboard 'Passengers' do |passengers|
193
-
194
- passengers.add_widget FnordMetric.widget(:passenger_blue_red_timeline,
195
- :metrics => [:passengers_blue_car, :passengers_red_car],
196
- :title => "Passengers (red/blue) timeline",
197
- :type => :timeline
198
- )
199
-
200
- passengers.add_widget FnordMetric.widget(:passengers_total_timeline,
201
- :metrics => [:cars_total, :passengers_total, :blue_to_red_ratio],
202
- :title => "Cars total + Passenger total + Red/Blue Ratio",
203
- :autoupdate => true,
204
- :type => :numbers
205
- )
206
-
207
- end
208
-
209
- Mongoid.configure do |c|
210
- c.master = Mongo::Connection.new.db("myfnordmetric")
211
- end
212
-
213
- app = FnordMetric::App.new
214
- Thin::Server.start('127.0.0.1', 2323, app)
215
-
216
-
217
- when run as a standalone service events can be added via a very simple (restful) http post:
218
-
219
- POST http://myapp:port/fnordmetric/events type=car_seen&color=red&passengers=2&speed=120
220
-
221
- with curl:
222
-
223
- curl -X POST -d "type=car_seen&color=red&passengers=2&speed=120" http://myapp:port/fnordmetric/events
224
-
225
-
226
-
227
- == Usage: From Rails/Rack
228
-
229
- you need a mongodb instance and have to configure the mongoid-gem if your app doesn't already do that:
230
-
231
- require 'fnordmetric'
232
- Mongoid.configure{ |c| c.master = Mongo::Connection.new.db("fnordmetric_test") }
233
-
234
-
235
- that's all. you can start tracking data:
311
+ == Todos
312
+
313
+ -> funnel-widget
314
+ -> combine/calculation gauges via opts_gauge({}, &block) (+calculate ctr)
315
+ -> timeline_widget: 'compare mode': compate gauge to yesterday
316
+ -> fix include_current
317
+ -> numbers_widget: handle decreasing vals
318
+ -> make redis-addr and redis-prefix + listen-ports configurable
319
+ -> referal tracking fu (parse googlequeries)
320
+ -> trend detection
321
+ -> opt_event options: :increment => gauge_name
322
+ -> preconfigured default-dashboard (like google analytics)
323
+ -> pagview+ref-tracking via js-tracking-pixel
324
+ -> table/gauge-list-widget (with mini-stats!)
325
+ -> prune the namespace-sessions-timline (remove event_ids older than x)
326
+ -> prune the namespace-event-types-list (trim to max items)
327
+ -> timelinewidget + numberswidget => should use redis hmget
328
+ -> get multiple metrics in a single http get
329
+ -> { _namespace: myns } field (!!!)
236
330
 
237
- FnordMetric.track('car_seen', :color => "red", :speed => 130, :passengers => 2)
238
- FnordMetric.track('car_seen', :color => "pink", :speed => 150, :passengers => 1)
239
- FnordMetric.track('car_seen', :color => "red", :speed => 65, :passengers => 4, :time => 50.hours.ago)
240
- FnordMetric.track('car_seen', :color => "blue", :speed => 100, :passengers => 2, :time => 30.hours.ago)
241
- FnordMetric.track('car_seen', :color => "red", :speed => 123, :passengers => 2)
242
- FnordMetric.track('car_seen', :color => "blue", :speed => 130, :passengers => 3)
243
- FnordMetric.track('car_seen', :color => "red", :speed => 142, :passengers => 2)
244
-
245
-
246
- to see some shiny stats you first have to define a 'metric'. e.g. in 'config/initializers/fnordmetric.rb':
247
-
248
- FnordMetric.metric(:colors_total, :types => [:car_seen], :count => true, :unique => :color)
249
- FnordMetric.metric(:cars_total, :types => [:car_seen], :count => true)
250
- FnordMetric.metric(:passengers_total, :types => [:car_seen], :sum => :passengers)
251
- FnordMetric.metric(:average_speed, :types => [:car_seen], :average => :speed)
252
-
253
-
254
-
255
- use combine-metrics to build your own 'indices':
256
-
257
- FnordMetric.metric(:passengers_red_car, :sum => :passengers, :filter => { :colors => :red }, :types => [:car_seen])
258
- FnordMetric.metric(:passengers_blue_car, :sum => :passengers, :filter => { :colors => :blue }, :types => [:car_seen])
259
-
260
- FnordMetric.metric(:blue_to_red_ratio, :combine => lambda{ |x|
261
- x.passengers_blue_car / x.passengers_red_car
262
- })
263
-
264
-
265
- fnordmetric comes with javascript charting helper and a javascript dashboard app. to
266
- use them you have to load a rails engine by adding this line to your routes.rb:
267
-
268
- mount FnordMetric::App => '/fnordmetric'
269
-
270
-
271
- point your browser to 'myapp.com/fnordmetric' and you should see an empty dashboard. you can
272
- add dashboards and widgets like this (e.g. in initializers/fnordmetric.rb):
273
-
274
- FnordMetric.dashboard 'Passengers' do |dash|
275
-
276
- dash.add_widget FnordMetric.widget(:passenger_blue_red_timeline,
277
- :metrics => [:passengers_blue_car, :passengers_red_car],
278
- :title => "Passengers (red/blue)",
279
- :type => :timeline
280
- )
281
-
282
- dash.add_widget FnordMetric.widget(:passengers_total_timeline,
283
- :metrics => :passengers_total,
284
- :title => "Passenger blue/red Ratio",
285
- :type => :timeline
286
- )
287
-
288
- end
289
-
290
-
291
- you can also get the raw numbers in your controller or model:
292
-
293
- report = FnordMetric.report(:range => (3.days.ago..Time.now))
294
- report.colors_total.current # => 3
295
- report.colors_total.current # => 3
296
- report.cars_total.current # => 7
297
- report.average_speed.current # => 113.6
298
- report.passengers_total.current # => 26
299
- report.colors_total.current # => 3
300
-
301
- report.colors_total.at(40.hours.ago) # => 1
302
- report.colors_total.at(20.hours.ago) # => 2
303
-
304
- report.colors_total.values
305
- => { <Date 03-10-11> => 1, <Date 04-10-11> => 2, <Date 05-10-11> => 3 }
306
-
307
- report.colors_total.ticks
308
- => [ (<Date 03-10-11 00:00:00>..<Date 03-10-11 23:59:59>), (<Date 04-10...
309
-
310
-
311
- and you can render the widgets in your own views:
312
-
313
- widget = FnordMetric.widget(
314
- :passengers_red_blue_widget,
315
- :title => "Passengers (red/blue)",
316
- :type => :timeline,
317
- :metrics => [:passengers_blue_car, :passengers_red_car],
318
- :range => (14.days.ago..Time.now)
319
- )
320
-
321
- widget.render
322
- => "<script type="text/javascript" src="/fnordmetric/widget.js?type=..."
323
-
324
-
325
- == Option Reference
326
-
327
- *FnordMetric.metric* (FnordMetric::Metric.new)
328
-
329
- ===== :count => true
330
- ====== return the total number of events (one of count, average, sum or combine is mandatory)
331
- ====== ~
332
-
333
- ===== :average => (field)
334
- ====== return the avg of all "field"-values (one of count, average, sum or combine is mandatory)
335
- ====== ~
336
-
337
- ===== :sum => (field)
338
- ====== return the sum of all "field"-values (one of count, average, sum or combine is mandatory)
339
- ====== ~
340
-
341
- ===== :combine => (lambda)
342
- ====== custom accumulator (one of count, average, sum or combine is mandatory)
343
- ====== ~
344
-
345
- ===== :unique => (field)
346
- ====== only consider events with unique (field)
347
- ====== ~
348
-
349
- ===== :types => (types)
350
- ====== only consider events where type in types
351
- ====== ~
352
-
353
- ===== :filter => (hash)
354
- ====== only consider events with fields matching (hash)
355
- ====== ~
356
-
357
- ===== :select => (lambda)
358
- ====== only consider events for which (lambda) is true
359
-
360
-
361
- *FnordMetric.widget* (FnordMetric::Widget.new)
362
-
363
- ===== :metrics => (fnord)
364
- ====== foobar (mandatory)
365
- ====== ~
366
-
367
- ===== :title => (fnord)
368
- ====== foobar (mandatory)
369
- ====== ~
370
-
371
- ===== :tick => (fnord)
372
- ====== foobar
373
- ====== ~
374
-
375
- ===== :range => (fnord)
376
- ====== foobar
377
- ====== ~
378
-
379
- ===== :current => (fnord)
380
- ====== FIXME: opt is actually named :include_curent
381
- ====== ~
382
-
383
- ===== :report => (fnord)
384
- ====== foobar
385
- ====== ~
386
-
387
- *TimelineWidget* (FnordMetric::TimelineWidget.new)
388
-
389
- ===== :delta => (fnord)
390
- ====== foobar
391
- ====== ~
392
-
393
- ===== :chart => (fnord)
394
- ====== foobar
395
- ====== ~
396
-
397
-
398
-
399
331
 
400
- == TODO
401
- * metric-api: request caching
402
- * widget loader: hide iframe body content until css has loaded
403
- * timeline widget: make range input editable (+parse)
404
- * add mongo indices
405
- * default range (daily/hourly)
406
- * highcharts cleanup
407
- * numbers widget: date format
408
- * numbers widget: delta option
409
- * numbers widget: 'trend' option
410
- * timeline widget: timezones
411
- * metric-api: request caching
412
- * compare widget
413
- * funnel widget
414
- * widget: allow init without name (autogenerate)
415
- * virtual dashboard: all metrics (current+today+last week+last month) [+add metric btn]
416
- * add widgets/metrics via webapp?
417
- * auth?!
332
+ -> demo / example: chatroom;
333
+ -> events: msg_read, msg_sent, {reg_start, reg_register, reg_active}, login (+demog.data+lang), referall
334
+ -> widgets: msgs sent/read (timeline), user-demog. (bars), reg-funnel (funnel), male vs. female users (pie), top langs (list), kpi list (toplist - regs, msg/user, conversion rate, etc), top referrers
418
335
 
419
336