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 ADDED
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
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
@@ -1,39 +1,89 @@
1
- require 'statsd'
2
-
3
1
  module Fozzie
4
2
  module Classes
5
3
 
6
- class AbstractFozzie < Statsd
4
+ class AbstractFozzie
5
+
6
+ RESERVED_CHARS_REGEX = /[\:\|\@]/
7
7
 
8
8
  attr_reader :prefix, :configuration
9
9
 
10
- def initialize
11
- @namespace = Fozzie.c.data_prefix
12
- super Fozzie.c.host, Fozzie.c.port
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
- self
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, ip, Fozzie.c.port)
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)
@@ -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 = Resolv.getaddresses(self.host)
60
- ips.compact.reject {|ip| ip.to_s.match(ip_address_regex).nil? }.first unless ips.nil?
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
- [path[:controller], path[:action], "render"].join('.')
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
@@ -1,3 +1,3 @@
1
1
  module Fozzie
2
- VERSION = "0.0.13"
2
+ VERSION = "0.0.14"
3
3
  end
@@ -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([]).twice
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 == nil
66
- c.ip_from_host.should == nil
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 == c.ip_from_host
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.13
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-14 00:00:00.000000000 Z
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: &70101336333380 !ruby/object:Gem::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: *70101336333380
24
+ version_requirements: *70330128630360
36
25
  - !ruby/object:Gem::Dependency
37
26
  name: rspec
38
- requirement: &70101336332560 !ruby/object:Gem::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: *70101336332560
35
+ version_requirements: *70330128629920
47
36
  - !ruby/object:Gem::Dependency
48
37
  name: mocha
49
- requirement: &70101336331840 !ruby/object:Gem::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: *70101336331840
46
+ version_requirements: *70330128629460
58
47
  - !ruby/object:Gem::Dependency
59
48
  name: syntax
60
- requirement: &70101336496260 !ruby/object:Gem::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: *70101336496260
57
+ version_requirements: *70330128629020
69
58
  - !ruby/object:Gem::Dependency
70
59
  name: rack-test
71
- requirement: &70101336495340 !ruby/object:Gem::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: *70101336495340
68
+ version_requirements: *70330128628580
80
69
  - !ruby/object:Gem::Dependency
81
70
  name: simplecov
82
- requirement: &70101336494540 !ruby/object:Gem::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: *70101336494540
79
+ version_requirements: *70330128628160
91
80
  - !ruby/object:Gem::Dependency
92
81
  name: sinatra
93
- requirement: &70101336493560 !ruby/object:Gem::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: *70101336493560
90
+ version_requirements: *70330128627720
102
91
  - !ruby/object:Gem::Dependency
103
92
  name: actionpack
104
- requirement: &70101336492460 !ruby/object:Gem::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: *70101336492460
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: 2372667692060957828
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: 2372667692060957828
180
+ hash: -2167407767466603242
169
181
  requirements: []
170
182
  rubyforge_project: fozzie
171
183
  rubygems_version: 1.8.10