mouth 0.8.1 → 0.8.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/.gitignore +1 -0
- data/MIT-LICENSE +1 -1
- data/README.md +40 -27
- data/Rakefile +2 -2
- data/TODO +4 -4
- data/bin/mouth +3 -3
- data/bin/mouth-console +1 -1
- data/bin/mouth-endoscope +3 -6
- data/lib/mouth.rb +37 -5
- data/lib/mouth/endoscope.rb +1 -1
- data/lib/mouth/endoscope/public/application.js +10 -4
- data/lib/mouth/endoscope/public/seven.js +1 -0
- data/lib/mouth/graph.rb +2 -2
- data/lib/mouth/instrument.rb +13 -9
- data/lib/mouth/record.rb +2 -1
- data/lib/mouth/recorder.rb +39 -0
- data/lib/mouth/runner.rb +2 -2
- data/lib/mouth/{sequence.rb → sequence_query.rb} +71 -16
- data/lib/mouth/source.rb +12 -3
- data/lib/mouth/sucker.rb +46 -19
- data/lib/mouth/version.rb +1 -1
- data/test/instrument_test.rb +79 -0
- data/test/recorder_test.rb +53 -0
- data/test/{sequence_test.rb → sequence_query_test.rb} +46 -8
- metadata +25 -21
- data/Capfile +0 -27
@@ -0,0 +1,53 @@
|
|
1
|
+
$LOAD_PATH.unshift 'test'
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
require 'mouth/recorder'
|
5
|
+
require 'mouth/sequence_query'
|
6
|
+
|
7
|
+
class RecorderTest < Test::Unit::TestCase
|
8
|
+
def setup
|
9
|
+
Mouth.collection_for("test").remove
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_increment
|
13
|
+
Mouth::Recorder.increment("test.recorders")
|
14
|
+
seq = Mouth::SequenceQuery.new("test.recorders").sequence
|
15
|
+
assert_equal 1, seq.inject(0) {|s,e| s + e}
|
16
|
+
assert_equal 1, seq.last
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_increment_delta
|
20
|
+
Mouth::Recorder.increment("test.recorders", 99)
|
21
|
+
seq = Mouth::SequenceQuery.new("test.recorders").sequence
|
22
|
+
assert_equal 99, seq.inject(0) {|s,e| s + e}
|
23
|
+
assert_equal 99, seq.last
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_increment_sample
|
27
|
+
found_noop = false
|
28
|
+
found_op = false
|
29
|
+
100.times do # In theory this could falsely fail 0.0026561% of the time
|
30
|
+
Mouth.collection_for("test").remove
|
31
|
+
Mouth::Recorder.increment("test.recorders", 1, 0.1)
|
32
|
+
seq = Mouth::SequenceQuery.new("test.recorders").sequence
|
33
|
+
sum = seq.inject(0) {|s,e| s + e}
|
34
|
+
if sum == 0
|
35
|
+
found_noop = true
|
36
|
+
elsif sum == 10
|
37
|
+
found_op = true
|
38
|
+
else
|
39
|
+
assert false, "Sum should either be 0 or 10"
|
40
|
+
end
|
41
|
+
break if found_noop && found_op
|
42
|
+
end
|
43
|
+
assert found_noop
|
44
|
+
assert found_op
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_gauge
|
48
|
+
Mouth::Recorder.gauge("test.recorders", 9)
|
49
|
+
seq = Mouth::SequenceQuery.new("test.recorders", :kind => :gauge).sequence
|
50
|
+
assert_equal 9, seq.inject(0) {|s,e| s + e}
|
51
|
+
assert_equal 9, seq.last
|
52
|
+
end
|
53
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
$LOAD_PATH.unshift 'test'
|
2
2
|
require 'test_helper'
|
3
3
|
|
4
|
-
require 'mouth/
|
4
|
+
require 'mouth/sequence_query'
|
5
5
|
|
6
6
|
class SequenceTest < Test::Unit::TestCase
|
7
7
|
def setup
|
@@ -16,12 +16,12 @@ class SequenceTest < Test::Unit::TestCase
|
|
16
16
|
timer = {"count" => 5, "min" => 1, "max" => 10, "mean" => 5, "sum" => 20, "median" => 4, "stddev" => 2.3}
|
17
17
|
(@start_timestamp..@end_timestamp).each do |t|
|
18
18
|
# Insert the document into mongo
|
19
|
-
Mouth.collection(Mouth.mongo_collection_name(@namespace)).update({"t" => t}, {"$set" => {"c.#{@metric}" => counter, "m.#{@metric}" => timer}}, :upsert => true)
|
19
|
+
Mouth.collection(Mouth.mongo_collection_name(@namespace)).update({"t" => t}, {"$set" => {"c.#{@metric}" => counter, "m.#{@metric}" => timer, "g.#{@metric}" => (t % 2 == 0 ? counter + 1 : nil)}}, :upsert => true)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def test_minute_counter_sequences
|
24
|
-
seq = Mouth::
|
24
|
+
seq = Mouth::SequenceQuery.new("#{@namespace}.#{@metric}", :start_time => @start_time, :end_time => @end_time)
|
25
25
|
|
26
26
|
sequences = seq.sequences
|
27
27
|
|
@@ -36,7 +36,7 @@ class SequenceTest < Test::Unit::TestCase
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def test_15_minute_counter_sequences
|
39
|
-
seq = Mouth::
|
39
|
+
seq = Mouth::SequenceQuery.new("#{@namespace}.#{@metric}", :granularity_in_minutes => 15, :start_time => @start_time, :end_time => @end_time)
|
40
40
|
|
41
41
|
sequences = seq.sequences
|
42
42
|
|
@@ -50,7 +50,7 @@ class SequenceTest < Test::Unit::TestCase
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def test_15_minute_timer_sequences_basic
|
53
|
-
seq = Mouth::
|
53
|
+
seq = Mouth::SequenceQuery.new("#{@namespace}.#{@metric}", :kind => :timer, :granularity_in_minutes => 15, :start_time => @start_time, :end_time => @end_time)
|
54
54
|
|
55
55
|
sequences = seq.sequences
|
56
56
|
assert_equal ["test"], sequences.keys
|
@@ -104,7 +104,7 @@ class SequenceTest < Test::Unit::TestCase
|
|
104
104
|
i += 1
|
105
105
|
end
|
106
106
|
|
107
|
-
seq = Mouth::
|
107
|
+
seq = Mouth::SequenceQuery.new("test.test", :kind => :timer, :granularity_in_minutes => 15, :start_time => @start_time, :end_time => @end_time)
|
108
108
|
values = seq.sequence
|
109
109
|
|
110
110
|
assert_equal 1, values.length
|
@@ -133,7 +133,7 @@ class SequenceTest < Test::Unit::TestCase
|
|
133
133
|
|
134
134
|
col = Mouth.collection(Mouth.mongo_collection_name("test"))
|
135
135
|
col.remove
|
136
|
-
seq = Mouth::
|
136
|
+
seq = Mouth::SequenceQuery.new("test.test", :kind => :timer, :granularity_in_minutes => 15, :start_time => @start_time, :end_time => @end_time)
|
137
137
|
values = seq.sequence
|
138
138
|
|
139
139
|
assert_equal [{"count"=>0,
|
@@ -154,10 +154,48 @@ class SequenceTest < Test::Unit::TestCase
|
|
154
154
|
|
155
155
|
col = Mouth.collection(Mouth.mongo_collection_name("test"))
|
156
156
|
col.remove
|
157
|
-
seq = Mouth::
|
157
|
+
seq = Mouth::SequenceQuery.new("test.test", :kind => :counter, :granularity_in_minutes => 15, :start_time => @start_time, :end_time => @end_time)
|
158
158
|
values = seq.sequence
|
159
159
|
|
160
160
|
assert_equal [0], values
|
161
161
|
end
|
162
162
|
|
163
|
+
def test_minute_gauge_sequences
|
164
|
+
seq = Mouth::SequenceQuery.new("#{@namespace}.#{@metric}", :kind => :gauge, :start_time => @start_time, :end_time => @end_time)
|
165
|
+
|
166
|
+
sequences = seq.sequences
|
167
|
+
|
168
|
+
assert_equal ["test"], sequences.keys
|
169
|
+
assert_equal 1, sequences.values.length
|
170
|
+
|
171
|
+
values = sequences.values.first
|
172
|
+
|
173
|
+
assert_equal 121, values.length
|
174
|
+
|
175
|
+
assert values.all? {|v| v == 2}
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_minute_time_sequence
|
179
|
+
q = Mouth::SequenceQuery.new("#{@namespace}.#{@metric}", :start_time => @start_time, :end_time => @end_time)
|
180
|
+
ts = q.time_sequence
|
181
|
+
assert_equal @start_time, ts.first
|
182
|
+
assert_equal @end_time, ts.last
|
183
|
+
assert_equal 121, ts.length
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_minute_epoch_sequence
|
187
|
+
q = Mouth::SequenceQuery.new("#{@namespace}.#{@metric}", :start_time => @start_time, :end_time => @end_time)
|
188
|
+
ts = q.epoch_sequence
|
189
|
+
assert_equal @start_time.to_i, ts.first
|
190
|
+
assert_equal @end_time.to_i, ts.last
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_15_minute_time_sequence
|
194
|
+
q = Mouth::SequenceQuery.new("#{@namespace}.#{@metric}", :start_time => @start_time, :end_time => @end_time, :granularity_in_minutes => 15)
|
195
|
+
ts = q.time_sequence
|
196
|
+
assert_equal Time.new(2012, 4, 1, 9, 30, 0, "-07:00"), ts.first
|
197
|
+
assert_equal Time.new(2012, 4, 1, 11, 30, 0, "-07:00"), ts.last
|
198
|
+
assert_equal q.sequence.length, ts.length
|
199
|
+
end
|
200
|
+
|
163
201
|
end
|
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.
|
4
|
+
version: 0.8.2
|
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-05-
|
12
|
+
date: 2012-05-08 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: em-mongo
|
16
|
-
requirement: &
|
16
|
+
requirement: &2168969780 !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: *
|
24
|
+
version_requirements: *2168969780
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: mongo
|
27
|
-
requirement: &
|
27
|
+
requirement: &2168969280 !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: *
|
35
|
+
version_requirements: *2168969280
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: bson_ext
|
38
|
-
requirement: &
|
38
|
+
requirement: &2168968820 !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: *
|
46
|
+
version_requirements: *2168968820
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: eventmachine
|
49
|
-
requirement: &
|
49
|
+
requirement: &2168968360 !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: *
|
57
|
+
version_requirements: *2168968360
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: vegas
|
60
|
-
requirement: &
|
60
|
+
requirement: &2168967900 !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: *
|
68
|
+
version_requirements: *2168967900
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: sinatra
|
71
|
-
requirement: &
|
71
|
+
requirement: &2168967440 !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: *
|
79
|
+
version_requirements: *2168967440
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: yajl-ruby
|
82
|
-
requirement: &
|
82
|
+
requirement: &2168966960 !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: *
|
90
|
+
version_requirements: *2168966960
|
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
|
@@ -98,7 +98,6 @@ extensions: []
|
|
98
98
|
extra_rdoc_files: []
|
99
99
|
files:
|
100
100
|
- .gitignore
|
101
|
-
- Capfile
|
102
101
|
- Gemfile
|
103
102
|
- MIT-LICENSE
|
104
103
|
- README.md
|
@@ -128,13 +127,16 @@ files:
|
|
128
127
|
- lib/mouth/graph.rb
|
129
128
|
- lib/mouth/instrument.rb
|
130
129
|
- lib/mouth/record.rb
|
130
|
+
- lib/mouth/recorder.rb
|
131
131
|
- lib/mouth/runner.rb
|
132
|
-
- lib/mouth/
|
132
|
+
- lib/mouth/sequence_query.rb
|
133
133
|
- lib/mouth/source.rb
|
134
134
|
- lib/mouth/sucker.rb
|
135
135
|
- lib/mouth/version.rb
|
136
136
|
- mouth.gemspec
|
137
|
-
- test/
|
137
|
+
- test/instrument_test.rb
|
138
|
+
- test/recorder_test.rb
|
139
|
+
- test/sequence_query_test.rb
|
138
140
|
- test/sucker_test.rb
|
139
141
|
- test/test_helper.rb
|
140
142
|
homepage: http://github.com/cypriss/mouth
|
@@ -157,11 +159,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
159
|
version: 1.3.4
|
158
160
|
requirements: []
|
159
161
|
rubyforge_project:
|
160
|
-
rubygems_version: 1.8.
|
162
|
+
rubygems_version: 1.8.10
|
161
163
|
signing_key:
|
162
164
|
specification_version: 3
|
163
165
|
summary: Collect and view stats in real time.
|
164
166
|
test_files:
|
165
|
-
- test/
|
167
|
+
- test/instrument_test.rb
|
168
|
+
- test/recorder_test.rb
|
169
|
+
- test/sequence_query_test.rb
|
166
170
|
- test/sucker_test.rb
|
167
171
|
- test/test_helper.rb
|
data/Capfile
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
load 'deploy'
|
2
|
-
|
3
|
-
# Simply way to deploy the app if you're developing it
|
4
|
-
# I will probably remove this file later.
|
5
|
-
set :application, "mouth"
|
6
|
-
default_run_options[:pty] = true
|
7
|
-
|
8
|
-
set :scm, :none
|
9
|
-
role :app, "sugar"
|
10
|
-
|
11
|
-
task :omg do
|
12
|
-
res = `gem build mouth.gemspec`
|
13
|
-
if res =~ /Success/
|
14
|
-
home = "#{capture('pwd').strip}/mouth"
|
15
|
-
file = res.match(/File: (.+)$/)[1]
|
16
|
-
run "mkdir -p ~/mouth"
|
17
|
-
loc = "#{home}/#{file}"
|
18
|
-
upload file, loc
|
19
|
-
sudo "gem install #{loc}"
|
20
|
-
run "rm #{loc}"
|
21
|
-
run "mouth-endoscope -K"
|
22
|
-
run "mouth --pidfile #{home}/mouth.pid -K"
|
23
|
-
run "sleep 5"
|
24
|
-
run "mouth-endoscope --mongohost 10.36.103.70"
|
25
|
-
run "mouth --pidfile #{home}/mouth.pid --logfile #{home}/mouth.log -H 10.18.23.135 -P 8889 --mongohost 10.36.103.70"
|
26
|
-
end
|
27
|
-
end
|