fnordmetric 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/fnordmetric.gemspec +6 -3
- data/lib/fnordmetric.rb +50 -33
- data/lib/fnordmetric/api.rb +38 -0
- data/lib/fnordmetric/app.rb +13 -13
- data/lib/fnordmetric/inbound_stream.rb +5 -22
- data/pub/fnordmetric.css +2 -2
- data/pub/fnordmetric.js +11 -7
- data/spec/api_spec.rb +49 -0
- metadata +6 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.2
|
data/fnordmetric.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{fnordmetric}
|
8
|
-
s.version = "0.6.
|
8
|
+
s.version = "0.6.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Paul Asmuth"]
|
12
|
-
s.date = %q{2012-01-
|
12
|
+
s.date = %q{2012-01-13}
|
13
13
|
s.description = %q{FnordMetric is a Ruby Event-Tracking gem on steroids}
|
14
14
|
s.email = %q{paul@paulasmuth.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
|
|
30
30
|
"haml/app.haml",
|
31
31
|
"haml/widget.haml",
|
32
32
|
"lib/fnordmetric.rb",
|
33
|
+
"lib/fnordmetric/api.rb",
|
33
34
|
"lib/fnordmetric/app.rb",
|
34
35
|
"lib/fnordmetric/average_metric.rb",
|
35
36
|
"lib/fnordmetric/bars_widget.rb",
|
@@ -64,6 +65,7 @@ Gem::Specification.new do |s|
|
|
64
65
|
"pub/sprite.png",
|
65
66
|
"pub/vendor/highcharts.js",
|
66
67
|
"pub/vendor/jquery-1.6.1.min.js",
|
68
|
+
"spec/api_spec.rb",
|
67
69
|
"spec/app_spec.rb",
|
68
70
|
"spec/context_spec.rb",
|
69
71
|
"spec/dashboard_spec.rb",
|
@@ -79,9 +81,10 @@ Gem::Specification.new do |s|
|
|
79
81
|
s.homepage = %q{http://github.com/paulasmuth/fnordmetric}
|
80
82
|
s.licenses = ["MIT"]
|
81
83
|
s.require_paths = ["lib"]
|
82
|
-
s.rubygems_version = %q{1.
|
84
|
+
s.rubygems_version = %q{1.6.2}
|
83
85
|
s.summary = %q{FnordMetric is a Ruby Event-Tracking gem on steroids}
|
84
86
|
s.test_files = [
|
87
|
+
"spec/api_spec.rb",
|
85
88
|
"spec/app_spec.rb",
|
86
89
|
"spec/context_spec.rb",
|
87
90
|
"spec/dashboard_spec.rb",
|
data/lib/fnordmetric.rb
CHANGED
@@ -12,8 +12,8 @@ module FnordMetric
|
|
12
12
|
|
13
13
|
@@namespaces = {}
|
14
14
|
|
15
|
-
def self.namespace(key=nil, &block)
|
16
|
-
@@namespaces[key] = block
|
15
|
+
def self.namespace(key=nil, &block)
|
16
|
+
@@namespaces[key] = block
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.server_configuration=(configuration)
|
@@ -23,7 +23,7 @@ module FnordMetric
|
|
23
23
|
def self.default_options(opts)
|
24
24
|
|
25
25
|
opts[:redis_url] ||= "redis://localhost:6379"
|
26
|
-
opts[:redis_prefix] ||= "fnordmetric"
|
26
|
+
opts[:redis_prefix] ||= "fnordmetric"
|
27
27
|
|
28
28
|
opts[:inbound_stream] ||= ["0.0.0.0", "1337"]
|
29
29
|
opts[:web_interface] ||= ["0.0.0.0", "4242"]
|
@@ -38,8 +38,8 @@ module FnordMetric
|
|
38
38
|
opts[:event_data_ttl] ||= 3600*24*30
|
39
39
|
|
40
40
|
# session data is kept for one month
|
41
|
-
opts[:session_data_ttl] ||= 3600*24*30
|
42
|
-
|
41
|
+
opts[:session_data_ttl] ||= 3600*24*30
|
42
|
+
|
43
43
|
opts
|
44
44
|
end
|
45
45
|
|
@@ -49,25 +49,10 @@ module FnordMetric
|
|
49
49
|
trap("TERM", &method(:shutdown))
|
50
50
|
trap("INT", &method(:shutdown))
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
if opts[:start_worker]
|
55
|
-
worker = Worker.new(@@namespaces.clone, opts)
|
56
|
-
worker.ready!
|
57
|
-
end
|
58
|
-
|
59
|
-
if opts[:inbound_stream]
|
60
|
-
begin
|
61
|
-
inbound_stream = InboundStream.start(opts)
|
62
|
-
log "listening on tcp##{opts[:inbound_stream].join(":")}"
|
63
|
-
rescue
|
64
|
-
log "cant start FnordMetric::InboundStream. port in use?"
|
65
|
-
end
|
66
|
-
end
|
52
|
+
app = embedded(opts)
|
67
53
|
|
68
54
|
if opts[:web_interface]
|
69
|
-
begin
|
70
|
-
app = FnordMetric::App.new(@@namespaces.clone, opts)
|
55
|
+
begin
|
71
56
|
Thin::Server.start(*opts[:web_interface], app)
|
72
57
|
log "listening on http##{opts[:web_interface].join(":")}"
|
73
58
|
rescue Exception => e
|
@@ -75,14 +60,7 @@ module FnordMetric
|
|
75
60
|
end
|
76
61
|
end
|
77
62
|
|
78
|
-
|
79
|
-
redis = connect_redis(opts[:redis_url])
|
80
|
-
EM::PeriodicTimer.new(opts[:print_stats]) do
|
81
|
-
print_stats(opts, redis)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
end
|
63
|
+
end
|
86
64
|
end
|
87
65
|
|
88
66
|
def self.log(msg)
|
@@ -113,21 +91,60 @@ module FnordMetric
|
|
113
91
|
|
114
92
|
def self.print_stats(opts, redis) # FIXME: refactor this mess
|
115
93
|
keys = [:events_received, :events_processed]
|
116
|
-
redis.llen("#{opts[:redis_prefix]}-queue") do |queue_length|
|
94
|
+
redis.llen("#{opts[:redis_prefix]}-queue") do |queue_length|
|
117
95
|
redis.hmget("#{opts[:redis_prefix]}-stats", *keys) do |data|
|
118
96
|
data_human = keys.size.times.map{|n|"#{keys[n]}: #{data[n]}"}
|
119
97
|
log "#{data_human.join(", ")}, queue_length: #{queue_length}"
|
120
|
-
end
|
98
|
+
end
|
121
99
|
end
|
122
100
|
end
|
123
101
|
|
124
|
-
def self.standalone
|
102
|
+
def self.standalone
|
125
103
|
require "fnordmetric/logger"
|
126
104
|
require "fnordmetric/standalone"
|
127
105
|
end
|
128
106
|
|
107
|
+
# returns a Rack app which can be mounted under any path.
|
108
|
+
# `:start_worker` starts a worker
|
109
|
+
# `:inbound_stream` starts the TCP interface
|
110
|
+
# `:print_stats` periodicaly prints worker stats
|
111
|
+
def self.embedded(opts={})
|
112
|
+
opts = default_options(opts)
|
113
|
+
app = nil
|
114
|
+
|
115
|
+
if opts[:rack_app] or opts[:web_interface]
|
116
|
+
app = FnordMetric::App.new(@@namespaces.clone, opts)
|
117
|
+
end
|
118
|
+
|
119
|
+
EM.next_tick do
|
120
|
+
if opts[:start_worker]
|
121
|
+
worker = Worker.new(@@namespaces.clone, opts)
|
122
|
+
worker.ready!
|
123
|
+
end
|
124
|
+
|
125
|
+
if opts[:inbound_stream]
|
126
|
+
begin
|
127
|
+
inbound_stream = InboundStream.start(opts)
|
128
|
+
log "listening on tcp##{opts[:inbound_stream].join(":")}"
|
129
|
+
rescue
|
130
|
+
log "cant start FnordMetric::InboundStream. port in use?"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
if opts[:print_stats]
|
135
|
+
redis = connect_redis(opts[:redis_url])
|
136
|
+
EM::PeriodicTimer.new(opts[:print_stats]) do
|
137
|
+
print_stats(opts, redis)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
app
|
143
|
+
end
|
144
|
+
|
129
145
|
end
|
130
146
|
|
147
|
+
require "fnordmetric/api"
|
131
148
|
require "fnordmetric/inbound_stream"
|
132
149
|
require "fnordmetric/worker"
|
133
150
|
require "fnordmetric/widget"
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
class FnordMetric::API
|
3
|
+
@@opts = nil
|
4
|
+
def initialize opts
|
5
|
+
@@opts = FnordMetric.default_options(opts)
|
6
|
+
connect
|
7
|
+
end
|
8
|
+
|
9
|
+
def connect
|
10
|
+
@redis = @@opts[:redis] if @@opts[:redis]
|
11
|
+
@redis = Redis.connect(:url => @@opts[:redis_url])
|
12
|
+
end
|
13
|
+
|
14
|
+
def event(event_data)
|
15
|
+
event_data = event_data.to_json if event_data.is_a?(Hash)
|
16
|
+
push_event(get_next_uuid, event_data)
|
17
|
+
end
|
18
|
+
|
19
|
+
def disconnect
|
20
|
+
@redis.quit
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def push_event(event_id, event_data)
|
26
|
+
prefix = @@opts[:redis_prefix]
|
27
|
+
@redis.hincrby "#{prefix}-testdata", "events_received", 1
|
28
|
+
@redis.hincrby "#{prefix}-stats", "events_received", 1
|
29
|
+
@redis.set "#{prefix}-event-#{event_id}", event_data
|
30
|
+
@redis.lpush "#{prefix}-queue", event_id
|
31
|
+
@redis.expire "#{prefix}-event-#{event_id}", @@opts[:event_queue_ttl]
|
32
|
+
event_id
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_next_uuid
|
36
|
+
SecureRandom.uuid
|
37
|
+
end
|
38
|
+
end
|
data/lib/fnordmetric/app.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
class FnordMetric::App < Sinatra::Base
|
4
|
-
|
4
|
+
|
5
5
|
@@sessions = Hash.new
|
6
|
-
|
6
|
+
|
7
7
|
Encoding.default_external = Encoding::UTF_8
|
8
8
|
|
9
9
|
#use Rack::Reloader, 0
|
10
|
-
|
10
|
+
|
11
11
|
enable :session
|
12
12
|
|
13
|
-
set :haml, :format => :html5
|
13
|
+
set :haml, :format => :html5
|
14
14
|
set :views, ::File.expand_path('../../../haml', __FILE__)
|
15
|
-
set :
|
15
|
+
set :public_folder, ::File.expand_path('../../../pub', __FILE__)
|
16
16
|
|
17
17
|
def initialize(namespaces, opts)
|
18
18
|
@namespaces = {}
|
@@ -25,7 +25,7 @@ class FnordMetric::App < Sinatra::Base
|
|
25
25
|
end
|
26
26
|
super(nil)
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
helpers do
|
30
30
|
include Rack::Utils
|
31
31
|
alias_method :h, :escape_html
|
@@ -38,7 +38,7 @@ class FnordMetric::App < Sinatra::Base
|
|
38
38
|
@namespaces
|
39
39
|
end
|
40
40
|
|
41
|
-
def current_namespace
|
41
|
+
def current_namespace
|
42
42
|
@namespaces[@namespaces.keys.detect{ |k|
|
43
43
|
k.to_s == params[:namespace]
|
44
44
|
}.try(:intern)]
|
@@ -47,7 +47,7 @@ class FnordMetric::App < Sinatra::Base
|
|
47
47
|
end
|
48
48
|
|
49
49
|
if ENV['RACK_ENV'] == "test"
|
50
|
-
set :raise_errors, true
|
50
|
+
set :raise_errors, true
|
51
51
|
end
|
52
52
|
|
53
53
|
get '/' do
|
@@ -78,7 +78,7 @@ class FnordMetric::App < Sinatra::Base
|
|
78
78
|
params[:sum] ? { :sum => _values.values.compact.map(&:to_i).sum } : _values
|
79
79
|
else
|
80
80
|
{ (_t = gauge.tick_at(Time.now.to_i-gauge.tick)) => gauge.value_at(_t) }
|
81
|
-
end
|
81
|
+
end
|
82
82
|
|
83
83
|
data.to_json
|
84
84
|
end
|
@@ -88,14 +88,14 @@ class FnordMetric::App < Sinatra::Base
|
|
88
88
|
sessions = current_namespace.sessions(:all, :limit => 100).map do |session|
|
89
89
|
session.fetch_data!
|
90
90
|
session.to_json
|
91
|
-
end
|
91
|
+
end
|
92
92
|
|
93
93
|
{ :sessions => sessions }.to_json
|
94
94
|
end
|
95
95
|
|
96
96
|
get '/:namespace/events' do
|
97
97
|
|
98
|
-
events = if params[:type]
|
98
|
+
events = if params[:type]
|
99
99
|
current_namespace.events(:by_type, :type => params[:type])
|
100
100
|
elsif params[:session_key]
|
101
101
|
current_namespace.events(:by_session_key, :session_key => params[:session_key])
|
@@ -122,7 +122,7 @@ class FnordMetric::App < Sinatra::Base
|
|
122
122
|
end
|
123
123
|
|
124
124
|
post '/events' do
|
125
|
-
halt 400, 'please specify the event_type (_type)' unless params["_type"]
|
125
|
+
halt 400, 'please specify the event_type (_type)' unless params["_type"]
|
126
126
|
track_event((8**32).to_s(36), parse_params(params))
|
127
127
|
end
|
128
128
|
|
@@ -130,7 +130,7 @@ private
|
|
130
130
|
|
131
131
|
def parse_params(hash)
|
132
132
|
hash.tap do |h|
|
133
|
-
h.keys.each{ |k| h[k] = parse_param(h[k]) }
|
133
|
+
h.keys.each{ |k| h[k] = parse_param(h[k]) }
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
@@ -1,6 +1,4 @@
|
|
1
|
-
require 'securerandom'
|
2
1
|
class FnordMetric::InboundStream < EventMachine::Connection
|
3
|
-
|
4
2
|
@@opts = nil
|
5
3
|
|
6
4
|
def self.start(opts)
|
@@ -13,18 +11,6 @@ class FnordMetric::InboundStream < EventMachine::Connection
|
|
13
11
|
EM.defer{ next_event }
|
14
12
|
end
|
15
13
|
|
16
|
-
def push_event(event_id, event_data)
|
17
|
-
prefix = @@opts[:redis_prefix]
|
18
|
-
|
19
|
-
@redis.hincrby "#{prefix}-stats", "events_received", 1
|
20
|
-
@redis.set "#{prefix}-event-#{event_id}", event_data
|
21
|
-
@redis.lpush "#{prefix}-queue", event_id
|
22
|
-
@redis.expire "#{prefix}-event-#{event_id}", @@opts[:event_queue_ttl]
|
23
|
-
|
24
|
-
@events_buffered -= 1
|
25
|
-
close_connection?
|
26
|
-
end
|
27
|
-
|
28
14
|
def next_event
|
29
15
|
read_next_event
|
30
16
|
push_next_event
|
@@ -39,20 +25,18 @@ class FnordMetric::InboundStream < EventMachine::Connection
|
|
39
25
|
|
40
26
|
def push_next_event
|
41
27
|
return true if @events.empty?
|
42
|
-
|
28
|
+
@events_buffered -= 1
|
29
|
+
@api.event(@events.pop)
|
30
|
+
close_connection?
|
43
31
|
EM.next_tick(&method(:push_next_event))
|
44
32
|
end
|
45
33
|
|
46
|
-
def get_next_uuid
|
47
|
-
SecureRandom.uuid
|
48
|
-
end
|
49
|
-
|
50
34
|
def close_connection?
|
51
|
-
@
|
35
|
+
@api.disconnect unless @streaming || (@events_buffered!=0)
|
52
36
|
end
|
53
37
|
|
54
38
|
def post_init
|
55
|
-
@
|
39
|
+
@api = FnordMetric::API.new(@@opts)
|
56
40
|
@events_buffered = 0
|
57
41
|
@streaming = true
|
58
42
|
@buffer = ""
|
@@ -63,5 +47,4 @@ class FnordMetric::InboundStream < EventMachine::Connection
|
|
63
47
|
@streaming = false
|
64
48
|
close_connection?
|
65
49
|
end
|
66
|
-
|
67
50
|
end
|
data/pub/fnordmetric.css
CHANGED
@@ -4,7 +4,7 @@ body{ background:#3b3e45; color:#333; margin:0; padding:0; overflow-y:scroll; fo
|
|
4
4
|
.shown{ display: block; }
|
5
5
|
.hidden{ display: none; }
|
6
6
|
|
7
|
-
.topbar{ height:38px; background:#24272c; position:fixed; top:0px; width:100%;}
|
7
|
+
.topbar{ height:38px; background:#24272c; position:fixed; top:0px; width:100%; z-index: 1}
|
8
8
|
.topbar ul { list-style-type:none; margin:0; }
|
9
9
|
.topbar ul li { padding: 5px 10px 5px 10px; background-color:#3b3e45; display:inline; height:38px; line-height:38px; border-radius:3px; margin-right:5px;}
|
10
10
|
.topbar ul li a { color:#ccc; font-size:13px; text-decoration:none; }
|
@@ -122,7 +122,7 @@ ul.session_list li .history:hover{ color:#333; text-decoration:underline; }
|
|
122
122
|
.sessions_feed ul.feed_inner li .message{ font-size:12px; line-height:19px; padding-top:9px; display:block; }
|
123
123
|
.sessions_feed ul.feed_inner li .properties{ margin-left:50px; font-size:10px; display:block; color:#555; }
|
124
124
|
.sessions_feed ul.feed_inner li .time{ font-size:10px; line-height:20px; padding-top:19px; padding-right:10px; display:block; color:#999; float:right; font-style:italic; }
|
125
|
-
.sessions_feed ul.feed_inner li .picture{ height:40px; overflow:hidden; width:40px; float:left; background:#333; margin:7px 10px 0 0;
|
125
|
+
.sessions_feed ul.feed_inner li .picture{ height:40px; overflow:hidden; width:40px; float:left; background:#333; margin:7px 10px 0 0; cursor:pointer; }
|
126
126
|
.sessions_sidebar{ min-height:1200px; float:right; width:250px; border-left:1px solid #C7C9CC; }
|
127
127
|
.events_sidebar{ min-height:1200px; float:left; width:200px; border-right:1px solid #C7C9CC; }
|
128
128
|
|
data/pub/fnordmetric.js
CHANGED
@@ -959,8 +959,6 @@ var FnordMetric = (function(){
|
|
959
959
|
|
960
960
|
listElem.append(
|
961
961
|
$('<li class="session"></li>').append(
|
962
|
-
$('<input type="checkbox" />').click(function(){ updateEventFilter(); })
|
963
|
-
).append(
|
964
962
|
$('<div class="picture"></div>').html(session_picture)
|
965
963
|
).append(
|
966
964
|
$('<span class="name"></span>').html(session_name)
|
@@ -969,9 +967,9 @@ var FnordMetric = (function(){
|
|
969
967
|
).append(
|
970
968
|
$('<span class="history"></span>').html('history')
|
971
969
|
.click(function(){
|
972
|
-
setCheckboxesCheckedState(true, false);
|
973
|
-
|
974
|
-
|
970
|
+
setCheckboxesCheckedState(true, false);
|
971
|
+
updateEventFilter();
|
972
|
+
loadEventHistory({session_key: session_data["session_key"]});
|
975
973
|
})
|
976
974
|
).attr('data-session', session_data["session_key"])
|
977
975
|
);
|
@@ -1002,16 +1000,22 @@ var FnordMetric = (function(){
|
|
1002
1000
|
event_time.html(formatTimeOfDay(event_data._time));
|
1003
1001
|
|
1004
1002
|
if(event_data._session_key && event_data._session_key.length > 0){
|
1003
|
+
var __session_key = event_data._session_key;
|
1004
|
+
var load_usersession = (function(){
|
1005
|
+
loadEventHistory({session_key: __session_key});
|
1006
|
+
});
|
1005
1007
|
if(session_data=sessionData[event_data._session_key]){
|
1006
1008
|
if(session_data._name){
|
1007
1009
|
event_props.append(
|
1008
|
-
$('<strong></strong>').html(session_data._name)
|
1010
|
+
$('<strong></strong>').html(session_data._name).css({
|
1011
|
+
'cursor': 'pointer'
|
1012
|
+
}).click(load_usersession)
|
1009
1013
|
);
|
1010
1014
|
}
|
1011
1015
|
if(session_data._picture){
|
1012
1016
|
event_picture.append(
|
1013
1017
|
$('<img width="40" />').attr('src', session_data._picture)
|
1014
|
-
)
|
1018
|
+
).click(load_usersession);
|
1015
1019
|
}
|
1016
1020
|
}
|
1017
1021
|
}
|
data/spec/api_spec.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require ::File.expand_path('../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
describe FnordMetric::Event do
|
4
|
+
|
5
|
+
include FnordMetric
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
@now = Time.utc(1992,01,13,5,23,23).to_i
|
9
|
+
@redis = Redis.new
|
10
|
+
@redis_wrap = RedisWrap.new(@redis)
|
11
|
+
|
12
|
+
@namespace = "fnordmetric-test-ns1234-api"
|
13
|
+
@timeline = "#{@namespace}-timeline"
|
14
|
+
|
15
|
+
@opts = {
|
16
|
+
:namespace_prefix => "#{@namespace}",
|
17
|
+
:redis_prefix => "fnordmetric-test",
|
18
|
+
:redis => @redis
|
19
|
+
}
|
20
|
+
@api = API.new @opts
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "creating events using API" do
|
24
|
+
|
25
|
+
before(:each) do
|
26
|
+
@redis.keys("fnordmetric-test-*").each { |k| @redis.del(k) }
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should create an event from a (json-)string" do
|
30
|
+
json_string = {
|
31
|
+
:_type => "Fn0rd123",
|
32
|
+
:_time => @now
|
33
|
+
}.to_json
|
34
|
+
event_id = @api.event(json_string)
|
35
|
+
event = Event.find(event_id, @opts)
|
36
|
+
event.type.should == "Fn0rd123"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should create an event from a hash" do
|
40
|
+
event_id = @api.event(
|
41
|
+
:_type => "Fn0rd234",
|
42
|
+
:_time => @now
|
43
|
+
)
|
44
|
+
event = Event.find(event_id, @opts)
|
45
|
+
event.type.should == "Fn0rd234"
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: fnordmetric
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.6.
|
5
|
+
version: 0.6.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Paul Asmuth
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2012-01-
|
13
|
+
date: 2012-01-13 00:00:00 +01:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -234,6 +234,7 @@ files:
|
|
234
234
|
- haml/app.haml
|
235
235
|
- haml/widget.haml
|
236
236
|
- lib/fnordmetric.rb
|
237
|
+
- lib/fnordmetric/api.rb
|
237
238
|
- lib/fnordmetric/app.rb
|
238
239
|
- lib/fnordmetric/average_metric.rb
|
239
240
|
- lib/fnordmetric/bars_widget.rb
|
@@ -268,6 +269,7 @@ files:
|
|
268
269
|
- pub/sprite.png
|
269
270
|
- pub/vendor/highcharts.js
|
270
271
|
- pub/vendor/jquery-1.6.1.min.js
|
272
|
+
- spec/api_spec.rb
|
271
273
|
- spec/app_spec.rb
|
272
274
|
- spec/context_spec.rb
|
273
275
|
- spec/dashboard_spec.rb
|
@@ -303,11 +305,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
303
305
|
requirements: []
|
304
306
|
|
305
307
|
rubyforge_project:
|
306
|
-
rubygems_version: 1.
|
308
|
+
rubygems_version: 1.6.2
|
307
309
|
signing_key:
|
308
310
|
specification_version: 3
|
309
311
|
summary: FnordMetric is a Ruby Event-Tracking gem on steroids
|
310
312
|
test_files:
|
313
|
+
- spec/api_spec.rb
|
311
314
|
- spec/app_spec.rb
|
312
315
|
- spec/context_spec.rb
|
313
316
|
- spec/dashboard_spec.rb
|