fnordmetric 0.6.2 → 0.6.3

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/README.md CHANGED
@@ -75,7 +75,7 @@ Installation
75
75
 
76
76
  or in your Gemfile:
77
77
 
78
- gem 'fnordmetric', '~> 0.5'
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
- * funnel-widget
340
- * combine/calculation gauges via opts_gauge({}, &block) (+calculate ctr)
341
- * timeline_widget: 'compare mode': compate gauge to yesterday
342
- * numbers_widget: handle decreasing vals
343
- * make listen-ports configurable
344
- * referal tracking fu (parse googlequeries)
345
- * trend detection
346
- * opt_event options: :increment => gauge_name
347
- * preconfigured default-dashboard (like google analytics)
348
- * pagview+ref-tracking via js-tracking-pixel
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.2
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.2"
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 Fnordmetric Dashboard
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.token
21
+ %a{:href=>"/#{namespace.token}"}=h namespace.title
22
22
 
23
23
  #wrap
24
24
  #tabs
25
25
  %ul
26
- %li.active.sessions
27
- .picto.piechart
28
- Active Users
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
  }
@@ -12,8 +12,17 @@ class FnordMetric::API
12
12
  end
13
13
 
14
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)
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
@@ -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 receive_data(chunk)
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|
@@ -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("oops, lost an event :(") unless event_data
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: 1}
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; background:url('/fnordmetric/sprite.png') no-repeat 14px 14px; opacity:0.7; }
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:url('/fnordmetric/sprite.png') no-repeat 0 -49px #eee;
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
@@ -14,6 +14,9 @@ require "fnordmetric"
14
14
  require "eventmachine"
15
15
  require 'em-hiredis'
16
16
 
17
+ def EM.defer; yield; end
18
+ def EM.next_tick; yield; end
19
+
17
20
  class RedisWrap
18
21
 
19
22
  def initialize(redis, callbackable=true)
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: fnordmetric
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.6.2
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