Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
FnordMetric is a redis/ruby-based realtime Event-Tracking app
JavaScript Ruby Scala
branch: v0.3

This branch is 2674 commits behind paulasmuth:master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
doc
haml
lib
pub
spec
.document
.gitignore
Gemfile
Gemfile.lock
Procfile
Rakefile
VERSION
fnordmetric.gemspec
readme.rdoc

readme.rdoc

FnordMetric

fnordmetric is a ruby event tracking gem

Usage: Standalone service

you can run the fnordmetric webapp as a standalone service. Your 'fnordmetric_server.rb' would propably look something like this:

require "rubygems"
require "fnordmetric"
require "thin"

FnordMetric.metric(:cars_total, :count => :true, :types => [:car_seen])
FnordMetric.metric(:passengers_total, :sum => :passengers, :types => [:car_seen])
FnordMetric.metric(:passengers_red_car, :sum => :passengers, :filter => { :color => :red }, :types => [:car_seen]) 
FnordMetric.metric(:passengers_blue_car, :sum => :passengers, :filter => { :color => :blue }, :types => [:car_seen]) 
FnordMetric.metric(:blue_to_red_ratio, :combine => lambda{ |x| x.passengers_blue_car / x.passengers_red_car })

FnordMetric.dashboard 'Passengers' do |passengers| 

  passengers.add_widget FnordMetric.widget(:passenger_blue_red_timeline, 
    :metrics => [:passengers_blue_car, :passengers_red_car], 
    :title => "Passengers (red/blue) timeline", 
    :type => :timeline
  )

  passengers.add_widget FnordMetric.widget(:passengers_total_timeline, 
    :metrics => [:cars_total, :passengers_total, :blue_to_red_ratio],
    :title => "Cars total + Passenger total + Red/Blue Ratio", 
    :autoupdate => true,
    :type => :numbers
  )

end

Mongoid.configure do |c| 
  c.master = Mongo::Connection.new.db("myfnordmetric") 
end

app = FnordMetric::App.new
Thin::Server.start('127.0.0.1', 2323, app)

when run as a standalone service events can be added via a very simple (restful) http post:

POST http://myapp:port/fnordmetric/events type=car_seen&color=red&passengers=2&speed=120

with curl:

curl -X POST -d "type=car_seen&color=red&passengers=2&speed=120" http://myapp:port/fnordmetric/events

Usage: From Rails/Rack

you need a mongodb instance and have to configure the mongoid-gem if your app doesn't already do that:

require 'fnordmetric' 
Mongoid.configure{ |c| c.master = Mongo::Connection.new.db("fnordmetric_test") }

that's all. you can start tracking data:

FnordMetric.track('car_seen', :color => "red",  :speed => 130, :passengers => 2)
FnordMetric.track('car_seen', :color => "pink", :speed => 150, :passengers => 1)
FnordMetric.track('car_seen', :color => "red",  :speed => 65,  :passengers => 4, :time => 50.hours.ago)
FnordMetric.track('car_seen', :color => "blue", :speed => 100, :passengers => 2, :time => 30.hours.ago)
FnordMetric.track('car_seen', :color => "red",  :speed => 123, :passengers => 2)
FnordMetric.track('car_seen', :color => "blue", :speed => 130, :passengers => 3)
FnordMetric.track('car_seen', :color => "red",  :speed => 142, :passengers => 2)

to see some shiny stats you first have to define a 'metric'. e.g. in 'config/initializers/fnordmetric.rb':

FnordMetric.metric(:colors_total,     :types => [:car_seen], :count => true, :unique => :color) 
FnordMetric.metric(:cars_total,       :types => [:car_seen], :count => true) 
FnordMetric.metric(:passengers_total, :types => [:car_seen], :sum => :passengers) 
FnordMetric.metric(:average_speed,    :types => [:car_seen], :average => :speed)

use combine-metrics to build your own 'indices':

FnordMetric.metric(:passengers_red_car, :sum => :passengers, :filter => { :colors => :red }, :types => [:car_seen]) 
FnordMetric.metric(:passengers_blue_car, :sum => :passengers, :filter => { :colors => :blue }, :types => [:car_seen]) 

