lookout-statsd 1.0.0 → 2.0.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.
- checksums.yaml +4 -4
- data/.travis.yml +14 -0
- data/README.md +22 -1
- data/lib/statsd.rb +114 -5
- data/spec/statsd_spec.rb +57 -1
- data/statsd.gemspec +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 09edd7854e30fe524a21a82dd325487e96c83a3b
|
4
|
+
data.tar.gz: f7d047db68333414a84ec0bbdce59f0fcde041b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53190cf6ac482c34bde75b18f727f1b74904a5ef1bb837c3299e487bea532d164114a9625c5185254379c6a97ef8fec794d83e3fab89e0a10d4068e87909f0bd
|
7
|
+
data.tar.gz: 36d9ce3ed7906da7d80226d9978a03873fe9502744eb234a3a73adbfe81af75ba159694c174566d5b75e3264014161ebbe13d08428dcf9aa1749a7441668bf5a
|
data/.travis.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- jruby
|
4
|
+
- 2.1
|
5
|
+
- 1.9.3
|
6
|
+
deploy:
|
7
|
+
provider: rubygems
|
8
|
+
api_key: 701b3f137a894afa3dca9390da8b3afe
|
9
|
+
gem: lookout-statsd
|
10
|
+
on:
|
11
|
+
repo: lookout/statsd
|
12
|
+
install:
|
13
|
+
- gem install bundler
|
14
|
+
- bundle install --jobs=3 --retry=3
|
data/README.md
CHANGED
@@ -11,7 +11,7 @@ In your client code:
|
|
11
11
|
|
12
12
|
require 'rubygems'
|
13
13
|
require 'statsd'
|
14
|
-
STATSD = Statsd::Client.new('localhost',8125)
|
14
|
+
STATSD = Statsd::Client.new(:host => 'localhost', :port => 8125)
|
15
15
|
|
16
16
|
STATSD.increment('some_counter') # basic incrementing
|
17
17
|
STATSD.increment('system.nested_counter', 0.1) # incrementing with sampling (10%)
|
@@ -22,6 +22,27 @@ In your client code:
|
|
22
22
|
STATSD.timing('some_job_time', 20) # reporting job that took 20ms
|
23
23
|
STATSD.timing('some_job_time', 20, 0.05) # reporting job that took 20ms with sampling (5% sampling)
|
24
24
|
|
25
|
+
There is an option for reduced DNS lookups, you can specify an additional
|
26
|
+
constructor option `:resolve_always` and set it to `false`. By default, the
|
27
|
+
client will always resolve the address unless `host` is set to 'localhost' or
|
28
|
+
'127.0.0.1'.
|
29
|
+
|
30
|
+
require 'rubygems'
|
31
|
+
require 'statsd'
|
32
|
+
|
33
|
+
STATSD = Statsd::Client.new(:host => 'specialstats.host.example',
|
34
|
+
:port => '8125',
|
35
|
+
:resolve_always => false)
|
36
|
+
|
37
|
+
STATSD.increment('some_counter') # basic incrementing
|
38
|
+
|
39
|
+
#### Note about thread-safety
|
40
|
+
|
41
|
+
Since class variables and instance variables are not thread-safe on
|
42
|
+
initialization, there is a potential for multiple UDP sockets being opened upon
|
43
|
+
if you are using a truly multithreaded ruby, i.e. JRuby. Make sure to take that
|
44
|
+
in to account when initializing this library.
|
45
|
+
|
25
46
|
Guts
|
26
47
|
----
|
27
48
|
|
data/lib/statsd.rb
CHANGED
@@ -15,12 +15,17 @@ module Statsd
|
|
15
15
|
end
|
16
16
|
|
17
17
|
class Client
|
18
|
-
attr_accessor :host, :port, :prefix
|
18
|
+
attr_accessor :host, :port, :prefix, :resolve_always, :batch_size
|
19
19
|
|
20
20
|
def initialize(opts={})
|
21
21
|
@host = opts[:host] || 'localhost'
|
22
22
|
@port = opts[:port] || 8125
|
23
|
+
@batch_size = opts[:batch_size] || 10
|
23
24
|
@prefix = opts[:prefix]
|
25
|
+
# set resolve_always to true unless localhost or specified
|
26
|
+
@resolve_always = opts.fetch(:resolve_always, !is_localhost?)
|
27
|
+
@socket = UDPSocket.new
|
28
|
+
@send_data = send_method
|
24
29
|
end
|
25
30
|
|
26
31
|
def host_ip_addr
|
@@ -77,6 +82,22 @@ module Statsd
|
|
77
82
|
})
|
78
83
|
end
|
79
84
|
|
85
|
+
# Creates and yields a Batch that can be used to batch instrument reports into
|
86
|
+
# larger packets. Batches are sent either when the packet is "full" (defined
|
87
|
+
# by batch_size), or when the block completes, whichever is the sooner.
|
88
|
+
#
|
89
|
+
# Good artists copy https://github.com/reinh/statsd/blob/master/lib/statsd.rb#L410
|
90
|
+
#
|
91
|
+
# @yield [Batch] a statsd subclass that collects and batches instruments
|
92
|
+
# @example Batch two instument operations:
|
93
|
+
# $statsd.batch do |batch|
|
94
|
+
# batch.increment 'sys.requests'
|
95
|
+
# batch.gauge('user.count', User.count)
|
96
|
+
# end
|
97
|
+
def batch(&block)
|
98
|
+
Batch.new(self).easy(&block)
|
99
|
+
end
|
100
|
+
|
80
101
|
private
|
81
102
|
|
82
103
|
def send_stats(data, sample_rate = 1)
|
@@ -98,17 +119,105 @@ module Statsd
|
|
98
119
|
raise "host and port must be set" unless host && port
|
99
120
|
|
100
121
|
begin
|
101
|
-
sock = UDPSocket.new
|
102
122
|
data.each do |d|
|
103
|
-
|
123
|
+
@send_data[d]
|
104
124
|
end
|
105
125
|
rescue # silent but deadly
|
106
|
-
ensure
|
107
|
-
sock.close
|
108
126
|
end
|
109
127
|
true
|
110
128
|
end
|
111
129
|
|
130
|
+
def socket_connect!
|
131
|
+
@socket.connect(@host, @port)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Curries the send based on if we need to lookup dns every time we send
|
135
|
+
def send_method
|
136
|
+
if resolve_always
|
137
|
+
lambda {|data| @socket.send(data, 0, @host, @port)}
|
138
|
+
else
|
139
|
+
socket_connect!
|
140
|
+
lambda {|data| @socket.send(data, 0)}
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def is_localhost?
|
145
|
+
@host == 'localhost' || @host == '127.0.0.1'
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Some more unabashed borrowing: https://github.com/reinh/statsd/blob/master/lib/statsd.rb#L410
|
150
|
+
# The big difference between this implementation and reinh's is that we don't support namespaces,
|
151
|
+
# and we have a bunch of hacks for introducing prefixes to the namespaces we're acting against.
|
152
|
+
# = Batch: A batching statsd proxy
|
153
|
+
#
|
154
|
+
# @example Batch a set of instruments using Batch and manual flush:
|
155
|
+
# $statsd = Statsd.new 'localhost', 8125
|
156
|
+
# batch = Statsd::Batch.new($statsd)
|
157
|
+
# batch.increment 'garets'
|
158
|
+
# batch.timing 'glork', 320
|
159
|
+
# batch.gauge 'bork', 100
|
160
|
+
# batch.flush
|
161
|
+
#
|
162
|
+
# Batch is a subclass of Statsd, but with a constructor that proxies to a
|
163
|
+
# normal Statsd instance. It has it's own batch_size parameters
|
164
|
+
# (that inherit defaults from the supplied Statsd instance). It is recommended
|
165
|
+
# that some care is taken if setting very large batch sizes. If the batch size
|
166
|
+
# exceeds the allowed packet size for UDP on your network, communication
|
167
|
+
# troubles may occur and data will be lost.
|
168
|
+
class Batch < Statsd::Client
|
169
|
+
|
170
|
+
extend Forwardable
|
171
|
+
def_delegators :@statsd,
|
172
|
+
:host, :host=,
|
173
|
+
:port, :port=,
|
174
|
+
:prefix,
|
175
|
+
:postfix,
|
176
|
+
:delimiter, :delimiter=
|
177
|
+
|
178
|
+
attr_accessor :batch_size
|
179
|
+
|
180
|
+
# @param [Statsd] requires a configured Statsd instance
|
181
|
+
def initialize(statsd)
|
182
|
+
@statsd = statsd
|
183
|
+
@batch_size = statsd.batch_size
|
184
|
+
@backlog = []
|
185
|
+
@send_data = send_method
|
186
|
+
end
|
187
|
+
|
188
|
+
# @yields [Batch] yields itself
|
189
|
+
#
|
190
|
+
# A convenience method to ensure that data is not lost in the event of an
|
191
|
+
# exception being thrown. Batches will be transmitted on the parent socket
|
192
|
+
# as soon as the batch is full, and when the block finishes.
|
193
|
+
def easy
|
194
|
+
yield self
|
195
|
+
ensure
|
196
|
+
flush
|
197
|
+
end
|
198
|
+
|
199
|
+
def flush
|
200
|
+
unless @backlog.empty?
|
201
|
+
@statsd.send_data @backlog.join("\n")
|
202
|
+
@backlog.clear
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def send_batch_data(message)
|
207
|
+
@backlog << message
|
208
|
+
if @backlog.size >= @batch_size
|
209
|
+
flush
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def send_method
|
214
|
+
lambda { |data|
|
215
|
+
@backlog << data
|
216
|
+
if @backlog.size >= @batch_size
|
217
|
+
flush
|
218
|
+
end
|
219
|
+
}
|
220
|
+
end
|
112
221
|
end
|
113
222
|
|
114
223
|
module Rails
|
data/spec/statsd_spec.rb
CHANGED
@@ -55,6 +55,48 @@ describe Statsd::Client do
|
|
55
55
|
c = Statsd::Client.new(:prefix => prefix)
|
56
56
|
c.prefix.should match(prefix)
|
57
57
|
end
|
58
|
+
|
59
|
+
it 'should accept a :resolve_always keyword argument' do
|
60
|
+
lookup = false
|
61
|
+
c = Statsd::Client.new(:resolve_always => lookup)
|
62
|
+
c.resolve_always.should be(lookup)
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when :resolve_always is not specified' do
|
66
|
+
|
67
|
+
context 'when host is localhost or 127.0.0.1' do
|
68
|
+
it ':resolve_always should default to false' do
|
69
|
+
c = Statsd::Client.new(:host => 'localhost')
|
70
|
+
c.resolve_always.should be(false)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'when host is not local' do
|
75
|
+
it ':resolve_always should default to true' do
|
76
|
+
c = Statsd::Client.new(:host => 'statsd.example.example')
|
77
|
+
c.resolve_always.should be(true)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#send_stats' do
|
86
|
+
|
87
|
+
it 'should use cached resolve address when :resolve_always is false' do
|
88
|
+
c = Statsd::Client.new(:resolve_always => false)
|
89
|
+
sock = c.instance_variable_get(:@socket)
|
90
|
+
expect(sock).to receive(:send).with(anything, 0)
|
91
|
+
c.increment('foo')
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should always resolve address when :resolve_always is true' do
|
95
|
+
c = Statsd::Client.new(:resolve_always => true)
|
96
|
+
sock = c.instance_variable_get(:@socket)
|
97
|
+
expect(sock).to receive(:send).with(anything, 0, c.host, c.port)
|
98
|
+
c.increment('foo')
|
99
|
+
end
|
58
100
|
end
|
59
101
|
|
60
102
|
describe '#timing' do
|
@@ -148,4 +190,18 @@ describe Statsd::Client do
|
|
148
190
|
c.gauge('foo' => 1)
|
149
191
|
end
|
150
192
|
end
|
151
|
-
|
193
|
+
|
194
|
+
describe '#batch' do
|
195
|
+
let(:c) { Statsd::Client.new }
|
196
|
+
subject { c.batch { |b| b.increment('foo'); b.increment('bar'); } }
|
197
|
+
|
198
|
+
it 'should take a block and put increments into a buffer' do
|
199
|
+
Statsd::Batch.any_instance do |b|
|
200
|
+
b.backlog.should_receive(:<<).exactly.twice
|
201
|
+
end
|
202
|
+
Statsd::Batch.any_instance.should_receive(:flush).and_call_original
|
203
|
+
c.should_receive(:send_data).once
|
204
|
+
subject
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
data/statsd.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lookout-statsd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- R. Tyler Croy
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2016-05-16 00:00:00.000000000 Z
|
14
14
|
dependencies: []
|
15
15
|
description: A simple ruby statsd client.
|
16
16
|
email:
|
@@ -20,6 +20,7 @@ extensions: []
|
|
20
20
|
extra_rdoc_files: []
|
21
21
|
files:
|
22
22
|
- ".gitignore"
|
23
|
+
- ".travis.yml"
|
23
24
|
- Gemfile
|
24
25
|
- Guardfile
|
25
26
|
- README.md
|
@@ -50,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
50
51
|
version: 1.3.6
|
51
52
|
requirements: []
|
52
53
|
rubyforge_project:
|
53
|
-
rubygems_version: 2.4.
|
54
|
+
rubygems_version: 2.4.6
|
54
55
|
signing_key:
|
55
56
|
specification_version: 4
|
56
57
|
summary: Ruby statsd client.
|