fozzie 0.0.13 → 0.0.14
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/Guardfile +9 -0
- data/fozzie.gemspec +2 -1
- data/lib/fozzie/classes.rb +87 -17
- data/lib/fozzie/configuration.rb +12 -5
- data/lib/fozzie/rails/middleware.rb +2 -2
- data/lib/fozzie/version.rb +1 -1
- data/spec/lib/fozzie/configuration_spec.rb +10 -5
- metadata +43 -31
data/Guardfile
ADDED
data/fozzie.gemspec
CHANGED
@@ -17,7 +17,6 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
|
20
|
-
s.add_dependency 'statsd-ruby'
|
21
20
|
s.add_development_dependency 'rake'
|
22
21
|
s.add_development_dependency 'rspec'
|
23
22
|
s.add_development_dependency 'mocha'
|
@@ -26,4 +25,6 @@ Gem::Specification.new do |s|
|
|
26
25
|
s.add_development_dependency 'simplecov'
|
27
26
|
s.add_development_dependency 'sinatra'
|
28
27
|
s.add_development_dependency 'actionpack'
|
28
|
+
s.add_development_dependency 'guard'
|
29
|
+
s.add_development_dependency 'guard-rspec'
|
29
30
|
end
|
data/lib/fozzie/classes.rb
CHANGED
@@ -1,39 +1,89 @@
|
|
1
|
-
require 'statsd'
|
2
|
-
|
3
1
|
module Fozzie
|
4
2
|
module Classes
|
5
3
|
|
6
|
-
class AbstractFozzie
|
4
|
+
class AbstractFozzie
|
5
|
+
|
6
|
+
RESERVED_CHARS_REGEX = /[\:\|\@]/
|
7
7
|
|
8
8
|
attr_reader :prefix, :configuration
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
# Sends an increment (count = 1) for the given stat to the statsd server.
|
11
|
+
#
|
12
|
+
# @param stat (see #count)
|
13
|
+
# @param sample_rate (see #count)
|
14
|
+
# @see #count
|
15
|
+
def increment(stat, sample_rate=1)
|
16
|
+
count(stat, 1, sample_rate)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Sends a decrement (count = -1) for the given stat to the statsd server.
|
20
|
+
#
|
21
|
+
# @param stat (see #count)
|
22
|
+
# @param sample_rate (see #count)
|
23
|
+
# @see #count
|
24
|
+
def decrement(stat, sample_rate=1)
|
25
|
+
count(stat, -1, sample_rate)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Sends an arbitrary count for the given stat to the statsd server.
|
29
|
+
#
|
30
|
+
# @param [String] stat stat name
|
31
|
+
# @param [Integer] count count
|
32
|
+
# @param [Integer] sample_rate sample rate, 1 for always
|
33
|
+
def count(stat, count, sample_rate=1)
|
34
|
+
send(stat, count, 'c', sample_rate)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Sends a timing (in ms) for the given stat to the statsd server. The
|
38
|
+
# sample_rate determines what percentage of the time this report is sent. The
|
39
|
+
# statsd server then uses the sample_rate to correctly track the average
|
40
|
+
# timing for the stat.
|
41
|
+
#
|
42
|
+
# @param stat stat name
|
43
|
+
# @param [Integer] ms timing in milliseconds
|
44
|
+
# @param [Integer] sample_rate sample rate, 1 for always
|
45
|
+
def timing(stat, ms, sample_rate=1)
|
46
|
+
send(stat, ms, 'ms', sample_rate)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Reports execution time of the provided block using {#timing}.
|
50
|
+
#
|
51
|
+
# @param stat (see #timing)
|
52
|
+
# @param sample_rate (see #timing)
|
53
|
+
# @yield The operation to be timed
|
54
|
+
# @see #timing
|
55
|
+
# @example Report the time (in ms) taken to activate an account
|
56
|
+
# $statsd.time('account.activate') { @account.activate! }
|
57
|
+
def time(stat, sample_rate=1)
|
58
|
+
stat = stat.flatten.join('.') if stat.kind_of?(Array)
|
59
|
+
start = Time.now
|
60
|
+
result = yield
|
61
|
+
timing(stat, ((Time.now - start) * 1000).round, sample_rate)
|
62
|
+
result
|
63
|
+
end
|
13
64
|
|
14
|
-
|
65
|
+
def time_to_do(stat, sample_rate=1, &block)
|
66
|
+
time_for(stat, sample_rate, &block)
|
15
67
|
end
|
16
68
|
|
17
|
-
def time_to_do(stat, sample_rate=1, &block); time_for(stat, sample_rate, &block); end
|
18
69
|
def time_for(stat, sample_rate=1, &block)
|
19
|
-
stat = stat.flatten.join('.') if stat.kind_of?(Array)
|
20
70
|
time(stat, sample_rate, &block)
|
21
71
|
end
|
22
72
|
|
23
|
-
def committed; commit; end
|
24
73
|
def commit
|
25
74
|
event :commit
|
26
75
|
end
|
76
|
+
def committed; commit; end
|
27
77
|
|
28
|
-
def build; built; end
|
29
78
|
def built
|
30
79
|
event :build
|
31
80
|
end
|
81
|
+
def build; built; end
|
32
82
|
|
33
|
-
def deploy(app = nil); deployed(app); end
|
34
83
|
def deployed(app = nil)
|
35
84
|
event :deploy, app
|
36
85
|
end
|
86
|
+
def deploy(app = nil); deployed(app); end
|
37
87
|
|
38
88
|
def increment_on(stat, perf, sample_rate=1)
|
39
89
|
key = "#{stat}.%s" % (perf ? "success" : "fail")
|
@@ -41,6 +91,14 @@ module Fozzie
|
|
41
91
|
perf
|
42
92
|
end
|
43
93
|
|
94
|
+
def logger
|
95
|
+
self.class.logger
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.logger
|
99
|
+
@logger
|
100
|
+
end
|
101
|
+
|
44
102
|
private
|
45
103
|
|
46
104
|
def event(type, app = nil)
|
@@ -50,18 +108,30 @@ module Fozzie
|
|
50
108
|
end
|
51
109
|
|
52
110
|
def send_to_socket(message)
|
111
|
+
return false if Fozzie.c.ip_from_host.blank?
|
53
112
|
begin
|
54
|
-
ip = Fozzie.c.ip_from_host
|
55
|
-
raise RuntimeError, "Could not locate IP" unless ip
|
56
|
-
|
57
113
|
self.class.logger.debug {"Statsd: #{message}"} if self.class.logger
|
58
|
-
socket.send(message, 0,
|
59
|
-
rescue SocketError, RuntimeError => exc
|
114
|
+
socket.send(message, 0, Fozzie.c.ip_from_host, Fozzie.c.port)
|
115
|
+
rescue SocketError, RuntimeError, Errno::EADDRNOTAVAIL, Timeout::Error => exc
|
60
116
|
self.class.logger.debug {"Statsd Failure: #{exc.message}"} if self.class.logger
|
61
117
|
nil
|
62
118
|
end
|
63
119
|
end
|
64
120
|
|
121
|
+
def sampled(sample_rate)
|
122
|
+
yield unless sample_rate < 1 and rand > sample_rate
|
123
|
+
end
|
124
|
+
|
125
|
+
def send(stat, delta, type, sample_rate)
|
126
|
+
prefix = "#{Fozzie.c.data_prefix}." unless Fozzie.c.data_prefix.nil?
|
127
|
+
stat = stat.to_s.gsub('::', '.').gsub(RESERVED_CHARS_REGEX, '_')
|
128
|
+
sampled(sample_rate) { send_to_socket("#{prefix}#{stat}:#{delta}|#{type}#{'|@' << sample_rate.to_s if sample_rate < 1}") }
|
129
|
+
end
|
130
|
+
|
131
|
+
def socket
|
132
|
+
@socket ||= UDPSocket.new
|
133
|
+
end
|
134
|
+
|
65
135
|
end
|
66
136
|
|
67
137
|
def self.included(klass)
|
data/lib/fozzie/configuration.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'core_ext/hash'
|
2
2
|
require 'resolv'
|
3
|
+
require 'timeout'
|
3
4
|
|
4
5
|
module Fozzie
|
5
6
|
|
@@ -7,11 +8,12 @@ module Fozzie
|
|
7
8
|
# that will be used within the Fozzie codebase.
|
8
9
|
class Configuration
|
9
10
|
|
10
|
-
attr_accessor :env, :config_path, :host, :port, :appname, :namespaces
|
11
|
+
attr_accessor :env, :config_path, :host, :port, :appname, :namespaces, :timeout
|
11
12
|
|
12
13
|
def initialize(args = {})
|
13
14
|
merge_and_assign_config(args)
|
14
|
-
|
15
|
+
self.ip_from_host
|
16
|
+
self.origin_name
|
15
17
|
self
|
16
18
|
end
|
17
19
|
|
@@ -50,14 +52,19 @@ module Fozzie
|
|
50
52
|
:config_path => '',
|
51
53
|
:env => (ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'),
|
52
54
|
:appname => '',
|
53
|
-
:namespaces => %w{Stats S Statistics Warehouse}
|
55
|
+
:namespaces => %w{Stats S Statistics Warehouse},
|
56
|
+
:timeout => 5
|
54
57
|
}.dup
|
55
58
|
end
|
56
59
|
|
57
60
|
def host_to_ip
|
58
61
|
return self.host unless self.host.match(ip_address_regex).nil?
|
59
|
-
ips =
|
60
|
-
|
62
|
+
ips = begin
|
63
|
+
Timeout.timeout(self.timeout) { Resolv.getaddresses(self.host) }
|
64
|
+
rescue Timeout::Error => exc
|
65
|
+
[]
|
66
|
+
end
|
67
|
+
(ips.empty? ? "" : ips.compact.reject {|ip| ip.to_s.match(ip_address_regex).nil? }.first || "")
|
61
68
|
end
|
62
69
|
|
63
70
|
def ip_address_regex
|
@@ -11,8 +11,8 @@ module Fozzie
|
|
11
11
|
begin
|
12
12
|
routing = (rails_version == 3 ? ::Rails.application.routes : ::ActionController::Routing::Routes)
|
13
13
|
path = routing.recognize_path(path_str)
|
14
|
-
|
15
|
-
|
14
|
+
stat = [path[:controller], path[:action], "render"].join('.')
|
15
|
+
stat
|
16
16
|
rescue ActionController::RoutingError => exc
|
17
17
|
S.increment "routing.error"
|
18
18
|
nil
|
data/lib/fozzie/version.rb
CHANGED
@@ -59,11 +59,10 @@ describe Fozzie::Configuration do
|
|
59
59
|
end
|
60
60
|
|
61
61
|
it "assigns nil on miss" do
|
62
|
-
Resolv.expects(:getaddresses).with('some.awesome.log.server').returns([])
|
63
|
-
|
62
|
+
Resolv.expects(:getaddresses).with('some.awesome.log.server').returns([])
|
64
63
|
c = Fozzie::Configuration.new({:env => 'test', :config_path => nil, :host => 'some.awesome.log.server'})
|
65
|
-
c.ip_from_host.should ==
|
66
|
-
c.ip_from_host.should ==
|
64
|
+
c.ip_from_host.should == ""
|
65
|
+
c.ip_from_host.should == ""
|
67
66
|
end
|
68
67
|
|
69
68
|
it "looks up ip from host" do
|
@@ -74,7 +73,13 @@ describe Fozzie::Configuration do
|
|
74
73
|
it "caches the ip once it is retrieved" do
|
75
74
|
Resolv.expects(:getaddresses).with('lonelyplanet.com').returns(["1.1.1.1"])
|
76
75
|
c = Fozzie::Configuration.new({:env => 'test', :config_path => nil, :host => 'lonelyplanet.com'})
|
77
|
-
c.ip_from_host.should ==
|
76
|
+
c.ip_from_host.should == "1.1.1.1"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "raises Timeout on slow lookup" do
|
80
|
+
Resolv.stubs(:getaddresses).with('lonelyplanet.com') {|val| sleep 0.6; [] }
|
81
|
+
c = Fozzie::Configuration.new(:env => 'test', :config_path => nil, :host => 'lonelyplanet.com', :timeout => 0.5)
|
82
|
+
c.ip_from_host.should == ""
|
78
83
|
end
|
79
84
|
|
80
85
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fozzie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.14
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,22 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02
|
12
|
+
date: 2012-03-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: statsd-ruby
|
16
|
-
requirement: &70101336334120 !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '0'
|
22
|
-
type: :runtime
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: *70101336334120
|
25
14
|
- !ruby/object:Gem::Dependency
|
26
15
|
name: rake
|
27
|
-
requirement: &
|
16
|
+
requirement: &70330128630360 !ruby/object:Gem::Requirement
|
28
17
|
none: false
|
29
18
|
requirements:
|
30
19
|
- - ! '>='
|
@@ -32,10 +21,10 @@ dependencies:
|
|
32
21
|
version: '0'
|
33
22
|
type: :development
|
34
23
|
prerelease: false
|
35
|
-
version_requirements: *
|
24
|
+
version_requirements: *70330128630360
|
36
25
|
- !ruby/object:Gem::Dependency
|
37
26
|
name: rspec
|
38
|
-
requirement: &
|
27
|
+
requirement: &70330128629920 !ruby/object:Gem::Requirement
|
39
28
|
none: false
|
40
29
|
requirements:
|
41
30
|
- - ! '>='
|
@@ -43,10 +32,10 @@ dependencies:
|
|
43
32
|
version: '0'
|
44
33
|
type: :development
|
45
34
|
prerelease: false
|
46
|
-
version_requirements: *
|
35
|
+
version_requirements: *70330128629920
|
47
36
|
- !ruby/object:Gem::Dependency
|
48
37
|
name: mocha
|
49
|
-
requirement: &
|
38
|
+
requirement: &70330128629460 !ruby/object:Gem::Requirement
|
50
39
|
none: false
|
51
40
|
requirements:
|
52
41
|
- - ! '>='
|
@@ -54,10 +43,10 @@ dependencies:
|
|
54
43
|
version: '0'
|
55
44
|
type: :development
|
56
45
|
prerelease: false
|
57
|
-
version_requirements: *
|
46
|
+
version_requirements: *70330128629460
|
58
47
|
- !ruby/object:Gem::Dependency
|
59
48
|
name: syntax
|
60
|
-
requirement: &
|
49
|
+
requirement: &70330128629020 !ruby/object:Gem::Requirement
|
61
50
|
none: false
|
62
51
|
requirements:
|
63
52
|
- - ! '>='
|
@@ -65,10 +54,10 @@ dependencies:
|
|
65
54
|
version: '0'
|
66
55
|
type: :development
|
67
56
|
prerelease: false
|
68
|
-
version_requirements: *
|
57
|
+
version_requirements: *70330128629020
|
69
58
|
- !ruby/object:Gem::Dependency
|
70
59
|
name: rack-test
|
71
|
-
requirement: &
|
60
|
+
requirement: &70330128628580 !ruby/object:Gem::Requirement
|
72
61
|
none: false
|
73
62
|
requirements:
|
74
63
|
- - ! '>='
|
@@ -76,10 +65,10 @@ dependencies:
|
|
76
65
|
version: '0'
|
77
66
|
type: :development
|
78
67
|
prerelease: false
|
79
|
-
version_requirements: *
|
68
|
+
version_requirements: *70330128628580
|
80
69
|
- !ruby/object:Gem::Dependency
|
81
70
|
name: simplecov
|
82
|
-
requirement: &
|
71
|
+
requirement: &70330128628160 !ruby/object:Gem::Requirement
|
83
72
|
none: false
|
84
73
|
requirements:
|
85
74
|
- - ! '>='
|
@@ -87,10 +76,10 @@ dependencies:
|
|
87
76
|
version: '0'
|
88
77
|
type: :development
|
89
78
|
prerelease: false
|
90
|
-
version_requirements: *
|
79
|
+
version_requirements: *70330128628160
|
91
80
|
- !ruby/object:Gem::Dependency
|
92
81
|
name: sinatra
|
93
|
-
requirement: &
|
82
|
+
requirement: &70330128627720 !ruby/object:Gem::Requirement
|
94
83
|
none: false
|
95
84
|
requirements:
|
96
85
|
- - ! '>='
|
@@ -98,10 +87,32 @@ dependencies:
|
|
98
87
|
version: '0'
|
99
88
|
type: :development
|
100
89
|
prerelease: false
|
101
|
-
version_requirements: *
|
90
|
+
version_requirements: *70330128627720
|
102
91
|
- !ruby/object:Gem::Dependency
|
103
92
|
name: actionpack
|
104
|
-
requirement: &
|
93
|
+
requirement: &70330128627260 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :development
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *70330128627260
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: guard
|
104
|
+
requirement: &70330128626840 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: *70330128626840
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: guard-rspec
|
115
|
+
requirement: &70330128626400 !ruby/object:Gem::Requirement
|
105
116
|
none: false
|
106
117
|
requirements:
|
107
118
|
- - ! '>='
|
@@ -109,7 +120,7 @@ dependencies:
|
|
109
120
|
version: '0'
|
110
121
|
type: :development
|
111
122
|
prerelease: false
|
112
|
-
version_requirements: *
|
123
|
+
version_requirements: *70330128626400
|
113
124
|
description: Gem allows statistics gathering from Ruby and Ruby on Rails applications
|
114
125
|
to Statsd
|
115
126
|
email:
|
@@ -121,6 +132,7 @@ files:
|
|
121
132
|
- .gitignore
|
122
133
|
- .rvmrc
|
123
134
|
- Gemfile
|
135
|
+
- Guardfile
|
124
136
|
- README.md
|
125
137
|
- Rakefile
|
126
138
|
- fozzie.gemspec
|
@@ -156,7 +168,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
156
168
|
version: '0'
|
157
169
|
segments:
|
158
170
|
- 0
|
159
|
-
hash:
|
171
|
+
hash: -2167407767466603242
|
160
172
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
173
|
none: false
|
162
174
|
requirements:
|
@@ -165,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
177
|
version: '0'
|
166
178
|
segments:
|
167
179
|
- 0
|
168
|
-
hash:
|
180
|
+
hash: -2167407767466603242
|
169
181
|
requirements: []
|
170
182
|
rubyforge_project: fozzie
|
171
183
|
rubygems_version: 1.8.10
|