statsd-ruby 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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