statsd-ruby 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Rein Henrichs
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,29 @@
1
+ = statsd
2
+
3
+ A Ruby statsd client (https://github.com/etsy/statsd)
4
+
5
+ = Testing
6
+
7
+ Run the specs with <tt>rake spec</tt>
8
+
9
+ Run the specs and include live integration specs with <tt>LIVE=true rake spec</tt>. Note: This will test over a real UDP socket.
10
+
11
+ == Contributing to statsd
12
+
13
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
14
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
15
+ * Fork the project
16
+ * Start a feature/bugfix branch
17
+ * Commit and push until you are happy with your contribution
18
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
19
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
20
+
21
+ == Contributors
22
+
23
+ * Rein Henrichs
24
+ * Ray Krueger
25
+
26
+ == Copyright
27
+
28
+ Copyright (c) 2011 Rein Henrichs. See LICENSE.txt for
29
+ further details.
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ require 'jeweler'
5
+ Jeweler::Tasks.new do |gem|
6
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
7
+ gem.name = "statsd-ruby"
8
+ gem.homepage = "http://github.com/reinh/statsd"
9
+ gem.license = "MIT"
10
+ gem.summary = %Q{A Statsd client in Ruby}
11
+ gem.description = %Q{A Statsd client in Ruby}
12
+ gem.email = "rein@phpfog.com"
13
+ gem.authors = ["Rein Henrichs"]
14
+ gem.add_development_dependency "minitest", ">= 0"
15
+ gem.add_development_dependency "yard", "~> 0.6.0"
16
+ gem.add_development_dependency "jeweler", "~> 1.5.2"
17
+ gem.add_development_dependency "rcov", ">= 0"
18
+ end
19
+ Jeweler::RubygemsDotOrgTasks.new
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.pattern = 'spec/**/*_spec.rb'
25
+ spec.verbose = true
26
+ end
27
+
28
+ require 'rcov/rcovtask'
29
+ Rcov::RcovTask.new do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.pattern = 'spec/**/*_spec.rb'
32
+ spec.verbose = true
33
+ end
34
+
35
+ task :default => :spec
36
+
37
+ require 'yard'
38
+ YARD::Rake::YardocTask.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
data/lib/statsd.rb ADDED
@@ -0,0 +1,66 @@
1
+ require 'socket'
2
+
3
+ # = Statsd: A Statsd client (https://github.com/etsy/statsd)
4
+ #
5
+ # Example:
6
+ #
7
+ # statsd = Statsd.new 'localhost', 8125
8
+ #
9
+ # statsd.increment 'garets'
10
+ # statsd.timing 'glork', 320
11
+ class Statsd
12
+ attr_accessor :namespace
13
+
14
+ class << self
15
+ attr_accessor :logger
16
+ end
17
+
18
+ # @param [String] host your statsd host
19
+ # @param [Integer] port your statsd port
20
+ def initialize(host, port=8125)
21
+ @host, @port = host, port
22
+ end
23
+
24
+ # @param [String] stat stat name
25
+ # @param [Integer] sample_rate sample rate, 1 for always
26
+ def increment(stat, sample_rate=1); count stat, 1, sample_rate end
27
+
28
+ # @param [String] stat stat name
29
+ # @param [Integer] sample_rate sample rate, 1 for always
30
+ def decrement(stat, sample_rate=1); count stat, -1, sample_rate end
31
+
32
+ # @param [String] stat stat name
33
+ # @param [Integer] count count
34
+ # @param [Integer] sample_rate sample rate, 1 for always
35
+ def count(stat, count, sample_rate=1); send stat, count, 'c', sample_rate end
36
+
37
+ # @param [String] stat stat name
38
+ # @param [Integer] ms timing in milliseconds
39
+ # @param [Integer] sample_rate sample rate, 1 for always
40
+ def timing(stat, ms, sample_rate=1); send stat, ms, 'ms', sample_rate end
41
+
42
+ def time(stat, sample_rate=1)
43
+ start = Time.now
44
+ result = yield
45
+ timing(stat, ((Time.now - start) * 1000).round, sample_rate)
46
+ result
47
+ end
48
+
49
+ private
50
+
51
+ def sampled(sample_rate)
52
+ yield unless sample_rate < 1 and rand > sample_rate
53
+ end
54
+
55
+ def send(stat, delta, type, sample_rate)
56
+ prefix = "#{@namespace}." unless @namespace.nil?
57
+ sampled(sample_rate) { send_to_socket("#{prefix}#{stat}:#{delta}|#{type}#{'|@' << sample_rate.to_s if sample_rate < 1}") }
58
+ end
59
+
60
+ def send_to_socket(message)
61
+ self.class.logger.debug {"Statsd: #{message}"} if self.class.logger
62
+ socket.send(message, 0, @host, @port)
63
+ end
64
+
65
+ def socket; @socket ||= UDPSocket.new end
66
+ end
data/spec/helper.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'minitest/autorun'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require 'statsd'
7
+
8
+ class FakeUDPSocket
9
+ def initialize
10
+ @buffer = []
11
+ end
12
+
13
+ def send(message, *rest)
14
+ @buffer.push [message]
15
+ end
16
+
17
+ def recv
18
+ res = @buffer.shift
19
+ end
20
+
21
+ def clear
22
+ @buffer = []
23
+ end
24
+
25
+ def to_s
26
+ inspect
27
+ end
28
+
29
+ def inspect
30
+ "<FakeUDPSocket: #{@buffer.inspect}>"
31
+ end
32
+ end
@@ -0,0 +1,154 @@
1
+ require 'helper'
2
+
3
+ describe Statsd do
4
+ before do
5
+ @statsd = Statsd.new('localhost', 1234)
6
+ class << @statsd
7
+ public :sampled # we need to test this
8
+ attr_reader :host, :port # we also need to test this
9
+ def socket; @socket ||= FakeUDPSocket.new end
10
+ end
11
+ end
12
+
13
+ after { @statsd.socket.clear }
14
+
15
+ describe "#initialize" do
16
+ it "should set the host and port" do
17
+ @statsd.host.must_equal 'localhost'
18
+ @statsd.port.must_equal 1234
19
+ end
20
+
21
+ it "should default the port to 8125" do
22
+ Statsd.new('localhost').instance_variable_get('@port').must_equal 8125
23
+ end
24
+ end
25
+
26
+ describe "#increment" do
27
+ it "should format the message according to the statsd spec" do
28
+ @statsd.increment('foobar')
29
+ @statsd.socket.recv.must_equal ['foobar:1|c']
30
+ end
31
+
32
+ describe "with a sample rate" do
33
+ before { class << @statsd; def rand; 0; end; end } # ensure delivery
34
+ it "should format the message according to the statsd spec" do
35
+ @statsd.increment('foobar', 0.5)
36
+ @statsd.socket.recv.must_equal ['foobar:1|c|@0.5']
37
+ end
38
+ end
39
+ end
40
+
41
+ describe "#decrement" do
42
+ it "should format the message according to the statsd spec" do
43
+ @statsd.decrement('foobar')
44
+ @statsd.socket.recv.must_equal ['foobar:-1|c']
45
+ end
46
+
47
+ describe "with a sample rate" do
48
+ before { class << @statsd; def rand; 0; end; end } # ensure delivery
49
+ it "should format the message according to the statsd spec" do
50
+ @statsd.decrement('foobar', 0.5)
51
+ @statsd.socket.recv.must_equal ['foobar:-1|c|@0.5']
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "#timing" do
57
+ it "should format the message according to the statsd spec" do
58
+ @statsd.timing('foobar', 500)
59
+ @statsd.socket.recv.must_equal ['foobar:500|ms']
60
+ end
61
+
62
+ describe "with a sample rate" do
63
+ before { class << @statsd; def rand; 0; end; end } # ensure delivery
64
+ it "should format the message according to the statsd spec" do
65
+ @statsd.timing('foobar', 500, 0.5)
66
+ @statsd.socket.recv.must_equal ['foobar:500|ms|@0.5']
67
+ end
68
+ end
69
+ end
70
+
71
+ describe "#time" do
72
+ it "should format the message according to the statsd spec" do
73
+ @statsd.time('foobar') { sleep(0.001); 'test' }
74
+ @statsd.socket.recv.must_equal ['foobar:1|ms']
75
+ end
76
+
77
+ it "should return the result of the block" do
78
+ result = @statsd.time('foobar') { sleep(0.001); 'test' }
79
+ result.must_equal 'test'
80
+ end
81
+
82
+ describe "with a sample rate" do
83
+ before { class << @statsd; def rand; 0; end; end } # ensure delivery
84
+
85
+ it "should format the message according to the statsd spec" do
86
+ result = @statsd.time('foobar', 0.5) { sleep(0.001); 'test' }
87
+ @statsd.socket.recv.must_equal ['foobar:1|ms|@0.5']
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "#sampled" do
93
+ describe "when the sample rate is 1" do
94
+ it "should yield" do
95
+ @statsd.sampled(1) { :yielded }.must_equal :yielded
96
+ end
97
+ end
98
+
99
+ describe "when the sample rate is greater than a random value [0,1]" do
100
+ before { class << @statsd; def rand; 0; end; end } # ensure delivery
101
+ it "should yield" do
102
+ @statsd.sampled(0.5) { :yielded }.must_equal :yielded
103
+ end
104
+ end
105
+
106
+ describe "when the sample rate is less than a random value [0,1]" do
107
+ before { class << @statsd; def rand; 1; end; end } # ensure no delivery
108
+ it "should not yield" do
109
+ @statsd.sampled(0.5) { :yielded }.must_equal nil
110
+ end
111
+ end
112
+
113
+ describe "when the sample rate is equal to a random value [0,1]" do
114
+ before { class << @statsd; def rand; 0.5; end; end } # ensure delivery
115
+ it "should yield" do
116
+ @statsd.sampled(0.5) { :yielded }.must_equal :yielded
117
+ end
118
+ end
119
+ end
120
+
121
+ describe "with namespace" do
122
+ before { @statsd.namespace = 'service' }
123
+
124
+ it "should add namespace to increment" do
125
+ @statsd.increment('foobar')
126
+ @statsd.socket.recv.must_equal ['service.foobar:1|c']
127
+ end
128
+
129
+ it "should add namespace to decrement" do
130
+ @statsd.decrement('foobar')
131
+ @statsd.socket.recv.must_equal ['service.foobar:-1|c']
132
+ end
133
+
134
+ it "should add namespace to timing" do
135
+ @statsd.timing('foobar', 500)
136
+ @statsd.socket.recv.must_equal ['service.foobar:500|ms']
137
+ end
138
+ end
139
+ end
140
+
141
+ describe Statsd do
142
+ describe "with a real UDP socket" do
143
+ it "should actually send stuff over the socket" do
144
+ socket = UDPSocket.new
145
+ host, port = 'localhost', 12345
146
+ socket.bind(host, port)
147
+
148
+ statsd = Statsd.new(host, port)
149
+ statsd.increment('foobar')
150
+ message = socket.recvfrom(16).first
151
+ message.must_equal 'foobar:1|c'
152
+ end
153
+ end
154
+ end if ENV['LIVE']
@@ -0,0 +1,57 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{statsd-ruby}
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Rein Henrichs"]
12
+ s.date = %q{2011-06-23}
13
+ s.description = %q{A Statsd client in Ruby}
14
+ s.email = %q{rein@phpfog.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "LICENSE.txt",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "lib/statsd.rb",
26
+ "spec/helper.rb",
27
+ "spec/statsd_spec.rb",
28
+ "statsd-ruby.gemspec"
29
+ ]
30
+ s.homepage = %q{http://github.com/reinh/statsd}
31
+ s.licenses = ["MIT"]
32
+ s.require_paths = ["lib"]
33
+ s.rubygems_version = %q{1.5.2}
34
+ s.summary = %q{A Statsd client in Ruby}
35
+
36
+ if s.respond_to? :specification_version then
37
+ s.specification_version = 3
38
+
39
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
40
+ s.add_development_dependency(%q<minitest>, [">= 0"])
41
+ s.add_development_dependency(%q<yard>, ["~> 0.6.0"])
42
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
43
+ s.add_development_dependency(%q<rcov>, [">= 0"])
44
+ else
45
+ s.add_dependency(%q<minitest>, [">= 0"])
46
+ s.add_dependency(%q<yard>, ["~> 0.6.0"])
47
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
48
+ s.add_dependency(%q<rcov>, [">= 0"])
49
+ end
50
+ else
51
+ s.add_dependency(%q<minitest>, [">= 0"])
52
+ s.add_dependency(%q<yard>, ["~> 0.6.0"])
53
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
54
+ s.add_dependency(%q<rcov>, [">= 0"])
55
+ end
56
+ end
57
+
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: statsd-ruby
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
+ platform: ruby
12
+ authors:
13
+ - Rein Henrichs
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-06-23 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: minitest
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: yard
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ hash: 7
44
+ segments:
45
+ - 0
46
+ - 6
47
+ - 0
48
+ version: 0.6.0
49
+ type: :development
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: jeweler
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ hash: 7
60
+ segments:
61
+ - 1
62
+ - 5
63
+ - 2
64
+ version: 1.5.2
65
+ type: :development
66
+ version_requirements: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ name: rcov
69
+ prerelease: false
70
+ requirement: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ type: :development
80
+ version_requirements: *id004
81
+ description: A Statsd client in Ruby
82
+ email: rein@phpfog.com
83
+ executables: []
84
+
85
+ extensions: []
86
+
87
+ extra_rdoc_files:
88
+ - LICENSE.txt
89
+ - README.rdoc
90
+ files:
91
+ - .document
92
+ - LICENSE.txt
93
+ - README.rdoc
94
+ - Rakefile
95
+ - VERSION
96
+ - lib/statsd.rb
97
+ - spec/helper.rb
98
+ - spec/statsd_spec.rb
99
+ - statsd-ruby.gemspec
100
+ has_rdoc: true
101
+ homepage: http://github.com/reinh/statsd
102
+ licenses:
103
+ - MIT
104
+ post_install_message:
105
+ rdoc_options: []
106
+
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ hash: 3
115
+ segments:
116
+ - 0
117
+ version: "0"
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ hash: 3
124
+ segments:
125
+ - 0
126
+ version: "0"
127
+ requirements: []
128
+
129
+ rubyforge_project:
130
+ rubygems_version: 1.5.2
131
+ signing_key:
132
+ specification_version: 3
133
+ summary: A Statsd client in Ruby
134
+ test_files: []
135
+