mouth 0.8.0 → 0.8.1

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/.gitignore CHANGED
@@ -4,4 +4,4 @@
4
4
  log/*.log
5
5
  log/*.pid
6
6
  Gemfile.lock
7
-
7
+ *.gem
data/Capfile CHANGED
@@ -17,6 +17,7 @@ task :omg do
17
17
  loc = "#{home}/#{file}"
18
18
  upload file, loc
19
19
  sudo "gem install #{loc}"
20
+ run "rm #{loc}"
20
21
  run "mouth-endoscope -K"
21
22
  run "mouth --pidfile #{home}/mouth.pid -K"
22
23
  run "sleep 5"
data/TODO CHANGED
@@ -1,14 +1,17 @@
1
+ Now
2
+ - Build a caching system so that ticks don't pull in old data
3
+
1
4
  Next
2
5
  - Cookie-ize the timespan settings
3
6
  - Re implement graph autoplacement
4
7
  - Better backend impl of source list
5
- - Figure out how dashboards can scroll
6
8
  - Show period averages / rates
7
9
  - Full keyboard navigation
8
10
  - Build in some mechanisms to diagnose mongo connection issues
9
11
  - Auto refreshing source list (every minute?)
10
12
  - More Tests
11
13
  - Figure out time zones
14
+ - replicaset connection for endoscope
12
15
 
13
16
  Someday
14
17
  - Picker:
@@ -29,4 +32,4 @@ Bugs:
29
32
  - tooltip spawns multiple copies on large datasets
30
33
 
31
34
  Refactorings:
32
- - reconcile naming of 'sources' sometimes being array of strings and sometimes array of objects
35
+ - reconcile naming of 'sources' sometimes being array of strings and sometimes array of objects
data/bin/mouth CHANGED
@@ -16,6 +16,7 @@ options = {
16
16
  parser = OptionParser.new do |op|
17
17
  op.banner = "Usage: mouth [options]"
18
18
 
19
+ op.separator "Mouth version: #{Mouth::VERSION}"
19
20
  op.separator ""
20
21
  op.separator "Options:"
21
22
 
@@ -12,7 +12,11 @@ rescue LoadError
12
12
  end
13
13
 
14
14
  Vegas::Runner.new(Mouth::Endoscope, 'mouth-endoscope') do |runner, opts, app|
15
- opts.on("--mongohost HOSTPORT", "STORE SUCKINGS IN THIS MONGO") do |mongo_host|
15
+ opts.on("--mongohost HOST", "STORE SUCKINGS IN THIS MONGO HOST") do |mongo_host|
16
16
  Mouth.mongo_host = mongo_host
17
17
  end
18
+
19
+ opts.on("--mongoport PORT", "STORE SUCKINGS IN THIS MONGO PORT") do |mongo_port|
20
+ Mouth.mongo_port = mongo_port
21
+ end
18
22
  end
@@ -5,12 +5,13 @@ module Mouth
5
5
  class << self
6
6
  attr_accessor :logger
7
7
  attr_accessor :mongo_host
8
+ attr_accessor :mongo_port
8
9
 
9
10
  # Returns a mongo connection (NOT an em-mongo connection)
10
11
  def mongo
11
12
  @mongo ||= begin
12
13
  require 'mongo' # require mongo here, as opposed to the top, because we don't want mongo included in the reactor (use em-mongo for that)
13
- Mongo::Connection.new(self.mongo_host || "localhost").db("mouth")
14
+ Mongo::Connection.new(self.mongo_host || "localhost", self.mongo_port || 27017, :pool_size => 5, :pool_timeout => 20).db("mouth")
14
15
  end
15
16
  end
16
17
 
@@ -336,6 +336,7 @@ var DashboardPane = Backbone.View.extend({
336
336
  this.dashboardList.bind('current_change', this.onCurrentChange);
337
337
 
338
338
  this.model = null;
339
+ this.graphViews = [];
339
340
 
340
341
  this.elGrid= this.$('#grid');
341
342
  this.elAddGraph = this.$('.add-graph');
@@ -350,22 +351,28 @@ var DashboardPane = Backbone.View.extend({
350
351
  onCurrentChange: function(model) {
351
352
  var self = this;
352
353
 
354
+ _.each(self.graphViews, function(gv) {
355
+ gv.destroy();
356
+ });
357
+ self.graphViews = [];
358
+
353
359
  // Clean up
354
360
  if (self.model) {
355
361
  self.model.graphs.unbind('add', self.onAddGraph);
356
- self.elGrid.empty();
362
+ //self.elGrid.empty();
357
363
  }
358
364
 
359
365
  self.model = model;
360
366
  model.graphs.each(function(m) {
361
367
  self.onAddGraph(m);
362
- })
368
+ });
363
369
  self.render();
364
370
  model.graphs.bind('add', self.onAddGraph);
365
371
  },
366
372
 
367
373
  onAddGraph: function(m) {
368
374
  var graphView = new GraphView({model: m});
375
+ this.graphViews.push(graphView);
369
376
  this.elGrid.append(graphView.render().el);
370
377
  },
371
378
 
@@ -406,7 +413,7 @@ var GraphView = Backbone.View.extend({
406
413
  },
407
414
 
408
415
  initialize: function(opts) {
409
- _.bindAll(this, 'render', 'onDragStop', 'onClickEdit', 'onClickPick', 'onCreateModel', 'onClickDelete', 'onRemoveModel', 'onPick', 'onCancelPick', 'onDateRangeChanged', 'onTick');
416
+ _.bindAll(this, 'render', 'onDragStop', 'onClickEdit', 'onClickPick', 'onCreateModel', 'onClickDelete', 'onRemoveModel', 'onPick', 'onCancelPick', 'onDateRangeChanged', 'onTick', 'destroy');
410
417
 
411
418
  this.mode = 'front';
412
419
  this.model = opts.model;
@@ -418,6 +425,13 @@ var GraphView = Backbone.View.extend({
418
425
  $(document.body).bind('date_range_changed', this.onDateRangeChanged);
419
426
  },
420
427
 
428
+ destroy: function() {
429
+ this.model.unbind('change:id', this.onCreateModel);
430
+ this.model.unbind('remove', this.onRemoveModel);
431
+ this.model.unbind('tick', this.onTick);
432
+ $(this.el).remove();
433
+ },
434
+
421
435
  render: function() {
422
436
  var el = $(this.el)
423
437
  , m = this.model
@@ -79,7 +79,21 @@ module Mouth
79
79
  ###
80
80
  map_function = <<-JS
81
81
  function() {
82
- emit(Math.floor((this.t - #{start_timestamp}) / #{minutes}), this);
82
+ var doc = {t: this.t, m: {}, c: {}}
83
+ , thisMetrics = this.#{self.kind_letter.to_s}
84
+ , docMetrics = doc.#{self.kind_letter.to_s}
85
+ , fields = #{self.metrics.to_s}
86
+ , i, k, val
87
+ ;
88
+
89
+ for (i = 0; i < fields.length; i += 1) {
90
+ val = thisMetrics[fields[i]];
91
+ if (typeof val != "undefined") {
92
+ docMetrics[fields[i]] = val;
93
+ }
94
+ }
95
+
96
+ emit(Math.floor((this.t - #{start_timestamp}) / #{minutes}), doc);
83
97
  }
84
98
  JS
85
99
 
@@ -75,9 +75,11 @@ module Mouth
75
75
  # timer: glork:320|ms
76
76
  # (future) gauge: gaugor:333|g
77
77
  def store!(data)
78
- key_value, command_sampling = data.split("|", 2)
78
+ key_value, command_sampling = data.to_s.split("|", 2)
79
79
  key, value = key_value.to_s.split(":")
80
- command, sampling = command_sampling.split("|")
80
+ command, sampling = command_sampling.to_s.split("|")
81
+
82
+ return unless key && value && command && key.length > 0 && value.length > 0 && command.length > 0
81
83
 
82
84
  key = Mouth.parse_key(key).join(".")
83
85
  value = value.to_f
@@ -1,3 +1,3 @@
1
1
  module Mouth
2
- VERSION = "0.8.0"
2
+ VERSION = "0.8.1"
3
3
  end
@@ -39,6 +39,19 @@ class SuckerTest < Test::Unit::TestCase
39
39
  assert_equal ({"default.happening" => 3}), r.counters.values.first
40
40
  end
41
41
 
42
+ def test_storing_invalid
43
+ r = Mouth::Sucker.new
44
+
45
+ r.store!("stuff")
46
+ r.store!("stuff:3")
47
+ r.store!("stuff|c")
48
+ r.store!("")
49
+ r.store!("3|c")
50
+ r.store!("stuff:3|p")
51
+
52
+ assert_equal nil, r.counters.values.first
53
+ end
54
+
42
55
  def test_storing_timer
43
56
  r = Mouth::Sucker.new
44
57
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mouth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-30 00:00:00.000000000Z
12
+ date: 2012-05-02 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: em-mongo
16
- requirement: &70094097164760 !ruby/object:Gem::Requirement
16
+ requirement: &70245756341200 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.4.2
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70094097164760
24
+ version_requirements: *70245756341200
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: mongo
27
- requirement: &70094097164260 !ruby/object:Gem::Requirement
27
+ requirement: &70245756340700 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '1.6'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70094097164260
35
+ version_requirements: *70245756340700
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: bson_ext
38
- requirement: &70094097163800 !ruby/object:Gem::Requirement
38
+ requirement: &70245756340240 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '1.6'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70094097163800
46
+ version_requirements: *70245756340240
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: eventmachine
49
- requirement: &70094097163340 !ruby/object:Gem::Requirement
49
+ requirement: &70245756339780 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 0.12.10
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70094097163340
57
+ version_requirements: *70245756339780
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: vegas
60
- requirement: &70094097162880 !ruby/object:Gem::Requirement
60
+ requirement: &70245756339320 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 0.1.8
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70094097162880
68
+ version_requirements: *70245756339320
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: sinatra
71
- requirement: &70094097162420 !ruby/object:Gem::Requirement
71
+ requirement: &70245756338860 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 1.3.1
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *70094097162420
79
+ version_requirements: *70245756338860
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: yajl-ruby
82
- requirement: &70094097161960 !ruby/object:Gem::Requirement
82
+ requirement: &70245756338400 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: 1.1.0
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *70094097161960
90
+ version_requirements: *70245756338400
91
91
  description: Ruby Daemon collects statistics via UDP packets, stores them in Mongo,
92
92
  and then views them via a user friendly Sintra app.
93
93
  email: jnovak@gmail.com