fnordmetric 0.6.2 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +17 -17
- data/VERSION +1 -1
- data/fnordmetric.gemspec +3 -2
- data/haml/app.haml +10 -5
- data/lib/fnordmetric/api.rb +12 -3
- data/lib/fnordmetric/app.rb +13 -2
- data/lib/fnordmetric/inbound_stream.rb +5 -1
- data/lib/fnordmetric/namespace.rb +21 -3
- data/lib/fnordmetric/worker.rb +1 -1
- data/pub/fnordmetric.css +3 -3
- data/spec/inbound_stream_spec.rb +34 -0
- data/spec/spec_helper.rb +3 -0
- metadata +3 -2
- data/pub/sprite.png +0 -0
data/README.md
CHANGED
@@ -75,7 +75,7 @@ Installation
|
|
75
75
|
|
76
76
|
or in your Gemfile:
|
77
77
|
|
78
|
-
gem 'fnordmetric', '
|
78
|
+
gem 'fnordmetric', '>= 0.6.3'
|
79
79
|
|
80
80
|
|
81
81
|
Documentation
|
@@ -177,6 +177,12 @@ require "fnordmetric"
|
|
177
177
|
|
178
178
|
FnordMetric.namespace :myapp do
|
179
179
|
|
180
|
+
# Set a custom namespace title, if you want one
|
181
|
+
# set_title "Emails sent"
|
182
|
+
|
183
|
+
# Hide the "Active Users" tab, if you want
|
184
|
+
# hide_active_users
|
185
|
+
|
180
186
|
# numeric (delta) gauge, 1-hour tick
|
181
187
|
gauge :messages_sent,
|
182
188
|
:tick => 1.hour.to_i,
|
@@ -336,19 +342,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
336
342
|
Todos
|
337
343
|
-----
|
338
344
|
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
* table/gauge-list-widget (with mini-stats!)
|
350
|
-
* prune the namespace-sessions-timline (remove event_ids older than x)
|
351
|
-
* prune the namespace-event-types-list (trim to max items)
|
352
|
-
* timelinewidget + numberswidget => should use redis hmget
|
353
|
-
* get multiple metrics in a single http get
|
354
|
-
* `{ _namespace: myns }` field
|
345
|
+
+ combine/calculation gauges via opts_gauge({}, &block) (+calculate ctr)
|
346
|
+
+ timeline_widget: 'compare mode': compare gauge to yesterday
|
347
|
+
+ numbers_widget: handle decreasing vals
|
348
|
+
+ opt_event options: :increment => gauge_name
|
349
|
+
+ prune the namespace-sessions-timline (remove event_ids older than x)
|
350
|
+
+ prune the namespace-event-types-list (trim to max items)
|
351
|
+
+ the funnel-widget
|
352
|
+
+ timelinewidget + numberswidget => should use redis hmget
|
353
|
+
+ get multiple metrics in a single http get
|
354
|
+
+ the `{ _namespace: myns }` field
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.3
|
data/fnordmetric.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
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.3"
|
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"]
|
@@ -62,7 +62,6 @@ Gem::Specification.new do |s|
|
|
62
62
|
"pub/fnordmetric.css",
|
63
63
|
"pub/fnordmetric.js",
|
64
64
|
"pub/loader.gif",
|
65
|
-
"pub/sprite.png",
|
66
65
|
"pub/vendor/highcharts.js",
|
67
66
|
"pub/vendor/jquery-1.6.1.min.js",
|
68
67
|
"spec/api_spec.rb",
|
@@ -72,6 +71,7 @@ Gem::Specification.new do |s|
|
|
72
71
|
"spec/event_spec.rb",
|
73
72
|
"spec/gauge_modifiers_spec.rb",
|
74
73
|
"spec/gauge_spec.rb",
|
74
|
+
"spec/inbound_stream_spec.rb",
|
75
75
|
"spec/namespace_spec.rb",
|
76
76
|
"spec/session_spec.rb",
|
77
77
|
"spec/spec_helper.rb",
|
@@ -91,6 +91,7 @@ Gem::Specification.new do |s|
|
|
91
91
|
"spec/event_spec.rb",
|
92
92
|
"spec/gauge_modifiers_spec.rb",
|
93
93
|
"spec/gauge_spec.rb",
|
94
|
+
"spec/inbound_stream_spec.rb",
|
94
95
|
"spec/namespace_spec.rb",
|
95
96
|
"spec/session_spec.rb",
|
96
97
|
"spec/spec_helper.rb",
|
data/haml/app.haml
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
%html
|
3
3
|
|
4
4
|
%head
|
5
|
-
%title
|
5
|
+
%title=current_namespace.title
|
6
6
|
|
7
7
|
%script(type="text/javascript" src="#{path_prefix}/vendor/jquery-1.6.1.min.js")
|
8
8
|
%script(type="text/javascript" src="#{path_prefix}/vendor/highcharts.js")
|
@@ -18,14 +18,15 @@
|
|
18
18
|
%ul
|
19
19
|
-namespaces.each do |key,namespace|
|
20
20
|
%li{:class => namespace.token == current_namespace.token ? 'active' : nil}
|
21
|
-
%a{:href=>"/#{namespace.token}"}=h namespace.
|
21
|
+
%a{:href=>"/#{namespace.token}"}=h namespace.title
|
22
22
|
|
23
23
|
#wrap
|
24
24
|
#tabs
|
25
25
|
%ul
|
26
|
-
|
27
|
-
.
|
28
|
-
|
26
|
+
- if current_namespace.active_users_available
|
27
|
+
%li.active.sessions
|
28
|
+
.picto.piechart
|
29
|
+
Active Users
|
29
30
|
|
30
31
|
-current_namespace.dashboards.each do |key,dashboard|
|
31
32
|
%li.dashboard{:rel => dashboard.token}
|
@@ -64,6 +65,10 @@
|
|
64
65
|
resizeViewport();
|
65
66
|
$(window).resize(resizeViewport);
|
66
67
|
|
68
|
+
if(!#{current_namespace.active_users_available.to_s}) {
|
69
|
+
$('#tabs li:first').trigger('click');
|
70
|
+
}
|
71
|
+
|
67
72
|
if(window.location.hash){
|
68
73
|
$('#tabs li.dashboard[rel="'+window.location.hash.slice(1)+'"]').trigger('click');
|
69
74
|
}
|
data/lib/fnordmetric/api.rb
CHANGED
@@ -12,8 +12,17 @@ class FnordMetric::API
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def event(event_data)
|
15
|
-
|
16
|
-
|
15
|
+
begin
|
16
|
+
if event_data.is_a?(Hash)
|
17
|
+
event_data = event_data.to_json
|
18
|
+
else
|
19
|
+
JSON.parse(event_data) # void ;)
|
20
|
+
end
|
21
|
+
rescue JSON::ParserError
|
22
|
+
FnordMetric.log("event_lost: can't parse json")
|
23
|
+
else
|
24
|
+
push_event(get_next_uuid, event_data)
|
25
|
+
end
|
17
26
|
end
|
18
27
|
|
19
28
|
def disconnect
|
@@ -23,7 +32,7 @@ class FnordMetric::API
|
|
23
32
|
private
|
24
33
|
|
25
34
|
def push_event(event_id, event_data)
|
26
|
-
prefix = @@opts[:redis_prefix]
|
35
|
+
prefix = @@opts[:redis_prefix]
|
27
36
|
@redis.hincrby "#{prefix}-testdata", "events_received", 1
|
28
37
|
@redis.hincrby "#{prefix}-stats", "events_received", 1
|
29
38
|
@redis.set "#{prefix}-event-#{event_id}", event_data
|
data/lib/fnordmetric/app.rb
CHANGED
@@ -3,6 +3,12 @@
|
|
3
3
|
class FnordMetric::App < Sinatra::Base
|
4
4
|
|
5
5
|
@@sessions = Hash.new
|
6
|
+
@@public_files = {
|
7
|
+
"fnordmetric.css" => "text/css",
|
8
|
+
"fnordmetric.js" => "application/x-javascript",
|
9
|
+
"vendor/jquery-1.6.1.min.js" => "application/x-javascript",
|
10
|
+
"vendor/highcharts.js" => "application/x-javascript"
|
11
|
+
}
|
6
12
|
|
7
13
|
Encoding.default_external = Encoding::UTF_8
|
8
14
|
|
@@ -11,8 +17,7 @@ class FnordMetric::App < Sinatra::Base
|
|
11
17
|
enable :session
|
12
18
|
|
13
19
|
set :haml, :format => :html5
|
14
|
-
set :views, ::File.expand_path('../../../haml', __FILE__)
|
15
|
-
set :public_folder, ::File.expand_path('../../../pub', __FILE__)
|
20
|
+
set :views, ::File.expand_path('../../../haml', __FILE__)
|
16
21
|
|
17
22
|
def initialize(namespaces, opts)
|
18
23
|
@namespaces = {}
|
@@ -126,6 +131,12 @@ class FnordMetric::App < Sinatra::Base
|
|
126
131
|
track_event((8**32).to_s(36), parse_params(params))
|
127
132
|
end
|
128
133
|
|
134
|
+
@@public_files.each do |public_file, public_file_type|
|
135
|
+
get "/#{public_file}" do
|
136
|
+
content_type(public_file_type)
|
137
|
+
::File.open(::File.expand_path("../../../pub/#{public_file}", __FILE__)).read
|
138
|
+
end
|
139
|
+
end
|
129
140
|
private
|
130
141
|
|
131
142
|
def parse_params(hash)
|
@@ -6,7 +6,11 @@ class FnordMetric::InboundStream < EventMachine::Connection
|
|
6
6
|
EM.start_server(*opts[:inbound_stream], self)
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
9
|
+
def self.options(opts)
|
10
|
+
@@opts = opts
|
11
|
+
end
|
12
|
+
|
13
|
+
def receive_data(chunk)
|
10
14
|
@buffer << chunk
|
11
15
|
EM.defer{ next_event }
|
12
16
|
end
|
@@ -2,12 +2,14 @@ class FnordMetric::Namespace
|
|
2
2
|
|
3
3
|
attr_reader :handlers, :gauges, :opts, :key, :dashboards
|
4
4
|
|
5
|
-
@@opts = [:event, :gauge, :widget]
|
5
|
+
@@opts = [:event, :gauge, :widget, :set_title, :active_users_available]
|
6
6
|
|
7
7
|
def initialize(key, opts)
|
8
8
|
@gauges = Hash.new
|
9
9
|
@dashboards = Hash.new
|
10
|
-
@handlers = Hash.new
|
10
|
+
@handlers = Hash.new
|
11
|
+
@title = key
|
12
|
+
@active_users_available = true
|
11
13
|
@opts = opts
|
12
14
|
@key = key
|
13
15
|
end
|
@@ -63,7 +65,15 @@ class FnordMetric::Namespace
|
|
63
65
|
def token
|
64
66
|
@key
|
65
67
|
end
|
66
|
-
|
68
|
+
|
69
|
+
def title
|
70
|
+
@title
|
71
|
+
end
|
72
|
+
|
73
|
+
def active_users_available
|
74
|
+
@active_users_available
|
75
|
+
end
|
76
|
+
|
67
77
|
def dashboards(name=nil)
|
68
78
|
return @dashboards unless name
|
69
79
|
dash = FnordMetric::Dashboard.new(:title => name)
|
@@ -85,6 +95,14 @@ class FnordMetric::Namespace
|
|
85
95
|
send(:"opt_#{m}", *args, &block)
|
86
96
|
end
|
87
97
|
|
98
|
+
def hide_active_users
|
99
|
+
@active_users_available = false
|
100
|
+
end
|
101
|
+
|
102
|
+
def set_title(key)
|
103
|
+
@title = key
|
104
|
+
end
|
105
|
+
|
88
106
|
def opt_event(event_type, opts={}, &block)
|
89
107
|
opts.merge!(:redis => @redis, :gauges => @gauges)
|
90
108
|
FnordMetric::Context.new(opts, block).tap do |context|
|
data/lib/fnordmetric/worker.rb
CHANGED
@@ -22,7 +22,7 @@ class FnordMetric::Worker
|
|
22
22
|
@redis.blpop(queue_key, 0).callback do |list, event_id|
|
23
23
|
@redis.get(event_key(event_id)).callback do |event_data|
|
24
24
|
process_event(event_id, event_data) if event_data
|
25
|
-
FnordMetric.log("
|
25
|
+
FnordMetric.log("event_lost: event_data not found for event-id '#{event_id}'") unless event_data
|
26
26
|
EM.next_tick(&method(:tick))
|
27
27
|
@redis.hincrby(stats_key, :events_processed, 1)
|
28
28
|
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%; z-index:
|
7
|
+
.topbar{ height:38px; background:#24272c; position:fixed; top:0px; width:100%; z-index: 1000;}
|
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; }
|
@@ -21,7 +21,7 @@ body{ background:#3b3e45; color:#333; margin:0; padding:0; overflow-y:scroll; fo
|
|
21
21
|
#tabs ul li:hover, #tabs ul li:hover:after{ color:#fff; }
|
22
22
|
#tabs ul li:hover .picto{ opacity:1; }
|
23
23
|
|
24
|
-
.picto{ display:block; height:14px; width:14px; float:left;
|
24
|
+
.picto{ display:block; height:14px; width:14px; float:left; opacity:0.7; }
|
25
25
|
.picto.piechart{ background-position:-42px -173px; width:9px; margin-right:5px; }
|
26
26
|
|
27
27
|
#viewport{ float:left; margin-left:150px; margin-top:30px; border-radius:3px; min-width:790px; }
|
@@ -73,7 +73,7 @@ text-shadow: 1px 0px 2px rgba(255, 255, 255, 1);
|
|
73
73
|
.headbar .button{
|
74
74
|
margin:8px 0px; height:16px; float:right; display:block;
|
75
75
|
margin-right:-1px;
|
76
|
-
background
|
76
|
+
background:#eee;
|
77
77
|
border:1px solid #999;
|
78
78
|
border-bottom-color:#888;
|
79
79
|
-webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, .1);
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require ::File.expand_path('../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
describe FnordMetric::InboundStream do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
@redis = Redis.new
|
7
|
+
@redis_wrap = RedisWrap.new(@redis)
|
8
|
+
FnordMetric::InboundStream.options(
|
9
|
+
:redis_url => "redis://localhost:6379",
|
10
|
+
:redis_prefix => "fnordmetric-test",
|
11
|
+
:event_queue_ttl => 120
|
12
|
+
)
|
13
|
+
@inbound_stream = FnordMetric::InboundStream.new(nil)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "pushing new events" do
|
17
|
+
it "should add parsable event to the queue" do
|
18
|
+
data = %Q{{"_type": "started"}\n}
|
19
|
+
|
20
|
+
lambda {
|
21
|
+
@inbound_stream.receive_data data
|
22
|
+
}.should change { @redis.llen("fnordmetric-test-queue") }.by +1
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should reject non parsable events" do
|
26
|
+
broken_data = %Q{{"_type": \n"started"}\n}
|
27
|
+
|
28
|
+
lambda {
|
29
|
+
@inbound_stream.receive_data broken_data
|
30
|
+
}.should_not change { @redis.llen("fnordmetric-test-queue") }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
data/spec/spec_helper.rb
CHANGED
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.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Paul Asmuth
|
@@ -266,7 +266,6 @@ files:
|
|
266
266
|
- pub/fnordmetric.css
|
267
267
|
- pub/fnordmetric.js
|
268
268
|
- pub/loader.gif
|
269
|
-
- pub/sprite.png
|
270
269
|
- pub/vendor/highcharts.js
|
271
270
|
- pub/vendor/jquery-1.6.1.min.js
|
272
271
|
- spec/api_spec.rb
|
@@ -276,6 +275,7 @@ files:
|
|
276
275
|
- spec/event_spec.rb
|
277
276
|
- spec/gauge_modifiers_spec.rb
|
278
277
|
- spec/gauge_spec.rb
|
278
|
+
- spec/inbound_stream_spec.rb
|
279
279
|
- spec/namespace_spec.rb
|
280
280
|
- spec/session_spec.rb
|
281
281
|
- spec/spec_helper.rb
|
@@ -317,6 +317,7 @@ test_files:
|
|
317
317
|
- spec/event_spec.rb
|
318
318
|
- spec/gauge_modifiers_spec.rb
|
319
319
|
- spec/gauge_spec.rb
|
320
|
+
- spec/inbound_stream_spec.rb
|
320
321
|
- spec/namespace_spec.rb
|
321
322
|
- spec/session_spec.rb
|
322
323
|
- spec/spec_helper.rb
|
data/pub/sprite.png
DELETED
Binary file
|