fnordmetric 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +1 -0
- data/VERSION +1 -1
- data/doc/preview1.png +0 -0
- data/doc/preview2.png +0 -0
- data/doc/ulm_stats.rb +622 -0
- data/doc/version +1 -0
- data/fnordmetric.gemspec +16 -38
- data/haml/app.haml +12 -5
- data/lib/fnordmetric.rb +3 -0
- data/lib/fnordmetric/app.rb +19 -10
- data/lib/fnordmetric/bars_widget.rb +26 -0
- data/lib/fnordmetric/context.rb +3 -3
- data/lib/fnordmetric/gauge.rb +20 -0
- data/lib/fnordmetric/gauge_calculations.rb +28 -4
- data/lib/fnordmetric/gauge_modifiers.rb +39 -6
- data/lib/fnordmetric/logger.rb +19 -0
- data/lib/fnordmetric/numbers_widget.rb +5 -15
- data/lib/fnordmetric/pie_widget.rb +23 -0
- data/lib/fnordmetric/standalone.rb +1 -1
- data/lib/fnordmetric/timeline_widget.rb +16 -23
- data/lib/fnordmetric/toplist_widget.rb +25 -0
- data/lib/fnordmetric/widget.rb +3 -3
- data/pub/{fnordmetric/fnordmetric.css → fnordmetric.css} +46 -36
- data/pub/fnordmetric.js +1069 -0
- data/pub/loader.gif +0 -0
- data/pub/{highcharts → vendor}/highcharts.js +0 -0
- data/pub/{jquery-1.6.1.min.js → vendor/jquery-1.6.1.min.js} +0 -0
- data/readme.rdoc +228 -311
- data/spec/app_spec.rb +63 -3
- data/spec/gauge_modifiers_spec.rb +157 -2
- data/spec/gauge_spec.rb +143 -12
- data/spec/widget_spec.rb +18 -18
- metadata +33 -58
- data/.document +0 -5
- data/_spec/app_spec.rb +0 -178
- data/_spec/cache_spec.rb +0 -53
- data/_spec/combine_metric_spec.rb +0 -19
- data/_spec/core_spec.rb +0 -50
- data/_spec/count_metric_spec.rb +0 -32
- data/_spec/dashboard_spec.rb +0 -67
- data/_spec/event_spec.rb +0 -46
- data/_spec/metric_spec.rb +0 -118
- data/_spec/report_spec.rb +0 -87
- data/_spec/sum_metric_spec.rb +0 -33
- data/_spec/widget_spec.rb +0 -107
- data/doc/example_server.rb +0 -56
- data/doc/import_dump.rb +0 -26
- data/pub/fnordmetric/fnordmetric.js +0 -543
- data/pub/fnordmetric/widget_numbers.js +0 -71
- data/pub/fnordmetric/widget_timeline.css +0 -0
- data/pub/fnordmetric/widget_timeline.js +0 -110
- data/pub/highcharts/adapters/mootools-adapter.js +0 -12
- data/pub/highcharts/adapters/mootools-adapter.src.js +0 -243
- data/pub/highcharts/adapters/prototype-adapter.js +0 -14
- data/pub/highcharts/adapters/prototype-adapter.src.js +0 -284
- data/pub/highcharts/highcharts.src.js +0 -11103
- data/pub/highcharts/modules/exporting.js +0 -22
- data/pub/highcharts/modules/exporting.src.js +0 -703
- data/pub/highcharts/themes/dark-blue.js +0 -268
- data/pub/highcharts/themes/dark-green.js +0 -268
- data/pub/highcharts/themes/gray.js +0 -262
- data/pub/highcharts/themes/grid.js +0 -97
- data/pub/raphael-min.js +0 -8
- data/pub/raphael-utils.js +0 -221
- data/ulm_stats.rb +0 -198
data/pub/loader.gif
ADDED
Binary file
|
File without changes
|
File without changes
|
data/readme.rdoc
CHANGED
@@ -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
|
-
|
5
|
+
{<img src="https://secure.travis-ci.org/paulasmuth/fnordmetric.png" />}[http://travis-ci.org/paulasmuth/fnordmetric]
|
6
6
|
|
7
|
-
|
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
|
-
|
11
|
-
{ "_type": "_waypoint", "waypoint": "thank_you_site", "map": "checkout_flow", "_session": "mysessiontoken" }
|
9
|
+
---
|
12
10
|
|
13
|
-
|
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
|
-
|
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
|
-
|
20
|
-
|
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
|
-
|
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
|
-
|
57
|
+
Log all incoming events:
|
26
58
|
|
27
|
-
|
59
|
+
$ ruby my_stats_app.rb log
|
28
60
|
|
29
|
-
|
61
|
+
This is the easiest way to submit an event:
|
30
62
|
|
31
|
-
|
63
|
+
echo "{'_type': 'unicorn_seen'}\n" | nc localhost 1337
|
32
64
|
|
33
|
-
(pic here)
|
34
65
|
|
35
|
-
|
66
|
+
== Installation
|
36
67
|
|
37
|
-
|
68
|
+
gem install fnordmetric
|
38
69
|
|
70
|
+
or in your Gemfile:
|
39
71
|
|
40
|
-
|
72
|
+
gem 'fnordmetric', '>= 0.5.1'
|
41
73
|
|
42
|
-
=== Configuration
|
43
74
|
|
44
|
-
|
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
|
-
===
|
101
|
+
=== Special Events
|
67
102
|
|
68
|
-
|
103
|
+
// track a pageview
|
104
|
+
{ "_type": "_pageview", "url": "/blob/my_super_seo_article", "_session": "mysessiontoken" }
|
69
105
|
|
70
|
-
|
106
|
+
// set the user name
|
107
|
+
{ "_type": "_set_name", "name": "Tingle Tangle Bob", "_session": "mysessiontoken" }
|
71
108
|
|
72
|
-
|
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
|
-
|
113
|
+
---
|
77
114
|
|
115
|
+
=== DSL Methods
|
78
116
|
|
79
|
-
|
117
|
+
gauge
|
80
118
|
|
81
|
-
|
119
|
+
widget
|
82
120
|
|
83
|
-
|
121
|
+
event
|
84
122
|
|
85
|
-
-> "_set_picture": Set the user picture for the current session (should have a "url" attr)
|
86
123
|
|
87
|
-
|
124
|
+
---
|
88
125
|
|
126
|
+
=== Event Handlers
|
89
127
|
|
128
|
+
call these methods from the event-handler block
|
90
129
|
|
91
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
143
|
+
---
|
102
144
|
|
145
|
+
=== Gauges
|
103
146
|
|
104
|
-
|
147
|
+
---
|
105
148
|
|
106
|
-
|
149
|
+
=== Widgets
|
107
150
|
|
108
|
-
|
151
|
+
[autoupdate] auto-refresh the timeline every n secs (0 turns autoupdate off)
|
109
152
|
|
110
|
-
|
153
|
+
==== Widget-Options: TimelineWidget
|
111
154
|
|
112
|
-
|
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
|
-
|
159
|
+
==== Widget-Options: BarsWidget
|
115
160
|
|
116
|
-
|
161
|
+
[plot_style] one of: vertical, horizontal
|
162
|
+
[order_by]: order bars/columns by: value, field
|
117
163
|
|
118
|
-
|
164
|
+
==== Widget-Options: Numbers-Widget
|
119
165
|
|
166
|
+
==== Widget-Options: ToplistWidget
|
120
167
|
|
121
168
|
|
122
|
-
|
169
|
+
---
|
123
170
|
|
124
|
-
|
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
|
-
|
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
|
-
|
181
|
+
== Full Example
|
137
182
|
|
138
|
-
|
183
|
+
require "fnordmetric"
|
139
184
|
|
140
|
-
|
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
|
-
|
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
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
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
|
-
|
401
|
-
|
402
|
-
|
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
|
|