fozzie 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.gitignore +5 -5
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -5
- data/Gemfile +3 -3
- data/README.md +288 -276
- data/Rakefile +6 -6
- data/fozzie.gemspec +29 -29
- data/fozzie.yml.example +14 -14
- data/lib/core_ext/hash/symbolize_keys.rb +21 -21
- data/lib/core_ext/module/alias_method_chain.rb +19 -19
- data/lib/core_ext/module/monitor.rb +12 -12
- data/lib/core_ext/string/snakecase.rb +9 -9
- data/lib/fozzie.rb +67 -67
- data/lib/fozzie/adapter/statsd.rb +95 -95
- data/lib/fozzie/bulk_dsl.rb +27 -27
- data/lib/fozzie/configuration.rb +1 -0
- data/lib/fozzie/dsl.rb +18 -18
- data/lib/fozzie/exception.rb +4 -4
- data/lib/fozzie/interface.rb +139 -139
- data/lib/fozzie/rack/middleware.rb +43 -43
- data/lib/fozzie/sniff.rb +49 -49
- data/lib/fozzie/version.rb +3 -3
- data/resources/mill.js.example +26 -26
- data/spec/config/fozzie.yml +5 -5
- data/spec/lib/core_ext/module/monitor_spec.rb +8 -8
- data/spec/lib/fozzie/adapter/statsd_spec.rb +82 -82
- data/spec/lib/fozzie/bulk_dsl_spec.rb +46 -46
- data/spec/lib/fozzie/configuration_spec.rb +125 -125
- data/spec/lib/fozzie/dsl_spec.rb +15 -15
- data/spec/lib/fozzie/rack/middleware_spec.rb +69 -69
- data/spec/lib/fozzie/rack/sinatra_spec.rb +30 -30
- data/spec/lib/fozzie/sniff_spec.rb +131 -131
- data/spec/lib/fozzie/version_spec.rb +9 -9
- data/spec/lib/fozzie_spec.rb +39 -39
- data/spec/shared_examples/fozzie_adapter.rb +7 -7
- data/spec/shared_examples/interface.rb +159 -159
- data/spec/spec_helper.rb +28 -28
- metadata +24 -36
- data/.rvmrc +0 -1
data/lib/fozzie/sniff.rb
CHANGED
@@ -1,49 +1,49 @@
|
|
1
|
-
require 'core_ext/module/monitor'
|
2
|
-
|
3
|
-
module Fozzie
|
4
|
-
module Sniff
|
5
|
-
|
6
|
-
def _monitor(bucket_name = nil)
|
7
|
-
@_monitor_flag = true
|
8
|
-
@_bucket_name = bucket_name
|
9
|
-
end
|
10
|
-
|
11
|
-
def _monitor_meth(target, &blk)
|
12
|
-
return if @_monitor_flag.nil? || !@_monitor_flag
|
13
|
-
|
14
|
-
@_monitor_flag = false
|
15
|
-
bin = @_bucket_name || [self.name.snakecase, target.to_s.snakecase]
|
16
|
-
feature = :monitor
|
17
|
-
aliased_target = target.to_s.sub(/([?!=])$/, '')
|
18
|
-
punctuation = $1
|
19
|
-
|
20
|
-
with = "#{aliased_target}_with_#{feature}#{punctuation}"
|
21
|
-
without = "#{aliased_target}_without_#{feature}#{punctuation}"
|
22
|
-
|
23
|
-
blk.call(with, without, feature, bin)
|
24
|
-
end
|
25
|
-
|
26
|
-
def method_added(target)
|
27
|
-
_monitor_meth(target) do |with, without, feature, bin|
|
28
|
-
define_method(with) do |*args, &blk|
|
29
|
-
S.time_for(bin) do
|
30
|
-
args.empty? ? self.send(without, &blk) : self.send(without, *args, &blk)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
self.alias_method_chain(target, feature)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def singleton_method_added(target)
|
38
|
-
_monitor_meth(target) do |with, without, feature, bin|
|
39
|
-
define_singleton_method(with) do |*args, &blk|
|
40
|
-
S.time_for(bin) do
|
41
|
-
args.empty? ? send(without, &blk) : send(without, *args, &blk)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
self.singleton_class.class_eval { alias_method_chain target, feature }
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
1
|
+
require 'core_ext/module/monitor'
|
2
|
+
|
3
|
+
module Fozzie
|
4
|
+
module Sniff
|
5
|
+
|
6
|
+
def _monitor(bucket_name = nil)
|
7
|
+
@_monitor_flag = true
|
8
|
+
@_bucket_name = bucket_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def _monitor_meth(target, &blk)
|
12
|
+
return if @_monitor_flag.nil? || !@_monitor_flag
|
13
|
+
|
14
|
+
@_monitor_flag = false
|
15
|
+
bin = @_bucket_name || [self.name.snakecase, target.to_s.snakecase]
|
16
|
+
feature = :monitor
|
17
|
+
aliased_target = target.to_s.sub(/([?!=])$/, '')
|
18
|
+
punctuation = $1
|
19
|
+
|
20
|
+
with = "#{aliased_target}_with_#{feature}#{punctuation}"
|
21
|
+
without = "#{aliased_target}_without_#{feature}#{punctuation}"
|
22
|
+
|
23
|
+
blk.call(with, without, feature, bin)
|
24
|
+
end
|
25
|
+
|
26
|
+
def method_added(target)
|
27
|
+
_monitor_meth(target) do |with, without, feature, bin|
|
28
|
+
define_method(with) do |*args, &blk|
|
29
|
+
S.time_for(bin) do
|
30
|
+
args.empty? ? self.send(without, &blk) : self.send(without, *args, &blk)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
self.alias_method_chain(target, feature)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def singleton_method_added(target)
|
38
|
+
_monitor_meth(target) do |with, without, feature, bin|
|
39
|
+
define_singleton_method(with) do |*args, &blk|
|
40
|
+
S.time_for(bin) do
|
41
|
+
args.empty? ? send(without, &blk) : send(without, *args, &blk)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
self.singleton_class.class_eval { alias_method_chain target, feature }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/lib/fozzie/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module Fozzie
|
2
|
-
VERSION = "1.0.
|
3
|
-
end
|
1
|
+
module Fozzie
|
2
|
+
VERSION = "1.0.3"
|
3
|
+
end
|
data/resources/mill.js.example
CHANGED
@@ -1,27 +1,27 @@
|
|
1
|
-
// Mill-Snippet_0.0.1
|
2
|
-
(function($){
|
3
|
-
var __mill__ = function() {
|
4
|
-
var c=[window.navigator,window.performance.timing], d=[], t, a, script, s;
|
5
|
-
for(n in c){
|
6
|
-
if(c[n]){
|
7
|
-
t=c[n];
|
8
|
-
for(a in c[n]){
|
9
|
-
if(a && (typeof(t[a])!=='function'&& typeof(t[a])!=='object')){
|
10
|
-
d.push(a);
|
11
|
-
d.push(escape(t[a]));
|
12
|
-
}
|
13
|
-
}
|
14
|
-
}
|
15
|
-
}
|
16
|
-
d.push('href');
|
17
|
-
d.push(window.location.href);
|
18
|
-
script = document.createElement('script');
|
19
|
-
script.src = "/mill?d=" + d.join(';');
|
20
|
-
script.async = true;
|
21
|
-
s = document.getElementsByTagName('script')[0];
|
22
|
-
s.parentNode.insertBefore(script, s);
|
23
|
-
};
|
24
|
-
if(window.addEventListener){
|
25
|
-
window.addEventListener('load', function(){__mill__();}, false);
|
26
|
-
}
|
1
|
+
// Mill-Snippet_0.0.1
|
2
|
+
(function($){
|
3
|
+
var __mill__ = function() {
|
4
|
+
var c=[window.navigator,window.performance.timing], d=[], t, a, script, s;
|
5
|
+
for(n in c){
|
6
|
+
if(c[n]){
|
7
|
+
t=c[n];
|
8
|
+
for(a in c[n]){
|
9
|
+
if(a && (typeof(t[a])!=='function'&& typeof(t[a])!=='object')){
|
10
|
+
d.push(a);
|
11
|
+
d.push(escape(t[a]));
|
12
|
+
}
|
13
|
+
}
|
14
|
+
}
|
15
|
+
}
|
16
|
+
d.push('href');
|
17
|
+
d.push(window.location.href);
|
18
|
+
script = document.createElement('script');
|
19
|
+
script.src = "/mill?d=" + d.join(';');
|
20
|
+
script.async = true;
|
21
|
+
s = document.getElementsByTagName('script')[0];
|
22
|
+
s.parentNode.insertBefore(script, s);
|
23
|
+
};
|
24
|
+
if(window.addEventListener){
|
25
|
+
window.addEventListener('load', function(){__mill__();}, false);
|
26
|
+
}
|
27
27
|
}).call($);
|
data/spec/config/fozzie.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
# Statistics configuration for Monitoring and Measuring
|
2
|
-
test:
|
3
|
-
appname: 'fozzie'
|
4
|
-
host: '1.1.1.1'
|
5
|
-
port: 9876
|
1
|
+
# Statistics configuration for Monitoring and Measuring
|
2
|
+
test:
|
3
|
+
appname: 'fozzie'
|
4
|
+
host: '1.1.1.1'
|
5
|
+
port: 9876
|
6
6
|
enable_rails_middleware: false
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Module do
|
4
|
-
|
5
|
-
it "includes _monitor method when required" do
|
6
|
-
Module.should respond_to(:_monitor)
|
7
|
-
end
|
8
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Module do
|
4
|
+
|
5
|
+
it "includes _monitor method when required" do
|
6
|
+
Module.should respond_to(:_monitor)
|
7
|
+
end
|
8
|
+
|
9
9
|
end
|
@@ -1,82 +1,82 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'fozzie/adapter/statsd'
|
3
|
-
|
4
|
-
module Fozzie::Adapter
|
5
|
-
describe Statsd do
|
6
|
-
it_behaves_like "fozzie adapter"
|
7
|
-
|
8
|
-
# Switch to Statsd adapter for the duration of this test
|
9
|
-
before(:all) do
|
10
|
-
Fozzie.c.adapter = :Statsd
|
11
|
-
end
|
12
|
-
|
13
|
-
after(:all) do
|
14
|
-
Fozzie.c.adapter = :TestAdapter
|
15
|
-
end
|
16
|
-
|
17
|
-
it "downcases any stat value" do
|
18
|
-
subject.should_receive(:send_to_socket).with {|bin| bin.match /\.foo/ }
|
19
|
-
|
20
|
-
subject.register(:bin => "FOO", :value => 1, :type => :gauge, :sample_rate => 1)
|
21
|
-
end
|
22
|
-
|
23
|
-
describe "#format_bucket" do
|
24
|
-
it "accepts arrays" do
|
25
|
-
subject.format_bucket([:foo, '2']).should match /foo.2$/
|
26
|
-
subject.format_bucket([:foo, '2']).should match /foo.2$/
|
27
|
-
subject.format_bucket(%w{foo bar}).should match /foo.bar$/
|
28
|
-
end
|
29
|
-
|
30
|
-
it "converts any values to strings for stat value, ignoring nil" do
|
31
|
-
subject.format_bucket([:foo, 1, nil, "@", "BAR"]).should =~ /foo.1._.bar/
|
32
|
-
end
|
33
|
-
|
34
|
-
it "replaces invalid chracters" do
|
35
|
-
subject.format_bucket([:foo, ':']).should match /foo.#{subject.class::RESERVED_CHARS_REPLACEMENT}$/
|
36
|
-
subject.format_bucket([:foo, '@']).should match /foo.#{subject.class::RESERVED_CHARS_REPLACEMENT}$/
|
37
|
-
subject.format_bucket('foo.bar.|').should match /foo.bar.#{subject.class::RESERVED_CHARS_REPLACEMENT}$/
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
describe "#format_value" do
|
42
|
-
it "defaults type to gauge when type is not mapped" do
|
43
|
-
subject.format_value(1, :foo, 1).should eq '1|g'
|
44
|
-
end
|
45
|
-
|
46
|
-
it "converts basic values to string" do
|
47
|
-
subject.format_value(1, :count, 1).should eq '1|c'
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
it "ensures block is called on socket error" do
|
52
|
-
subject.socket.stub(:send) { raise SocketError }
|
53
|
-
|
54
|
-
proc { subject.register(:bin => 'data.bin', :value => 1, :type => :gauge, :sample_rate => 1) { sleep 0.01 } }.should_not raise_error
|
55
|
-
proc { subject.register(:bin => 'data.bin', :value => 1, :type => :gauge, :sample_rate => 1) { sleep 0.01 } }.should_not raise_error
|
56
|
-
end
|
57
|
-
|
58
|
-
it "raises Timeout on slow lookup" do
|
59
|
-
Fozzie.c.timeout = 0.01
|
60
|
-
subject.socket.stub(:send).with(any_args) { sleep 0.4 }
|
61
|
-
|
62
|
-
subject.register(:bin => 'data.bin', :value => 1, :type => :gauge, :sample_rate => 1).should eq false
|
63
|
-
end
|
64
|
-
|
65
|
-
describe "multiple stats in a single call" do
|
66
|
-
|
67
|
-
it "collects stats together with delimeter" do
|
68
|
-
Fozzie.c.disable_prefix
|
69
|
-
|
70
|
-
stats = [
|
71
|
-
{ :bin => 'foo', :value => 1, :type => :count, :sample_rate => 1 },
|
72
|
-
{ :bin => 'bar', :value => 1, :type => :gauge, :sample_rate => 1 },
|
73
|
-
{ :bin => %w{foo bar}, :value => 100, :type => :timing, :sample_rate => 1 }
|
74
|
-
]
|
75
|
-
|
76
|
-
subject.should_receive(:send_to_socket).with "foo:1|c\nbar:1|g\nfoo.bar:100|ms"
|
77
|
-
|
78
|
-
subject.register(stats)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fozzie/adapter/statsd'
|
3
|
+
|
4
|
+
module Fozzie::Adapter
|
5
|
+
describe Statsd do
|
6
|
+
it_behaves_like "fozzie adapter"
|
7
|
+
|
8
|
+
# Switch to Statsd adapter for the duration of this test
|
9
|
+
before(:all) do
|
10
|
+
Fozzie.c.adapter = :Statsd
|
11
|
+
end
|
12
|
+
|
13
|
+
after(:all) do
|
14
|
+
Fozzie.c.adapter = :TestAdapter
|
15
|
+
end
|
16
|
+
|
17
|
+
it "downcases any stat value" do
|
18
|
+
subject.should_receive(:send_to_socket).with {|bin| bin.match /\.foo/ }
|
19
|
+
|
20
|
+
subject.register(:bin => "FOO", :value => 1, :type => :gauge, :sample_rate => 1)
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#format_bucket" do
|
24
|
+
it "accepts arrays" do
|
25
|
+
subject.format_bucket([:foo, '2']).should match /foo.2$/
|
26
|
+
subject.format_bucket([:foo, '2']).should match /foo.2$/
|
27
|
+
subject.format_bucket(%w{foo bar}).should match /foo.bar$/
|
28
|
+
end
|
29
|
+
|
30
|
+
it "converts any values to strings for stat value, ignoring nil" do
|
31
|
+
subject.format_bucket([:foo, 1, nil, "@", "BAR"]).should =~ /foo.1._.bar/
|
32
|
+
end
|
33
|
+
|
34
|
+
it "replaces invalid chracters" do
|
35
|
+
subject.format_bucket([:foo, ':']).should match /foo.#{subject.class::RESERVED_CHARS_REPLACEMENT}$/
|
36
|
+
subject.format_bucket([:foo, '@']).should match /foo.#{subject.class::RESERVED_CHARS_REPLACEMENT}$/
|
37
|
+
subject.format_bucket('foo.bar.|').should match /foo.bar.#{subject.class::RESERVED_CHARS_REPLACEMENT}$/
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#format_value" do
|
42
|
+
it "defaults type to gauge when type is not mapped" do
|
43
|
+
subject.format_value(1, :foo, 1).should eq '1|g'
|
44
|
+
end
|
45
|
+
|
46
|
+
it "converts basic values to string" do
|
47
|
+
subject.format_value(1, :count, 1).should eq '1|c'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "ensures block is called on socket error" do
|
52
|
+
subject.socket.stub(:send) { raise SocketError }
|
53
|
+
|
54
|
+
proc { subject.register(:bin => 'data.bin', :value => 1, :type => :gauge, :sample_rate => 1) { sleep 0.01 } }.should_not raise_error
|
55
|
+
proc { subject.register(:bin => 'data.bin', :value => 1, :type => :gauge, :sample_rate => 1) { sleep 0.01 } }.should_not raise_error
|
56
|
+
end
|
57
|
+
|
58
|
+
it "raises Timeout on slow lookup" do
|
59
|
+
Fozzie.c.timeout = 0.01
|
60
|
+
subject.socket.stub(:send).with(any_args) { sleep 0.4 }
|
61
|
+
|
62
|
+
subject.register(:bin => 'data.bin', :value => 1, :type => :gauge, :sample_rate => 1).should eq false
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "multiple stats in a single call" do
|
66
|
+
|
67
|
+
it "collects stats together with delimeter" do
|
68
|
+
Fozzie.c.disable_prefix
|
69
|
+
|
70
|
+
stats = [
|
71
|
+
{ :bin => 'foo', :value => 1, :type => :count, :sample_rate => 1 },
|
72
|
+
{ :bin => 'bar', :value => 1, :type => :gauge, :sample_rate => 1 },
|
73
|
+
{ :bin => %w{foo bar}, :value => 100, :type => :timing, :sample_rate => 1 }
|
74
|
+
]
|
75
|
+
|
76
|
+
subject.should_receive(:send_to_socket).with "foo:1|c\nbar:1|g\nfoo.bar:100|ms"
|
77
|
+
|
78
|
+
subject.register(stats)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -1,47 +1,47 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Fozzie
|
4
|
-
describe BulkDsl do
|
5
|
-
|
6
|
-
it_behaves_like "interface"
|
7
|
-
|
8
|
-
describe "#initialize" do
|
9
|
-
|
10
|
-
it "accepts and performs block" do
|
11
|
-
BulkDsl.any_instance.should_receive(:foo)
|
12
|
-
|
13
|
-
BulkDsl.new { foo }
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
it "sends statistics in one call" do
|
19
|
-
Fozzie.c.adapter.should_receive(:register).once
|
20
|
-
|
21
|
-
BulkDsl.new do
|
22
|
-
increment :foo
|
23
|
-
decrement :bar
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
it "scopes given block when arity provided" do
|
28
|
-
Fozzie.c.adapter.should_receive(:register).once
|
29
|
-
|
30
|
-
class Foo
|
31
|
-
|
32
|
-
def send_stats
|
33
|
-
BulkDsl.new do |s|
|
34
|
-
s.increment random_value
|
35
|
-
s.decrement random_value
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def random_value; rand end
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
Foo.new.send_stats
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Fozzie
|
4
|
+
describe BulkDsl do
|
5
|
+
|
6
|
+
it_behaves_like "interface"
|
7
|
+
|
8
|
+
describe "#initialize" do
|
9
|
+
|
10
|
+
it "accepts and performs block" do
|
11
|
+
BulkDsl.any_instance.should_receive(:foo)
|
12
|
+
|
13
|
+
BulkDsl.new { foo }
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
it "sends statistics in one call" do
|
19
|
+
Fozzie.c.adapter.should_receive(:register).once
|
20
|
+
|
21
|
+
BulkDsl.new do
|
22
|
+
increment :foo
|
23
|
+
decrement :bar
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it "scopes given block when arity provided" do
|
28
|
+
Fozzie.c.adapter.should_receive(:register).once
|
29
|
+
|
30
|
+
class Foo
|
31
|
+
|
32
|
+
def send_stats
|
33
|
+
BulkDsl.new do |s|
|
34
|
+
s.increment random_value
|
35
|
+
s.decrement random_value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def random_value; rand end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
Foo.new.send_stats
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
47
|
end
|