statsd-rb 0.1.0
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/LICENSE +19 -0
- data/README.md +52 -0
- data/Rakefile +9 -0
- data/lib/statsd.rb +1 -0
- data/lib/statsd/client.rb +48 -0
- data/lib/statsd/version.rb +3 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/statsd/client_spec.rb +175 -0
- metadata +74 -0
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2011 Matt Duncan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
statsd-rb
|
2
|
+
=========
|
3
|
+
A ruby client for [StatsD](https://github.com/etsy/statsd).
|
4
|
+
|
5
|
+
Usage
|
6
|
+
-----
|
7
|
+
Connecting to a StatsD instance:
|
8
|
+
|
9
|
+
require "statsd"
|
10
|
+
client = StatsD::Client.new
|
11
|
+
|
12
|
+
By default, clients will connect to `localhost:8125`. If you need to
|
13
|
+
connect to a remote server or a different port, use the `:hostname` and
|
14
|
+
`:port` options.
|
15
|
+
|
16
|
+
client = StatsD::Client.new(:hostname => "statsd", :port => 5000)
|
17
|
+
|
18
|
+
### Commands
|
19
|
+
Once you have a client, sending statistics is easy.
|
20
|
+
|
21
|
+
Increment the downloads count:
|
22
|
+
|
23
|
+
client.incr :downloads
|
24
|
+
|
25
|
+
Increment the downloads count, telling StatsD that the counter is being
|
26
|
+
sampled every 10th time. All commands take an optional last argument
|
27
|
+
`sample_rate`.
|
28
|
+
|
29
|
+
client.incr :downloads, 0.1
|
30
|
+
|
31
|
+
Decrement the invites count by two:
|
32
|
+
|
33
|
+
client.decrby :invites, 2
|
34
|
+
|
35
|
+
Time the archive job:
|
36
|
+
|
37
|
+
client.time :archive do
|
38
|
+
# something
|
39
|
+
end
|
40
|
+
|
41
|
+
Send an already calculated timing:
|
42
|
+
|
43
|
+
client.timing :archive, 300 # milliseconds
|
44
|
+
|
45
|
+
TODO
|
46
|
+
----
|
47
|
+
|
48
|
+
- Bulk updating
|
49
|
+
|
50
|
+
Author
|
51
|
+
------
|
52
|
+
Matt Duncan | [mattduncan.org](http://mattduncan.org) | [matt@mattduncan.org](mailto:matt@mattduncan.org)
|
data/Rakefile
ADDED
data/lib/statsd.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'statsd/client'
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
module StatsD
|
5
|
+
class Client
|
6
|
+
attr_reader :hostname, :port
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
@hostname = options[:hostname] || "localhost"
|
10
|
+
@port = (options[:port] || 8125).to_i
|
11
|
+
end
|
12
|
+
|
13
|
+
def time(key, sample_rate = 1, &block)
|
14
|
+
seconds = Benchmark.realtime { block.call }
|
15
|
+
timing(key, (seconds * 1000).round, sample_rate)
|
16
|
+
end
|
17
|
+
|
18
|
+
def timing(key, ms, sample_rate = 1)
|
19
|
+
send_data({ key => "#{ms}|ms" }, sample_rate)
|
20
|
+
end
|
21
|
+
|
22
|
+
def incr(key, sample_rate = 1)
|
23
|
+
incrby(key, 1, sample_rate)
|
24
|
+
end
|
25
|
+
|
26
|
+
def incrby(key, increment, sample_rate = 1)
|
27
|
+
send_data({ key => "#{increment}|c" }, sample_rate)
|
28
|
+
end
|
29
|
+
|
30
|
+
def decr(key, sample_rate = 1)
|
31
|
+
decrby(key, 1, sample_rate)
|
32
|
+
end
|
33
|
+
|
34
|
+
def decrby(key, decrement, sample_rate = 1)
|
35
|
+
incrby(key, -decrement, sample_rate)
|
36
|
+
end
|
37
|
+
|
38
|
+
def send_data(data, sample_rate = 1)
|
39
|
+
socket = UDPSocket.new
|
40
|
+
socket.bind("127.0.0.1", 0)
|
41
|
+
socket.connect(@hostname, @port)
|
42
|
+
data.each do |key, val|
|
43
|
+
val += "|@#{sample_rate}" if sample_rate != 1
|
44
|
+
socket.send "#{key}:#{val}", 0
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'statsd'
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe StatsD::Client do
|
4
|
+
describe "initialize" do
|
5
|
+
it "defaults to localhost:8125" do
|
6
|
+
client = described_class.new
|
7
|
+
client.hostname.should == "localhost"
|
8
|
+
client.port.should == 8125
|
9
|
+
end
|
10
|
+
|
11
|
+
it "initializes hostname and port" do
|
12
|
+
client = described_class.new(:hostname => "statsd.local", :port => 6000)
|
13
|
+
client.hostname.should == "statsd.local"
|
14
|
+
client.port.should == 6000
|
15
|
+
end
|
16
|
+
|
17
|
+
it "allows port to be specified as a string" do
|
18
|
+
client = described_class.new(:port => "6000")
|
19
|
+
client.port.should == 6000
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "send_data" do
|
24
|
+
describe "sending over socket" do
|
25
|
+
RSpec::Matchers.define :send_data do |expected|
|
26
|
+
match do |actual|
|
27
|
+
socket = UDPSocket.new
|
28
|
+
socket.bind("127.0.0.1", 9730)
|
29
|
+
actual.call
|
30
|
+
IO.select([socket])
|
31
|
+
req = socket.recvfrom_nonblock(100)
|
32
|
+
socket.close
|
33
|
+
req[0] == expected
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "sends single key and value" do
|
38
|
+
client = described_class.new(:port => 9730)
|
39
|
+
expect { client.send_data :hits => "1|c" }.to send_data "hits:1|c"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "socket connection" do
|
44
|
+
before :each do
|
45
|
+
@socket = double('socket')
|
46
|
+
[:bind, :connect].each { |m| @socket.stub m }
|
47
|
+
UDPSocket.stub(:new) { @socket }
|
48
|
+
@client = described_class.new(
|
49
|
+
:hostname => "statsd.local",
|
50
|
+
:port => 6000
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "binds to 127.0.0.1" do
|
55
|
+
@socket.should_receive(:bind).with("127.0.0.1", 0)
|
56
|
+
@client.send_data({})
|
57
|
+
end
|
58
|
+
|
59
|
+
it "connects to the client hostname and port" do
|
60
|
+
@socket.should_receive(:connect).with(
|
61
|
+
@client.hostname,
|
62
|
+
@client.port
|
63
|
+
)
|
64
|
+
@client.send_data({})
|
65
|
+
end
|
66
|
+
|
67
|
+
it "sends a single key and value" do
|
68
|
+
@socket.should_receive(:send).with("hits:1|c", 0)
|
69
|
+
@client.send_data :hits => "1|c"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "sends multiple keys and values" do
|
73
|
+
@socket.should_receive(:send).with("hits:1|c", 0)
|
74
|
+
@socket.should_receive(:send).with("downloads:1|c", 0)
|
75
|
+
@client.send_data :hits => "1|c", :downloads => "1|c"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "commands" do
|
81
|
+
before :each do
|
82
|
+
@client = described_class.new
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "incr" do
|
86
|
+
it "sends the increment" do
|
87
|
+
@client.should_receive(:send_data).with({ :hits => "1|c" }, 1)
|
88
|
+
@client.incr :hits
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "incrby" do
|
93
|
+
it "sends the specified increment value" do
|
94
|
+
@client.should_receive(:send_data).with({ :hits => "3|c" }, 1)
|
95
|
+
@client.incrby :hits, 3
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "decr" do
|
100
|
+
it "sends the decrement" do
|
101
|
+
@client.should_receive(:send_data).with({ :invites => "-1|c" }, 1)
|
102
|
+
@client.decr :invites
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "decrby" do
|
107
|
+
it "sends the specified decrement value" do
|
108
|
+
@client.should_receive(:send_data).with({ :tickets => "-4|c" }, 1)
|
109
|
+
@client.decrby :tickets, 4
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "timing" do
|
114
|
+
it "sends the timing" do
|
115
|
+
@client.should_receive(:send_data).with({ :archive => "230|ms" }, 1)
|
116
|
+
@client.timing :archive, 230
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "time" do
|
121
|
+
it "sends the time" do
|
122
|
+
@client.should_receive(:send_data).with({ :archive => "10|ms" }, 1)
|
123
|
+
@client.time(:archive) { sleep 0.01 }
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "sampling" do
|
129
|
+
before :each do
|
130
|
+
@client = described_class.new
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "incr" do
|
134
|
+
it "sends the sampleed increment" do
|
135
|
+
@client.should_receive(:send_data).with({ :hits => "1|c" }, 0.2)
|
136
|
+
@client.incr :hits, 0.2
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "incrby" do
|
141
|
+
it "sends the sampled increment" do
|
142
|
+
@client.should_receive(:send_data).with({ :hits => "3|c" }, 0.2)
|
143
|
+
@client.incrby :hits, 3, 0.2
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "decr" do
|
148
|
+
it "sends the sampled decrement" do
|
149
|
+
@client.should_receive(:send_data).with({ :invites => "-1|c" }, 0.5)
|
150
|
+
@client.decr :invites, 0.5
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "decrby" do
|
155
|
+
it "sends the sampled decrement" do
|
156
|
+
@client.should_receive(:send_data).with({ :tickets => "-4|c" }, 0.5)
|
157
|
+
@client.decrby :tickets, 4, 0.5
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "timing" do
|
162
|
+
it "sends the sampled timing" do
|
163
|
+
@client.should_receive(:send_data).with({ :archive => "230|ms" }, 0.1)
|
164
|
+
@client.timing :archive, 230, 0.1
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe "time" do
|
169
|
+
it "sends the sampled time" do
|
170
|
+
@client.should_receive(:send_data).with({ :archive => "10|ms" }, 0.1)
|
171
|
+
@client.time(:archive, 0.1) { sleep 0.01 }
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: statsd-rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Matt Duncan
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-03-21 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: " A ruby client for Etsy's StatsD statistics aggregator.\n"
|
23
|
+
email: matt@mattduncan.org
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- README.md
|
32
|
+
- Rakefile
|
33
|
+
- LICENSE
|
34
|
+
- lib/statsd/client.rb
|
35
|
+
- lib/statsd/version.rb
|
36
|
+
- lib/statsd.rb
|
37
|
+
- spec/spec_helper.rb
|
38
|
+
- spec/statsd/client_spec.rb
|
39
|
+
has_rdoc: true
|
40
|
+
homepage: http://github.com/mrduncan/statsd
|
41
|
+
licenses: []
|
42
|
+
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
hash: 3
|
54
|
+
segments:
|
55
|
+
- 0
|
56
|
+
version: "0"
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
hash: 3
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
version: "0"
|
66
|
+
requirements: []
|
67
|
+
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.6.2
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: A ruby client for StatsD.
|
73
|
+
test_files: []
|
74
|
+
|