FnordMetric.metric(:blue_to_red_ratio, :combine => lambda{ |x|
  x.passengers_blue_car / x.passengers_red_car
})

fnordmetric comes with javascript charting helper and a javascript dashboard app. to use them you have to load a rails engine by adding this line to your routes.rb:

mount FnordMetric::App => '/fnordmetric'

point your browser to 'myapp.com/fnordmetric' and you should see an empty dashboard. you can add dashboards and widgets like this (e.g. in initializers/fnordmetric.rb):

FnordMetric.dashboard 'Passengers' do |dash|  

  dash.add_widget FnordMetric.widget(:passenger_blue_red_timeline, 
    :metrics => [:passengers_blue_car, :passengers_red_car], 
    :title => "Passengers (red/blue)", 
    :type => :timeline
  )

  dash.add_widget FnordMetric.widget(:passengers_total_timeline, 
    :metrics => :passengers_total,
    :title => "Passenger blue/red Ratio", 
    :type => :timeline
  )

end

you can also get the raw numbers in your controller or model:

report = FnordMetric.report(:range => (3.days.ago..Time.now))
report.colors_total.current      # => 3  
report.colors_total.current      # => 3
report.cars_total.current        # => 7
report.average_speed.current     # => 113.6
report.passengers_total.current  # => 26
report.colors_total.current      # => 3

report.colors_total.at(40.hours.ago)   # => 1
report.colors_total.at(20.hours.ago)   # => 2

report.colors_total.values  
  => { <Date 03-10-11> => 1, <Date 04-10-11> => 2, <Date 05-10-11> => 3 }

report.colors_total.ticks
  => [ (<Date 03-10-11 00:00:00>..<Date 03-10-11 23:59:59>), (<Date 04-10...

and you can render the widgets in your own views:

widget = FnordMetric.widget(
  :passengers_red_blue_widget,
  :title => "Passengers (red/blue)",
  :type => :timeline,
  :metrics => [:passengers_blue_car, :passengers_red_car],
  :range => (14.days.ago..Time.now)
)

widget.render
  => "<script type="text/javascript" src="/fnordmetric/widget.js?type=..."

Option Reference

FnordMetric.metric (FnordMetric::Metric.new)

:count => true
return the total number of events (one of count, average, sum or combine is mandatory)
~
:average => (field)
return the avg of all “field”-values (one of count, average, sum or combine is mandatory)
~
:sum => (field)
return the sum of all “field”-values (one of count, average, sum or combine is mandatory)
~
:combine => (lambda)
custom accumulator (one of count, average, sum or combine is mandatory)
~
:unique => (field)
only consider events with unique (field)
~
:types => (types)
only consider events where type in types
~
:filter => (hash)
only consider events with fields matching (hash)
~
:select => (lambda)
only consider events for which (lambda) is true

FnordMetric.widget (FnordMetric::Widget.new)

:metrics => (fnord)
foobar (mandatory)
~
:title => (fnord)
foobar (mandatory)
~
:tick => (fnord)
foobar
~
:range => (fnord)
foobar
~
:current => (fnord)
FIXME: opt is actually named :include_curent
~
:report => (fnord)
foobar
~

TimelineWidget (FnordMetric::TimelineWidget.new)

:delta => (fnord)
foobar
~
:chart => (fnord)
foobar
~

TODO

  • metric-api: request caching

  • widget loader: hide iframe body content until css has loaded

  • timeline widget: make range input editable (+parse)

  • add mongo indices

  • default range (daily/hourly)

  • highcharts cleanup

  • numbers widget: date format

  • numbers widget: delta option

  • numbers widget: 'trend' option

  • timeline widget: timezones

  • metric-api: request caching

  • compare widget

  • funnel widget

  • widget: allow init without name (autogenerate)

  • virtual dashboard: all metrics (current+today+last week+last month) [+add metric btn]

  • add widgets/metrics via webapp?

  • auth?!

Copyright

Copyright © 2011 Paul Asmuth

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Something went wrong with that request. Please try again.