statsd-ruby 1.4.0 → 1.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 91ca6f8d710ca7a0a0fadccd48293a804e652c0d
4
- data.tar.gz: 24f9b37eb4a6fa239d1e80073ef3879f09f85909
2
+ SHA256:
3
+ metadata.gz: 0edd467226454eea7a63a7ed08e3468ac48a2d7438fdf8d291ab266a781c128b
4
+ data.tar.gz: 82f88de7bf7738e974a8d9f2d70f57f039d31d7f69f9b98c359b7d5c7970f93c
5
5
  SHA512:
6
- metadata.gz: 505b5f1250aeb05e0c23a8b6d9822d4ca331db53504f906ce19c9d2802bb8d5d48f8bdc1fc0aa1170ef9b9b6f31d9eb838161db17271a84325a503adbaa03bda
7
- data.tar.gz: ac00437d8f1e752db7989e7adecf174db970f27181312a19ad47216504f38a2cb0af4f51830a130454fa6bc3ad82e052ba7c495a9dc709b1878a82b762bd0ff0
6
+ metadata.gz: 3520cc824d180d7304fa883fefa945d3f785d560f313c328fed8f28e4d799728c6ab61cd6b9a855d8023f644f2d328f7f6626e0af7770d8e83d99b2bb0e7a2f8
7
+ data.tar.gz: f0bc2ade747bee51cca11128a6d6ce21491b13354f519f582f90c94cd09ce1ee26372b52945c8d369dfc5160194cfd967644254350b0dd1567ff28cd64de8206
@@ -0,0 +1,34 @@
1
+ name: Ruby
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ strategy:
8
+ matrix:
9
+ os:
10
+ - ubuntu
11
+ - macos
12
+ ruby:
13
+ - 2.4
14
+ - 2.5
15
+ - 2.6
16
+ # TODO: - 2.7
17
+ # TODO: jruby, rbx
18
+
19
+ runs-on: ${{ matrix.os }}-latest
20
+
21
+ steps:
22
+ - uses: actions/checkout@v1
23
+
24
+ - name: Set up Ruby
25
+ uses: actions/setup-ruby@v1
26
+ with:
27
+ ruby-version: ${{ matrix.ruby }}
28
+ architecture: x64
29
+
30
+ - name: Build and test with Rake
31
+ run: |
32
+ gem install bundler
33
+ bundle install
34
+ bundle exec rake
@@ -1,4 +1,4 @@
1
- = statsd-ruby {<img src="https://secure.travis-ci.org/reinh/statsd.png" />}[http://travis-ci.org/reinh/statsd]
1
+ = statsd-ruby Travis: {<img src="https://secure.travis-ci.org/reinh/statsd.svg" />}[http://travis-ci.org/reinh/statsd] CI: {<img src="https://github.com/reinh/statsd/workflows/Ruby/badge.svg" />}[https://github.com/reinh/statsd/actions?query=workflow%3ARuby]
2
2
 
3
3
  A Ruby client for {StatsD}[https://github.com/etsy/statsd]
4
4
 
@@ -33,7 +33,7 @@ Run the specs with <tt>rake spec</tt>
33
33
 
34
34
  = Performance
35
35
 
36
- * A short note about DNS: If you use a dns name for the host option, then you will want to use a local caching dns service for optimial performance (e.g. nscd).
36
+ * A short note about DNS: If you use a dns name for the host option, then you will want to use a local caching dns service for optimal performance (e.g. nscd).
37
37
 
38
38
  = Extensions / Libraries / Extra Docs
39
39
 
@@ -2,6 +2,8 @@ require 'socket'
2
2
  require 'forwardable'
3
3
  require 'json'
4
4
 
5
+ require 'statsd/monotonic_time'
6
+
5
7
  # = Statsd: A Statsd client (https://github.com/etsy/statsd)
6
8
  #
7
9
  # @example Set up a global Statsd client for a server on localhost:8125
@@ -53,18 +55,20 @@ class Statsd
53
55
  :postfix,
54
56
  :delimiter, :delimiter=
55
57
 
56
- attr_accessor :batch_size, :batch_byte_size
58
+ attr_accessor :batch_size, :batch_byte_size, :flush_interval
57
59
 
58
- # @param [Statsd] requires a configured Statsd instance
60
+ # @param [Statsd] statsd requires a configured Statsd instance
59
61
  def initialize(statsd)
60
62
  @statsd = statsd
61
63
  @batch_size = statsd.batch_size
62
64
  @batch_byte_size = statsd.batch_byte_size
65
+ @flush_interval = statsd.flush_interval
63
66
  @backlog = []
64
67
  @backlog_bytesize = 0
68
+ @last_flush = Time.now
65
69
  end
66
70
 
67
- # @yields [Batch] yields itself
71
+ # @yield [Batch] yields itself
68
72
  #
69
73
  # A convenience method to ensure that data is not lost in the event of an
70
74
  # exception being thrown. Batches will be transmitted on the parent socket
@@ -80,6 +84,7 @@ class Statsd
80
84
  @statsd.send_to_socket @backlog.join("\n")
81
85
  @backlog.clear
82
86
  @backlog_bytesize = 0
87
+ @last_flush = Time.now
83
88
  end
84
89
  end
85
90
 
@@ -89,7 +94,8 @@ class Statsd
89
94
  # this message wouldn't fit; flush the queue. note that we don't have
90
95
  # to do this for message based flushing, because we're incrementing by
91
96
  # one, so the post-queue check will always catch it
92
- if (@batch_byte_size && @backlog_bytesize + message.bytesize + 1 > @batch_byte_size)
97
+ if (@batch_byte_size && @backlog_bytesize + message.bytesize + 1 > @batch_byte_size) ||
98
+ (@flush_interval && last_flush_seconds_ago >= @flush_interval)
93
99
  flush
94
100
  end
95
101
  @backlog << message
@@ -103,6 +109,10 @@ class Statsd
103
109
  end
104
110
  end
105
111
 
112
+ def last_flush_seconds_ago
113
+ Time.now - @last_flush
114
+ end
115
+
106
116
  end
107
117
 
108
118
  class Admin
@@ -264,6 +274,9 @@ class Statsd
264
274
  # The default batch size, in bytes, for new batches (default: default nil; use batch_size)
265
275
  attr_accessor :batch_byte_size
266
276
 
277
+ # The flush interval, in seconds, for new batches (default: nil)
278
+ attr_accessor :flush_interval
279
+
267
280
  # a postfix to append to all metrics
268
281
  attr_reader :postfix
269
282
 
@@ -277,7 +290,7 @@ class Statsd
277
290
 
278
291
  # @param [String] host your statsd host
279
292
  # @param [Integer] port your statsd port
280
- # @param [Symbol] :tcp for TCP, :udp or any other value for UDP
293
+ # @param [Symbol] protocol :tcp for TCP, :udp or any other value for UDP
281
294
  def initialize(host = '127.0.0.1', port = 8125, protocol = :udp)
282
295
  @host = host || '127.0.0.1'
283
296
  @port = port || 8125
@@ -285,6 +298,7 @@ class Statsd
285
298
  @prefix = nil
286
299
  @batch_size = 10
287
300
  @batch_byte_size = nil
301
+ @flush_interval = nil
288
302
  @postfix = nil
289
303
  @socket = nil
290
304
  @protocol = protocol || :udp
@@ -408,10 +422,10 @@ class Statsd
408
422
  # @example Report the time (in ms) taken to activate an account
409
423
  # $statsd.time('account.activate') { @account.activate! }
410
424
  def time(stat, sample_rate=1)
411
- start = Time.now
425
+ start = MonotonicTime.time_in_ms
412
426
  result = yield
413
427
  ensure
414
- timing(stat, ((Time.now - start) * 1000).round, sample_rate)
428
+ timing(stat, (MonotonicTime.time_in_ms - start).round, sample_rate)
415
429
  result
416
430
  end
417
431
 
@@ -462,15 +476,15 @@ class Statsd
462
476
  # send(2) is atomic, however, in stream cases (TCP) the socket is left
463
477
  # in an inconsistent state if a partial message is written. If that case
464
478
  # occurs, the socket is closed down and we retry on a new socket.
465
- n = socket.write(message)
466
-
479
+ message = @protocol == :tcp ? message + "\n" : message
480
+ n = socket.write(message) rescue (err = $!; 0)
467
481
  if n == message.length
468
482
  break
469
483
  end
470
484
 
471
485
  connect
472
486
  retries += 1
473
- raise "statsd: Failed to send after #{retries} attempts" if retries >= 5
487
+ raise (err || "statsd: Failed to send after #{retries} attempts") if retries >= 5
474
488
  end
475
489
  n
476
490
  rescue => boom
@@ -0,0 +1,35 @@
1
+ class Statsd
2
+ # = MonotonicTime: a helper for getting monotonic time
3
+ #
4
+ # @example
5
+ # MonotonicTime.time_in_ms #=> 287138801.144576
6
+
7
+ # MonotonicTime guarantees that the time is strictly linearly
8
+ # increasing (unlike realtime).
9
+ # @see http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html
10
+ module MonotonicTime
11
+ class << self
12
+ # @return [Integer] current monotonic time in milliseconds
13
+ def time_in_ms
14
+ time_in_nanoseconds / (10.0 ** 6)
15
+ end
16
+
17
+ private
18
+
19
+ if defined?(Process::CLOCK_MONOTONIC)
20
+ def time_in_nanoseconds
21
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)
22
+ end
23
+ elsif RUBY_ENGINE == 'jruby'
24
+ def time_in_nanoseconds
25
+ java.lang.System.nanoTime
26
+ end
27
+ else
28
+ def time_in_nanoseconds
29
+ t = Time.now
30
+ t.to_i * (10 ** 9) + t.nsec
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -26,14 +26,14 @@ describe Statsd::Admin do
26
26
 
27
27
  describe "#initialize" do
28
28
  it "should set the host and port" do
29
- @admin.host.must_equal 'localhost'
30
- @admin.port.must_equal 1234
29
+ _(@admin.host).must_equal 'localhost'
30
+ _(@admin.port).must_equal 1234
31
31
  end
32
32
 
33
33
  it "should default the host to 127.0.0.1 and port to 8126" do
34
34
  statsd = Statsd::Admin.new
35
- statsd.host.must_equal '127.0.0.1'
36
- statsd.port.must_equal 8126
35
+ _(statsd.host).must_equal '127.0.0.1'
36
+ _(statsd.port).must_equal 8126
37
37
  end
38
38
  end
39
39
 
@@ -41,23 +41,23 @@ describe Statsd::Admin do
41
41
  it "should set host and port" do
42
42
  @admin.host = '1.2.3.4'
43
43
  @admin.port = 5678
44
- @admin.host.must_equal '1.2.3.4'
45
- @admin.port.must_equal 5678
44
+ _(@admin.host).must_equal '1.2.3.4'
45
+ _(@admin.port).must_equal 5678
46
46
  end
47
47
 
48
48
  it "should not resolve hostnames to IPs" do
49
49
  @admin.host = 'localhost'
50
- @admin.host.must_equal 'localhost'
50
+ _(@admin.host).must_equal 'localhost'
51
51
  end
52
52
 
53
53
  it "should set nil host to default" do
54
54
  @admin.host = nil
55
- @admin.host.must_equal '127.0.0.1'
55
+ _(@admin.host).must_equal '127.0.0.1'
56
56
  end
57
57
 
58
58
  it "should set nil port to default" do
59
59
  @admin.port = nil
60
- @admin.port.must_equal 8126
60
+ _(@admin.port).must_equal 8126
61
61
  end
62
62
  end
63
63
 
@@ -71,9 +71,9 @@ describe Statsd::Admin do
71
71
  @socket.write line
72
72
  end
73
73
  result = @admin.send action.to_sym
74
- result.must_be_kind_of Hash
75
- result.size.must_equal 3
76
- @socket.readline.must_equal "#{action}\n"
74
+ _(result).must_be_kind_of Hash
75
+ _(result.size).must_equal 3
76
+ _(@socket.readline).must_equal "#{action}\n"
77
77
  end
78
78
  end
79
79
 
@@ -86,9 +86,9 @@ describe Statsd::Admin do
86
86
  @socket.write line
87
87
  end
88
88
  result = @admin.send "del#{action}", "foo.*"
89
- result.must_be_kind_of Array
90
- result.size.must_equal 3
91
- @socket.readline.must_equal "del#{action} foo.*\n"
89
+ _(result).must_be_kind_of Array
90
+ _(result.size).must_equal 3
91
+ _(@socket.readline).must_equal "del#{action} foo.*\n"
92
92
  end
93
93
  end
94
94
  end
@@ -99,9 +99,9 @@ describe Statsd::Admin do
99
99
  @socket.write line
100
100
  end
101
101
  result = @admin.stats
102
- result.must_be_kind_of Hash
103
- result["whatever"].must_equal 0
104
- @socket.readline.must_equal "stats\n"
102
+ _(result).must_be_kind_of Hash
103
+ _(result["whatever"]).must_equal 0
104
+ _(@socket.readline).must_equal "stats\n"
105
105
  end
106
106
  end
107
107
 
@@ -109,7 +109,7 @@ describe Statsd::Admin do
109
109
  it "should reconnect" do
110
110
  c = $connect_count
111
111
  @admin.connect
112
- ($connect_count - c).must_equal 1
112
+ _(($connect_count - c)).must_equal 1
113
113
  end
114
114
  end
115
115
  end
@@ -26,18 +26,18 @@ describe Statsd do
26
26
 
27
27
  describe "#initialize" do
28
28
  it "should set the host and port" do
29
- @statsd.host.must_equal 'localhost'
30
- @statsd.port.must_equal 1234
29
+ _(@statsd.host).must_equal 'localhost'
30
+ _(@statsd.port).must_equal 1234
31
31
  end
32
32
 
33
33
  it "should default the host to 127.0.0.1 and port to 8125" do
34
34
  statsd = Statsd.new
35
- statsd.host.must_equal '127.0.0.1'
36
- statsd.port.must_equal 8125
35
+ _(statsd.host).must_equal '127.0.0.1'
36
+ _(statsd.port).must_equal 8125
37
37
  end
38
38
 
39
39
  it "should set delimiter to period by default" do
40
- @statsd.delimiter.must_equal "."
40
+ _(@statsd.delimiter).must_equal "."
41
41
  end
42
42
  end
43
43
 
@@ -45,54 +45,54 @@ describe Statsd do
45
45
  it "should set host and port" do
46
46
  @statsd.host = '1.2.3.4'
47
47
  @statsd.port = 5678
48
- @statsd.host.must_equal '1.2.3.4'
49
- @statsd.port.must_equal 5678
48
+ _(@statsd.host).must_equal '1.2.3.4'
49
+ _(@statsd.port).must_equal 5678
50
50
  end
51
51
 
52
52
  it "should not resolve hostnames to IPs" do
53
53
  @statsd.host = 'localhost'
54
- @statsd.host.must_equal 'localhost'
54
+ _(@statsd.host).must_equal 'localhost'
55
55
  end
56
56
 
57
57
  it "should set nil host to default" do
58
58
  @statsd.host = nil
59
- @statsd.host.must_equal '127.0.0.1'
59
+ _(@statsd.host).must_equal '127.0.0.1'
60
60
  end
61
61
 
62
62
  it "should set nil port to default" do
63
63
  @statsd.port = nil
64
- @statsd.port.must_equal 8125
64
+ _(@statsd.port).must_equal 8125
65
65
  end
66
66
 
67
67
  it "should allow an IPv6 address" do
68
68
  @statsd.host = '::1'
69
- @statsd.host.must_equal '::1'
69
+ _(@statsd.host).must_equal '::1'
70
70
  end
71
71
  end
72
72
 
73
- describe "#delimiter" do
73
+ describe "#delimiter" do
74
74
  it "should set delimiter" do
75
75
  @statsd.delimiter = "-"
76
- @statsd.delimiter.must_equal "-"
76
+ _(@statsd.delimiter).must_equal "-"
77
77
  end
78
-
78
+
79
79
  it "should set default to period if not given a value" do
80
80
  @statsd.delimiter = nil
81
- @statsd.delimiter.must_equal "."
81
+ _(@statsd.delimiter).must_equal "."
82
82
  end
83
83
  end
84
84
 
85
85
  describe "#increment" do
86
86
  it "should format the message according to the statsd spec" do
87
87
  @statsd.increment('foobar')
88
- @socket.recv.must_equal ['foobar:1|c']
88
+ _(@socket.recv).must_equal ['foobar:1|c']
89
89
  end
90
90
 
91
91
  describe "with a sample rate" do
92
92
  before { class << @statsd; def rand; 0; end; end } # ensure delivery
93
93
  it "should format the message according to the statsd spec" do
94
94
  @statsd.increment('foobar', 0.5)
95
- @socket.recv.must_equal ['foobar:1|c|@0.5']
95
+ _(@socket.recv).must_equal ['foobar:1|c|@0.5']
96
96
  end
97
97
  end
98
98
  end
@@ -100,14 +100,14 @@ describe Statsd do
100
100
  describe "#decrement" do
101
101
  it "should format the message according to the statsd spec" do
102
102
  @statsd.decrement('foobar')
103
- @socket.recv.must_equal ['foobar:-1|c']
103
+ _(@socket.recv).must_equal ['foobar:-1|c']
104
104
  end
105
105
 
106
106
  describe "with a sample rate" do
107
107
  before { class << @statsd; def rand; 0; end; end } # ensure delivery
108
108
  it "should format the message according to the statsd spec" do
109
109
  @statsd.decrement('foobar', 0.5)
110
- @socket.recv.must_equal ['foobar:-1|c|@0.5']
110
+ _(@socket.recv).must_equal ['foobar:-1|c|@0.5']
111
111
  end
112
112
  end
113
113
  end
@@ -115,16 +115,16 @@ describe Statsd do
115
115
  describe "#gauge" do
116
116
  it "should send a message with a 'g' type, per the nearbuy fork" do
117
117
  @statsd.gauge('begrutten-suffusion', 536)
118
- @socket.recv.must_equal ['begrutten-suffusion:536|g']
118
+ _(@socket.recv).must_equal ['begrutten-suffusion:536|g']
119
119
  @statsd.gauge('begrutten-suffusion', -107.3)
120
- @socket.recv.must_equal ['begrutten-suffusion:-107.3|g']
120
+ _(@socket.recv).must_equal ['begrutten-suffusion:-107.3|g']
121
121
  end
122
122
 
123
123
  describe "with a sample rate" do
124
124
  before { class << @statsd; def rand; 0; end; end } # ensure delivery
125
125
  it "should format the message according to the statsd spec" do
126
126
  @statsd.gauge('begrutten-suffusion', 536, 0.1)
127
- @socket.recv.must_equal ['begrutten-suffusion:536|g|@0.1']
127
+ _(@socket.recv).must_equal ['begrutten-suffusion:536|g|@0.1']
128
128
  end
129
129
  end
130
130
  end
@@ -132,14 +132,14 @@ describe Statsd do
132
132
  describe "#timing" do
133
133
  it "should format the message according to the statsd spec" do
134
134
  @statsd.timing('foobar', 500)
135
- @socket.recv.must_equal ['foobar:500|ms']
135
+ _(@socket.recv).must_equal ['foobar:500|ms']
136
136
  end
137
137
 
138
138
  describe "with a sample rate" do
139
139
  before { class << @statsd; def rand; 0; end; end } # ensure delivery
140
140
  it "should format the message according to the statsd spec" do
141
141
  @statsd.timing('foobar', 500, 0.5)
142
- @socket.recv.must_equal ['foobar:500|ms|@0.5']
142
+ _(@socket.recv).must_equal ['foobar:500|ms|@0.5']
143
143
  end
144
144
  end
145
145
  end
@@ -147,14 +147,14 @@ describe Statsd do
147
147
  describe "#set" do
148
148
  it "should format the message according to the statsd spec" do
149
149
  @statsd.set('foobar', 765)
150
- @socket.recv.must_equal ['foobar:765|s']
150
+ _(@socket.recv).must_equal ['foobar:765|s']
151
151
  end
152
152
 
153
153
  describe "with a sample rate" do
154
154
  before { class << @statsd; def rand; 0; end; end } # ensure delivery
155
155
  it "should format the message according to the statsd spec" do
156
156
  @statsd.set('foobar', 500, 0.5)
157
- @socket.recv.must_equal ['foobar:500|s|@0.5']
157
+ _(@socket.recv).must_equal ['foobar:500|s|@0.5']
158
158
  end
159
159
  end
160
160
  end
@@ -162,23 +162,23 @@ describe Statsd do
162
162
  describe "#time" do
163
163
  it "should format the message according to the statsd spec" do
164
164
  @statsd.time('foobar') { 'test' }
165
- @socket.recv.must_equal ['foobar:0|ms']
165
+ _(@socket.recv).must_equal ['foobar:0|ms']
166
166
  end
167
167
 
168
168
  it "should return the result of the block" do
169
169
  result = @statsd.time('foobar') { 'test' }
170
- result.must_equal 'test'
170
+ _(result).must_equal 'test'
171
171
  end
172
172
 
173
173
  describe "when given a block with an explicit return" do
174
174
  it "should format the message according to the statsd spec" do
175
175
  lambda { @statsd.time('foobar') { return 'test' } }.call
176
- @socket.recv.must_equal ['foobar:0|ms']
176
+ _(@socket.recv).must_equal ['foobar:0|ms']
177
177
  end
178
178
 
179
179
  it "should return the result of the block" do
180
180
  result = lambda { @statsd.time('foobar') { return 'test' } }.call
181
- result.must_equal 'test'
181
+ _(result).must_equal 'test'
182
182
  end
183
183
  end
184
184
 
@@ -187,7 +187,7 @@ describe Statsd do
187
187
 
188
188
  it "should format the message according to the statsd spec" do
189
189
  @statsd.time('foobar', 0.5) { 'test' }
190
- @socket.recv.must_equal ['foobar:0|ms|@0.5']
190
+ _(@socket.recv).must_equal ['foobar:0|ms|@0.5']
191
191
  end
192
192
  end
193
193
  end
@@ -197,7 +197,7 @@ describe Statsd do
197
197
  before { class << @statsd; def rand; raise end; end }
198
198
  it "should send" do
199
199
  @statsd.timing('foobar', 500, 1)
200
- @socket.recv.must_equal ['foobar:500|ms']
200
+ _(@socket.recv).must_equal ['foobar:500|ms']
201
201
  end
202
202
  end
203
203
 
@@ -205,7 +205,7 @@ describe Statsd do
205
205
  before { class << @statsd; def rand; 0; end; end } # ensure delivery
206
206
  it "should send" do
207
207
  @statsd.timing('foobar', 500, 0.5)
208
- @socket.recv.must_equal ['foobar:500|ms|@0.5']
208
+ _(@socket.recv).must_equal ['foobar:500|ms|@0.5']
209
209
  end
210
210
  end
211
211
 
@@ -220,7 +220,7 @@ describe Statsd do
220
220
  before { class << @statsd; def rand; 0; end; end } # ensure delivery
221
221
  it "should send" do
222
222
  @statsd.timing('foobar', 500, 0.5)
223
- @socket.recv.must_equal ['foobar:500|ms|@0.5']
223
+ _(@socket.recv).must_equal ['foobar:500|ms|@0.5']
224
224
  end
225
225
  end
226
226
  end
@@ -230,22 +230,22 @@ describe Statsd do
230
230
 
231
231
  it "should add namespace to increment" do
232
232
  @statsd.increment('foobar')
233
- @socket.recv.must_equal ['service.foobar:1|c']
233
+ _(@socket.recv).must_equal ['service.foobar:1|c']
234
234
  end
235
235
 
236
236
  it "should add namespace to decrement" do
237
237
  @statsd.decrement('foobar')
238
- @socket.recv.must_equal ['service.foobar:-1|c']
238
+ _(@socket.recv).must_equal ['service.foobar:-1|c']
239
239
  end
240
240
 
241
241
  it "should add namespace to timing" do
242
242
  @statsd.timing('foobar', 500)
243
- @socket.recv.must_equal ['service.foobar:500|ms']
243
+ _(@socket.recv).must_equal ['service.foobar:500|ms']
244
244
  end
245
245
 
246
246
  it "should add namespace to gauge" do
247
247
  @statsd.gauge('foobar', 500)
248
- @socket.recv.must_equal ['service.foobar:500|g']
248
+ _(@socket.recv).must_equal ['service.foobar:500|g']
249
249
  end
250
250
  end
251
251
 
@@ -254,22 +254,22 @@ describe Statsd do
254
254
 
255
255
  it "should add postfix to increment" do
256
256
  @statsd.increment('foobar')
257
- @socket.recv.must_equal ['foobar.ip-23-45-56-78:1|c']
257
+ _(@socket.recv).must_equal ['foobar.ip-23-45-56-78:1|c']
258
258
  end
259
259
 
260
260
  it "should add postfix to decrement" do
261
261
  @statsd.decrement('foobar')
262
- @socket.recv.must_equal ['foobar.ip-23-45-56-78:-1|c']
262
+ _(@socket.recv).must_equal ['foobar.ip-23-45-56-78:-1|c']
263
263
  end
264
264
 
265
265
  it "should add namespace to timing" do
266
266
  @statsd.timing('foobar', 500)
267
- @socket.recv.must_equal ['foobar.ip-23-45-56-78:500|ms']
267
+ _(@socket.recv).must_equal ['foobar.ip-23-45-56-78:500|ms']
268
268
  end
269
269
 
270
270
  it "should add namespace to gauge" do
271
271
  @statsd.gauge('foobar', 500)
272
- @socket.recv.must_equal ['foobar.ip-23-45-56-78:500|g']
272
+ _(@socket.recv).must_equal ['foobar.ip-23-45-56-78:500|g']
273
273
  end
274
274
  end
275
275
 
@@ -294,7 +294,7 @@ describe Statsd do
294
294
 
295
295
  @statsd.increment('foobar')
296
296
 
297
- @log.string.must_match "Statsd: foobar:1|c"
297
+ _(@log.string).must_match "Statsd: foobar:1|c"
298
298
  end
299
299
 
300
300
  it "should not write to the log unless debug" do
@@ -302,7 +302,7 @@ describe Statsd do
302
302
 
303
303
  @statsd.increment('foobar')
304
304
 
305
- @log.string.must_be_empty
305
+ _(@log.string).must_be_empty
306
306
  end
307
307
  end
308
308
 
@@ -315,7 +315,7 @@ describe Statsd do
315
315
  class Statsd::SomeClass; end
316
316
  @statsd.increment(Statsd::SomeClass, 1)
317
317
 
318
- @socket.recv.must_equal ['Statsd.SomeClass:1|c']
318
+ _(@socket.recv).must_equal ['Statsd.SomeClass:1|c']
319
319
  end
320
320
 
321
321
  describe "custom delimiter" do
@@ -327,13 +327,13 @@ describe Statsd do
327
327
  class Statsd::SomeOtherClass; end
328
328
  @statsd.increment(Statsd::SomeOtherClass, 1)
329
329
 
330
- @socket.recv.must_equal ['Statsd-SomeOtherClass:1|c']
330
+ _(@socket.recv).must_equal ['Statsd-SomeOtherClass:1|c']
331
331
  end
332
332
  end
333
333
 
334
334
  it "should replace statsd reserved chars in the stat name" do
335
335
  @statsd.increment('ray@hostname.blah|blah.blah:blah', 1)
336
- @socket.recv.must_equal ['ray_hostname.blah_blah.blah_blah:1|c']
336
+ _(@socket.recv).must_equal ['ray_hostname.blah_blah.blah_blah:1|c']
337
337
  end
338
338
  end
339
339
 
@@ -341,7 +341,8 @@ describe Statsd do
341
341
  before do
342
342
  require 'stringio'
343
343
  Statsd.logger = Logger.new(@log = StringIO.new)
344
- @socket.instance_eval { def write(*) raise SocketError end }
344
+ @socket.instance_variable_set(:@err_count, 0)
345
+ @socket.instance_eval { def write(*) @err_count+=1; raise SocketError end }
345
346
  end
346
347
 
347
348
  it "should ignore socket errors" do
@@ -350,35 +351,54 @@ describe Statsd do
350
351
 
351
352
  it "should log socket errors" do
352
353
  @statsd.increment('foobar')
353
- @log.string.must_match 'Statsd: SocketError'
354
+ _(@log.string).must_match 'Statsd: SocketError'
355
+ end
356
+
357
+ it "should retry and reconnect on socket errors" do
358
+ $connect_count = 0
359
+ @statsd.increment('foobar')
360
+ _(@socket.instance_variable_get(:@err_count)).must_equal 5
361
+ _($connect_count).must_equal 5
354
362
  end
355
363
  end
356
364
 
357
365
  describe "batching" do
358
366
  it "should have a default batch size of 10" do
359
- @statsd.batch_size.must_equal 10
367
+ _(@statsd.batch_size).must_equal 10
360
368
  end
361
369
 
362
370
  it "should have a default batch byte size of nil" do
363
371
  assert_nil @statsd.batch_byte_size
364
372
  end
365
373
 
374
+ it "should have a default flush interval of nil" do
375
+ assert_nil @statsd.flush_interval
376
+ end
377
+
366
378
  it "should have a modifiable batch size" do
367
379
  @statsd.batch_size = 7
368
- @statsd.batch_size.must_equal 7
380
+ _(@statsd.batch_size).must_equal 7
369
381
  @statsd.batch do |b|
370
- b.batch_size.must_equal 7
382
+ _(b.batch_size).must_equal 7
371
383
  end
372
384
 
373
385
  @statsd.batch_size = nil
374
386
  @statsd.batch_byte_size = 1472
375
387
  @statsd.batch do |b|
376
388
  assert_nil b.batch_size
377
- b.batch_byte_size.must_equal 1472
389
+ _(b.batch_byte_size).must_equal 1472
378
390
  end
379
391
 
380
392
  end
381
393
 
394
+ it 'should have a modifiable flush interval' do
395
+ @statsd.flush_interval = 1
396
+ _(@statsd.flush_interval).must_equal 1
397
+ @statsd.batch do |b|
398
+ _(b.flush_interval).must_equal 1
399
+ end
400
+ end
401
+
382
402
  it "should flush the batch at the batch size or at the end of the block" do
383
403
  @statsd.batch do |b|
384
404
  b.batch_size = 3
@@ -387,10 +407,10 @@ describe Statsd do
387
407
  # block is done.
388
408
  5.times { b.increment('foobar') }
389
409
 
390
- @socket.recv.must_equal [(["foobar:1|c"] * 3).join("\n")]
410
+ _(@socket.recv).must_equal [(["foobar:1|c"] * 3).join("\n")]
391
411
  end
392
412
 
393
- @socket.recv.must_equal [(["foobar:1|c"] * 2).join("\n")]
413
+ _(@socket.recv).must_equal [(["foobar:1|c"] * 2).join("\n")]
394
414
  end
395
415
 
396
416
  it "should flush based on batch byte size" do
@@ -402,10 +422,10 @@ describe Statsd do
402
422
  # block is done.
403
423
  3.times { b.increment('foobar') }
404
424
 
405
- @socket.recv.must_equal [(["foobar:1|c"] * 2).join("\n")]
425
+ _(@socket.recv).must_equal [(["foobar:1|c"] * 2).join("\n")]
406
426
  end
407
427
 
408
- @socket.recv.must_equal ["foobar:1|c"]
428
+ _(@socket.recv).must_equal ["foobar:1|c"]
409
429
  end
410
430
 
411
431
  it "should flush immediately when the queue is exactly a batch size" do
@@ -413,40 +433,56 @@ describe Statsd do
413
433
  b.batch_size = nil
414
434
  b.batch_byte_size = 21
415
435
 
436
+ # The first two should flush together
437
+ 2.times { b.increment('foobar') }
438
+
439
+ _(@socket.recv).must_equal [(["foobar:1|c"] * 2).join("\n")]
440
+ end
441
+ end
442
+
443
+ it "should flush when the interval has passed" do
444
+ @statsd.batch do |b|
445
+ b.batch_size = nil
446
+ b.flush_interval = 0.01
447
+
416
448
  # The first two should flush, the last will be flushed when the
417
449
  # block is done.
418
450
  2.times { b.increment('foobar') }
451
+ sleep(0.03)
452
+ b.increment('foobar')
419
453
 
420
- @socket.recv.must_equal [(["foobar:1|c"] * 2).join("\n")]
454
+ _(@socket.recv).must_equal [(["foobar:1|c"] * 2).join("\n")]
421
455
  end
456
+
457
+ _(@socket.recv).must_equal ["foobar:1|c"]
422
458
  end
423
459
 
424
460
  it "should not flush to the socket if the backlog is empty" do
425
461
  batch = Statsd::Batch.new(@statsd)
426
462
  batch.flush
427
- @socket.recv.must_be :nil?
463
+ _(@socket.recv).must_be :nil?
428
464
 
429
465
  batch.increment 'foobar'
430
466
  batch.flush
431
- @socket.recv.must_equal %w[foobar:1|c]
467
+ _(@socket.recv).must_equal %w[foobar:1|c]
432
468
  end
433
469
 
434
470
  it "should support setting namespace for the underlying instance" do
435
471
  batch = Statsd::Batch.new(@statsd)
436
472
  batch.namespace = 'ns'
437
- @statsd.namespace.must_equal 'ns'
473
+ _(@statsd.namespace).must_equal 'ns'
438
474
  end
439
475
 
440
476
  it "should support setting host for the underlying instance" do
441
477
  batch = Statsd::Batch.new(@statsd)
442
478
  batch.host = '1.2.3.4'
443
- @statsd.host.must_equal '1.2.3.4'
479
+ _(@statsd.host).must_equal '1.2.3.4'
444
480
  end
445
481
 
446
482
  it "should support setting port for the underlying instance" do
447
483
  batch = Statsd::Batch.new(@statsd)
448
484
  batch.port = 42
449
- @statsd.port.must_equal 42
485
+ _(@statsd.port).must_equal 42
450
486
  end
451
487
 
452
488
  end
@@ -455,7 +491,7 @@ describe Statsd do
455
491
  it "should reconnect" do
456
492
  c = $connect_count
457
493
  @statsd.connect
458
- ($connect_count - c).must_equal 1
494
+ _(($connect_count - c)).must_equal 1
459
495
  end
460
496
  end
461
497
 
@@ -474,7 +510,7 @@ describe Statsd do
474
510
  statsd = Statsd.new(host, port)
475
511
  statsd.increment('foobar')
476
512
  message = socket.recvfrom(16).first
477
- message.must_equal 'foobar:1|c'
513
+ _(message).must_equal 'foobar:1|c'
478
514
  ensure
479
515
  socket.close
480
516
  end
@@ -490,7 +526,7 @@ describe Statsd do
490
526
  statsd = Statsd.new(host, port)
491
527
  statsd.increment('foobar')
492
528
  message = socket.recvfrom(16).first
493
- message.must_equal 'foobar:1|c'
529
+ _(message).must_equal 'foobar:1|c'
494
530
  ensure
495
531
  socket.close
496
532
  end
@@ -506,7 +542,7 @@ describe Statsd do
506
542
  statsd = Statsd.new(host, port)
507
543
  statsd.increment('foobar')
508
544
  message = socket.recvfrom(16).first
509
- message.must_equal 'foobar:1|c'
545
+ _(message).must_equal 'foobar:1|c'
510
546
  ensure
511
547
  socket.close
512
548
  end
@@ -531,7 +567,7 @@ describe Statsd do
531
567
  end
532
568
 
533
569
  message = socket.recvfrom(16).first
534
- message.must_equal 'foobar:1|c'
570
+ _(message).must_equal "foobar:1|c\n"
535
571
  ensure
536
572
  socket.close if socket
537
573
  server.close
@@ -555,7 +591,7 @@ describe Statsd do
555
591
  end
556
592
 
557
593
  message = socket.recvfrom(16).first
558
- message.must_equal 'foobar:1|c'
594
+ _(message).must_equal "foobar:1|c\n"
559
595
  ensure
560
596
  socket.close if socket
561
597
  server.close
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
- Gem::Specification.new("statsd-ruby", "1.4.0") do |s|
3
+ Gem::Specification.new("statsd-ruby", "1.5.0") do |s|
4
4
  s.authors = `git log --format='%aN' | sort -u`.split("\n")
5
5
  s.email = "reinh@reinh.com"
6
6
 
@@ -17,7 +17,7 @@ Gem::Specification.new("statsd-ruby", "1.4.0") do |s|
17
17
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
18
18
  end
19
19
 
20
- s.add_development_dependency "minitest", ">= 3.2.0"
20
+ s.add_development_dependency "minitest", ">= 5.6.0"
21
21
  s.add_development_dependency "yard"
22
22
  s.add_development_dependency "simplecov", ">= 0.6.4"
23
23
  s.add_development_dependency "rake"
metadata CHANGED
@@ -1,15 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: statsd-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
+ - Agis Anastasopoulos
7
8
  - Alex Williams
8
9
  - Andrew Meyer
10
+ - Bill Franklin
9
11
  - Chris Gaffney
10
12
  - Cody Cutrer
11
13
  - Corey Donohoe
12
14
  - Dotan Nahum
15
+ - Elyahou Ittah
13
16
  - Erez Rabih
14
17
  - Eric Chapweske
15
18
  - Gabriel Burt
@@ -17,12 +20,14 @@ authors:
17
20
  - James Tucker
18
21
  - Jeremy Kemper
19
22
  - John Nunemaker
23
+ - Kyrylo Silin
20
24
  - Lann Martin
21
25
  - Mahesh Murthy
22
26
  - Manu J
23
27
  - Matt Sanford
24
28
  - Nate Bird
25
29
  - Noah Lorang
30
+ - Olle Jonsson
26
31
  - Oscar Del Ben
27
32
  - Peter Mounce
28
33
  - Ray Krueger
@@ -36,7 +41,7 @@ authors:
36
41
  autorequire:
37
42
  bindir: bin
38
43
  cert_chain: []
39
- date: 2017-03-29 00:00:00.000000000 Z
44
+ date: 2021-01-07 00:00:00.000000000 Z
40
45
  dependencies:
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: minitest
@@ -44,14 +49,14 @@ dependencies:
44
49
  requirements:
45
50
  - - ">="
46
51
  - !ruby/object:Gem::Version
47
- version: 3.2.0
52
+ version: 5.6.0
48
53
  type: :development
49
54
  prerelease: false
50
55
  version_requirements: !ruby/object:Gem::Requirement
51
56
  requirements:
52
57
  - - ">="
53
58
  - !ruby/object:Gem::Version
54
- version: 3.2.0
59
+ version: 5.6.0
55
60
  - !ruby/object:Gem::Dependency
56
61
  name: yard
57
62
  requirement: !ruby/object:Gem::Requirement
@@ -103,14 +108,15 @@ extra_rdoc_files:
103
108
  - README.rdoc
104
109
  files:
105
110
  - ".document"
111
+ - ".github/workflows/ci.yml"
106
112
  - ".gitignore"
107
- - ".travis.yml"
108
113
  - Gemfile
109
114
  - LICENSE.txt
110
115
  - README.rdoc
111
116
  - Rakefile
112
117
  - lib/statsd-ruby.rb
113
118
  - lib/statsd.rb
119
+ - lib/statsd/monotonic_time.rb
114
120
  - spec/helper.rb
115
121
  - spec/statsd_admin_spec.rb
116
122
  - spec/statsd_spec.rb
@@ -134,8 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
134
140
  - !ruby/object:Gem::Version
135
141
  version: '0'
136
142
  requirements: []
137
- rubyforge_project:
138
- rubygems_version: 2.5.1
143
+ rubygems_version: 3.1.4
139
144
  signing_key:
140
145
  specification_version: 4
141
146
  summary: A Ruby StatsD client
@@ -1,21 +0,0 @@
1
- ---
2
- language: ruby
3
-
4
- rvm:
5
- - 2.0.0
6
- - 2.1
7
- - 2.2
8
- - 2.3.0
9
- - 2.4.0
10
- - rbx-2
11
- - jruby
12
- - ruby-head
13
-
14
- sudo: false
15
-
16
- matrix:
17
- allow_failures:
18
- - rvm: rbx-2
19
- - rvm: ruby-head
20
- - rvm: jruby
21
- - rvm: jruby-head