fozzie 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +5 -5
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +5 -5
  6. data/Gemfile +3 -3
  7. data/README.md +288 -276
  8. data/Rakefile +6 -6
  9. data/fozzie.gemspec +29 -29
  10. data/fozzie.yml.example +14 -14
  11. data/lib/core_ext/hash/symbolize_keys.rb +21 -21
  12. data/lib/core_ext/module/alias_method_chain.rb +19 -19
  13. data/lib/core_ext/module/monitor.rb +12 -12
  14. data/lib/core_ext/string/snakecase.rb +9 -9
  15. data/lib/fozzie.rb +67 -67
  16. data/lib/fozzie/adapter/statsd.rb +95 -95
  17. data/lib/fozzie/bulk_dsl.rb +27 -27
  18. data/lib/fozzie/configuration.rb +1 -0
  19. data/lib/fozzie/dsl.rb +18 -18
  20. data/lib/fozzie/exception.rb +4 -4
  21. data/lib/fozzie/interface.rb +139 -139
  22. data/lib/fozzie/rack/middleware.rb +43 -43
  23. data/lib/fozzie/sniff.rb +49 -49
  24. data/lib/fozzie/version.rb +3 -3
  25. data/resources/mill.js.example +26 -26
  26. data/spec/config/fozzie.yml +5 -5
  27. data/spec/lib/core_ext/module/monitor_spec.rb +8 -8
  28. data/spec/lib/fozzie/adapter/statsd_spec.rb +82 -82
  29. data/spec/lib/fozzie/bulk_dsl_spec.rb +46 -46
  30. data/spec/lib/fozzie/configuration_spec.rb +125 -125
  31. data/spec/lib/fozzie/dsl_spec.rb +15 -15
  32. data/spec/lib/fozzie/rack/middleware_spec.rb +69 -69
  33. data/spec/lib/fozzie/rack/sinatra_spec.rb +30 -30
  34. data/spec/lib/fozzie/sniff_spec.rb +131 -131
  35. data/spec/lib/fozzie/version_spec.rb +9 -9
  36. data/spec/lib/fozzie_spec.rb +39 -39
  37. data/spec/shared_examples/fozzie_adapter.rb +7 -7
  38. data/spec/shared_examples/interface.rb +159 -159
  39. data/spec/spec_helper.rb +28 -28
  40. metadata +24 -36
  41. data/.rvmrc +0 -1
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
- require 'bundler'
2
- Bundler::GemHelper.install_tasks
3
-
4
- require 'rspec/core/rake_task'
5
- RSpec::Core::RakeTask.new(:spec)
6
-
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
7
  task :default => :spec
@@ -1,29 +1,29 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "fozzie/version"
4
-
5
- Gem::Specification.new do |s|
6
- s.name = "fozzie"
7
- s.version = Fozzie::VERSION
8
- s.authors = ["Marc Watts"]
9
- s.email = ["marc.watts@lonelyplanet.co.uk"]
10
- s.summary = %q{Ruby gem from Lonely Planet Online to register statistics. Currently supports Statsd.}
11
- s.description = %q{
12
- Gem to make statistics sending from Ruby applications simple and efficient as possible.
13
- Currently supports Statsd, and is inspired by the original ruby-statsd gem by Etsy.
14
- }
15
-
16
- s.rubyforge_project = "fozzie"
17
-
18
- s.files = `git ls-files`.split("\n")
19
- s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
20
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
- s.require_paths = ["lib"]
22
-
23
- s.add_dependency 'sys-uname'
24
-
25
- s.add_development_dependency 'rake'
26
- s.add_development_dependency 'rspec'
27
- s.add_development_dependency 'sinatra'
28
- s.add_development_dependency 'rack-test'
29
- end
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "fozzie/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "fozzie"
7
+ s.version = Fozzie::VERSION
8
+ s.authors = ["Marc Watts"]
9
+ s.email = ["marc.watts@lonelyplanet.co.uk"]
10
+ s.summary = %q{Ruby gem from Lonely Planet Online to register statistics. Currently supports Statsd.}
11
+ s.description = %q{
12
+ Gem to make statistics sending from Ruby applications simple and efficient as possible.
13
+ Currently supports Statsd, and is inspired by the original ruby-statsd gem by Etsy.
14
+ }
15
+
16
+ s.rubyforge_project = "fozzie"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ s.add_dependency 'sys-uname'
24
+
25
+ s.add_development_dependency 'rake'
26
+ s.add_development_dependency 'rspec'
27
+ s.add_development_dependency 'sinatra'
28
+ s.add_development_dependency 'rack-test'
29
+ end
@@ -1,15 +1,15 @@
1
- generic: &generic
2
- appname: fozzie
3
- host: '127.0.0.1'
4
- port: 8125
5
-
6
- development:
7
- <<: *generic
8
- staging:
9
- <<: *generic
10
- test:
11
- <<: *generic
12
- ci:
13
- <<: *generic
14
- production:
1
+ generic: &generic
2
+ appname: fozzie
3
+ host: '127.0.0.1'
4
+ port: 8125
5
+
6
+ development:
7
+ <<: *generic
8
+ staging:
9
+ <<: *generic
10
+ test:
11
+ <<: *generic
12
+ ci:
13
+ <<: *generic
14
+ production:
15
15
  <<: *generic
@@ -1,22 +1,22 @@
1
- class Hash
2
- def symbolize_keys(&select)
3
- dup.symbolize_keys!(&select)
4
- end
5
-
6
- def symbolize_keys!(&select)
7
- if select
8
- keys.each do |key|
9
- if select[key]
10
- new_key = (key.to_sym rescue key.to_s.to_sym)
11
- self[new_key] = delete(key)
12
- end
13
- end
14
- else
15
- keys.each do |key|
16
- new_key = (key.to_sym rescue key.to_s.to_sym)
17
- self[new_key] = delete(key)
18
- end
19
- end
20
- self
21
- end
1
+ class Hash
2
+ def symbolize_keys(&select)
3
+ dup.symbolize_keys!(&select)
4
+ end
5
+
6
+ def symbolize_keys!(&select)
7
+ if select
8
+ keys.each do |key|
9
+ if select[key]
10
+ new_key = (key.to_sym rescue key.to_s.to_sym)
11
+ self[new_key] = delete(key)
12
+ end
13
+ end
14
+ else
15
+ keys.each do |key|
16
+ new_key = (key.to_sym rescue key.to_s.to_sym)
17
+ self[new_key] = delete(key)
18
+ end
19
+ end
20
+ self
21
+ end
22
22
  end
@@ -1,20 +1,20 @@
1
- class Module
2
- def alias_method_chain(target, feature)
3
- aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
4
- yield(aliased_target, punctuation) if block_given?
5
-
6
- with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}"
7
-
8
- alias_method without_method, target
9
- alias_method target, with_method
10
-
11
- case
12
- when public_method_defined?(without_method)
13
- public target
14
- when protected_method_defined?(without_method)
15
- protected target
16
- when private_method_defined?(without_method)
17
- private target
18
- end
19
- end
1
+ class Module
2
+ def alias_method_chain(target, feature)
3
+ aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
4
+ yield(aliased_target, punctuation) if block_given?
5
+
6
+ with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}"
7
+
8
+ alias_method without_method, target
9
+ alias_method target, with_method
10
+
11
+ case
12
+ when public_method_defined?(without_method)
13
+ public target
14
+ when protected_method_defined?(without_method)
15
+ protected target
16
+ when private_method_defined?(without_method)
17
+ private target
18
+ end
19
+ end
20
20
  end
@@ -1,12 +1,12 @@
1
- require 'fozzie/sniff'
2
-
3
- class Module
4
-
5
- def _monitor(bucket_name = nil)
6
- return unless Fozzie.c.sniff?
7
- self.class_eval { extend Fozzie::Sniff }
8
- @_monitor_flag = true
9
- @_bucket_name = bucket_name
10
- end
11
-
12
- end
1
+ require 'fozzie/sniff'
2
+
3
+ class Module
4
+
5
+ def _monitor(bucket_name = nil)
6
+ return unless Fozzie.c.sniff?
7
+ self.class_eval { extend Fozzie::Sniff }
8
+ @_monitor_flag = true
9
+ @_bucket_name = bucket_name
10
+ end
11
+
12
+ end
@@ -1,10 +1,10 @@
1
- class String
2
- def snakecase
3
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
4
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
5
- tr('-', '_').
6
- gsub(/\s/, '_').
7
- gsub(/__+/, '_').
8
- downcase
9
- end
1
+ class String
2
+ def snakecase
3
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
4
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
5
+ tr('-', '_').
6
+ gsub(/\s/, '_').
7
+ gsub(/__+/, '_').
8
+ downcase
9
+ end
10
10
  end
@@ -1,67 +1,67 @@
1
- # Fozzie is an implementation of the Statsd statistics gathering tool,
2
- # designed to make gathering stastistics from applications easy, fast, and effective.
3
- #
4
- # Configuration can be applied through a block and/or configuration file ('config/fozzie.yml')
5
- #
6
- # Fozzie provides automatic namespacing for the current environment, and host.
7
- #
8
- # Rack and Rails middleware is avaliable to gather statistics on the processing time of Controller actions.
9
- #
10
-
11
- module Fozzie
12
-
13
- require 'core_ext/module/monitor'
14
- require 'core_ext/module/alias_method_chain' unless Module.methods.include?(:alias_method_chain)
15
- require 'core_ext/string/snakecase'
16
- require 'core_ext/hash/symbolize_keys'
17
-
18
- require 'fozzie/adapter'
19
-
20
- require "fozzie/exception"
21
- require 'fozzie/configuration'
22
- require "fozzie/dsl"
23
- require "fozzie/bulk_dsl"
24
- require "fozzie/version"
25
-
26
- class << self
27
-
28
- # Shortcut for `Fozzie.config`
29
- def c
30
- config
31
- end
32
-
33
- # Returns the current configuration. Creates configuration on first-time request
34
- def config
35
- @config ||= Configuration.new
36
- end
37
-
38
- # Allows the setting on valudes against the configuration
39
- #
40
- # `Fozzie.configure {|config| config.wat = :random }`
41
- def configure
42
- yield c if block_given?
43
- end
44
-
45
- # Set a logger
46
- #
47
- #
48
- # `Fozzie.logger = Logger.new(STDOUT)`
49
- def logger=(logger)
50
- @logger = logger
51
- end
52
-
53
- # Accessor for logger
54
- #
55
- # `Fozzie.logger.warn 'foo'`
56
- def logger
57
- @logger
58
- end
59
-
60
- end
61
-
62
- # Loads each namespace for registering statistics
63
- self.c.namespaces.each do |klas|
64
- Kernel.const_set(klas, Dsl.instance) unless const_defined?(klas)
65
- end
66
-
67
- end
1
+ # Fozzie is an implementation of the Statsd statistics gathering tool,
2
+ # designed to make gathering stastistics from applications easy, fast, and effective.
3
+ #
4
+ # Configuration can be applied through a block and/or configuration file ('config/fozzie.yml')
5
+ #
6
+ # Fozzie provides automatic namespacing for the current environment, and host.
7
+ #
8
+ # Rack and Rails middleware is avaliable to gather statistics on the processing time of Controller actions.
9
+ #
10
+
11
+ module Fozzie
12
+
13
+ require 'core_ext/module/monitor'
14
+ require 'core_ext/module/alias_method_chain' unless Module.methods.include?(:alias_method_chain)
15
+ require 'core_ext/string/snakecase'
16
+ require 'core_ext/hash/symbolize_keys'
17
+
18
+ require 'fozzie/adapter'
19
+
20
+ require "fozzie/exception"
21
+ require 'fozzie/configuration'
22
+ require "fozzie/dsl"
23
+ require "fozzie/bulk_dsl"
24
+ require "fozzie/version"
25
+
26
+ class << self
27
+
28
+ # Shortcut for `Fozzie.config`
29
+ def c
30
+ config
31
+ end
32
+
33
+ # Returns the current configuration. Creates configuration on first-time request
34
+ def config
35
+ @config ||= Configuration.new
36
+ end
37
+
38
+ # Allows the setting on valudes against the configuration
39
+ #
40
+ # `Fozzie.configure {|config| config.wat = :random }`
41
+ def configure
42
+ yield c if block_given?
43
+ end
44
+
45
+ # Set a logger
46
+ #
47
+ #
48
+ # `Fozzie.logger = Logger.new(STDOUT)`
49
+ def logger=(logger)
50
+ @logger = logger
51
+ end
52
+
53
+ # Accessor for logger
54
+ #
55
+ # `Fozzie.logger.warn 'foo'`
56
+ def logger
57
+ @logger
58
+ end
59
+
60
+ end
61
+
62
+ # Loads each namespace for registering statistics
63
+ self.c.namespaces.each do |klas|
64
+ Kernel.const_set(klas, Dsl.instance) unless const_defined?(klas)
65
+ end
66
+
67
+ end
@@ -1,95 +1,95 @@
1
- require 'socket'
2
- require 'resolv'
3
-
4
- module Fozzie
5
- module Adapter
6
-
7
- class Statsd
8
-
9
- RESERVED_CHARS_REGEX = /[\:\|\@\s]/
10
- RESERVED_CHARS_REPLACEMENT = '_'
11
- DELIMETER = '.'
12
- SAFE_SEPARATOR = '-'
13
- TYPES = { :gauge => 'g', :count => 'c', :timing => 'ms' }
14
- BULK_DELIMETER = "\n"
15
-
16
- # Send the statistic to the server
17
- #
18
- # Creates the Statsd key from the given values, and sends to socket (depending on sample rate)
19
- def register(*stats)
20
- metrics = stats.flatten.collect do |stat|
21
- next if sampled?(stat[:sample_rate])
22
-
23
- bucket = format_bucket(stat[:bin])
24
- value = format_value(stat[:value], stat[:type], stat[:sample_rate])
25
-
26
- [bucket, value].join(':')
27
- end.compact.join(BULK_DELIMETER)
28
-
29
- send_to_socket(metrics)
30
- end
31
-
32
- def format_bucket(stat)
33
- bucket = [stat].flatten.compact.collect(&:to_s).join(DELIMETER).downcase
34
- bucket = bucket.gsub('::', DELIMETER).gsub(RESERVED_CHARS_REGEX, RESERVED_CHARS_REPLACEMENT)
35
- bucket = [Fozzie.c.data_prefix, bucket].compact.join(DELIMETER)
36
-
37
- bucket
38
- end
39
-
40
- def format_value(val, type, sample_rate)
41
- converted_type = TYPES[type.to_sym]
42
- converted_type ||= TYPES[:gauge]
43
-
44
- value = [val, converted_type].join('|')
45
- value << '@%s' % sample_rate.to_s if sample_rate < 1
46
-
47
- value
48
- end
49
-
50
- # If the statistic is sampled, generate a condition to check if it's good to send
51
- def sampled(sample_rate)
52
- yield unless sampled?(sample_rate)
53
- end
54
-
55
- def sampled?(sample_rate)
56
- sample_rate < 1 and rand > sample_rate
57
- end
58
-
59
- # Send data to the server via the socket
60
- def send_to_socket(message)
61
- Fozzie.logger.debug {"Statsd: #{message}"} if Fozzie.logger
62
- Timeout.timeout(Fozzie.c.timeout) {
63
- res = socket.send(message, 0, host_ip, host_port)
64
- Fozzie.logger.debug {"Statsd sent: #{res}"} if Fozzie.logger
65
- (res.to_i == message.length)
66
- }
67
- rescue => exc
68
- Fozzie.logger.debug {"Statsd Failure: #{exc.message}\n#{exc.backtrace}"} if Fozzie.logger
69
- false
70
- end
71
-
72
- # The Socket we want to use to send data
73
- def socket
74
- @socket ||= ::UDPSocket.new
75
- end
76
-
77
- def host_ip
78
- @host_ip ||= Resolv.getaddress(Fozzie.c.host)
79
- end
80
-
81
- def host_port
82
- @host_port ||= Fozzie.c.port
83
- end
84
-
85
- def delimeter
86
- DELIMETER
87
- end
88
-
89
- def safe_separator
90
- SAFE_SEPARATOR
91
- end
92
- end
93
-
94
- end
95
- end
1
+ require 'socket'
2
+ require 'resolv'
3
+
4
+ module Fozzie
5
+ module Adapter
6
+
7
+ class Statsd
8
+
9
+ RESERVED_CHARS_REGEX = /[\:\|\@\s]/
10
+ RESERVED_CHARS_REPLACEMENT = '_'
11
+ DELIMETER = '.'
12
+ SAFE_SEPARATOR = '-'
13
+ TYPES = { :gauge => 'g', :count => 'c', :timing => 'ms' }
14
+ BULK_DELIMETER = "\n"
15
+
16
+ # Send the statistic to the server
17
+ #
18
+ # Creates the Statsd key from the given values, and sends to socket (depending on sample rate)
19
+ def register(*stats)
20
+ metrics = stats.flatten.collect do |stat|
21
+ next if sampled?(stat[:sample_rate])
22
+
23
+ bucket = format_bucket(stat[:bin])
24
+ value = format_value(stat[:value], stat[:type], stat[:sample_rate])
25
+
26
+ [bucket, value].join(':')
27
+ end.compact.join(BULK_DELIMETER)
28
+
29
+ send_to_socket(metrics)
30
+ end
31
+
32
+ def format_bucket(stat)
33
+ bucket = [stat].flatten.compact.collect(&:to_s).join(DELIMETER).downcase
34
+ bucket = bucket.gsub('::', DELIMETER).gsub(RESERVED_CHARS_REGEX, RESERVED_CHARS_REPLACEMENT)
35
+ bucket = [Fozzie.c.data_prefix, bucket].compact.join(DELIMETER)
36
+
37
+ bucket
38
+ end
39
+
40
+ def format_value(val, type, sample_rate)
41
+ converted_type = TYPES[type.to_sym]
42
+ converted_type ||= TYPES[:gauge]
43
+
44
+ value = [val, converted_type].join('|')
45
+ value << '@%s' % sample_rate.to_s if sample_rate < 1
46
+
47
+ value
48
+ end
49
+
50
+ # If the statistic is sampled, generate a condition to check if it's good to send
51
+ def sampled(sample_rate)
52
+ yield unless sampled?(sample_rate)
53
+ end
54
+
55
+ def sampled?(sample_rate)
56
+ sample_rate < 1 and rand > sample_rate
57
+ end
58
+
59
+ # Send data to the server via the socket
60
+ def send_to_socket(message)
61
+ Fozzie.logger.debug {"Statsd: #{message}"} if Fozzie.logger
62
+ Timeout.timeout(Fozzie.c.timeout) {
63
+ res = socket.send(message, 0, host_ip, host_port)
64
+ Fozzie.logger.debug {"Statsd sent: #{res}"} if Fozzie.logger
65
+ (res.to_i == message.length)
66
+ }
67
+ rescue => exc
68
+ Fozzie.logger.debug {"Statsd Failure: #{exc.message}\n#{exc.backtrace}"} if Fozzie.logger
69
+ false
70
+ end
71
+
72
+ # The Socket we want to use to send data
73
+ def socket
74
+ @socket ||= ::UDPSocket.new
75
+ end
76
+
77
+ def host_ip
78
+ @host_ip ||= Resolv.getaddress(Fozzie.c.host)
79
+ end
80
+
81
+ def host_port
82
+ @host_port ||= Fozzie.c.port
83
+ end
84
+
85
+ def delimeter
86
+ DELIMETER
87
+ end
88
+
89
+ def safe_separator
90
+ SAFE_SEPARATOR
91
+ end
92
+ end
93
+
94
+ end
95
+ end