dogstatsd-ruby 3.3.0 → 4.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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -0
  3. data/lib/datadog/statsd.rb +236 -176
  4. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 046a0af9f230451c91fdeb9ae128c550b1c20623fa017d326e63a2f053f7cc9a
4
- data.tar.gz: e2ba838497de521e89d386645a0228f819fdd03c28acc05a4789aa7f8d979de8
3
+ metadata.gz: 6d2b1b9e7ec2a48c5305f6acda103d0b7a09787801dd899a38fb665f5389e4f3
4
+ data.tar.gz: 3d974fffb4ace3bc248e69dcdaabb4c556e6783a25d65af98cb65bdccafc52ee
5
5
  SHA512:
6
- metadata.gz: f2048376477bd1af31a63b75d17638df999c9f6341f967b2c826177add2a13831a54a72729e2a5c62aa09fa4aca6dccbaba308c79d9adcd470808d3bb80cde59
7
- data.tar.gz: 2e0ac5fc90f8a2359f35a754034bb6474c1169ac8c8f3301257555553e1aca4f708cecd4d9245ff835cbe4396561a89d3bd3700ef6cea6c92c343a1e41ca2055
6
+ metadata.gz: 16c82cb62bfd324d5e1dc1c6293fa121b92bd0c88d00474210c5da67f2cb07ae350cc0b717b15739c7a6f09e9021323ba348cec70ec2d0ac66a362f15f81007b
7
+ data.tar.gz: 6e82cef56d746ecf7b10890d397e313c143611b18b4ae65db67eb2f252cb27acacb45de03f6447b7b4ebb1666209806d6b048fb2857c5c8790f1f6729f4ae806
data/README.md CHANGED
@@ -49,6 +49,11 @@ end
49
49
 
50
50
  # Tag a metric.
51
51
  statsd.histogram('query.time', 10, :tags => ["version:1"])
52
+
53
+ # Auto-close socket after end of block
54
+ Datadog::Statsd.open('localhost', 8125) do |s|
55
+ s.increment('page.views')
56
+ end
52
57
  ```
53
58
 
54
59
  You can also post events to your stream. You can tag them, set priority and even aggregate them with other events.
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'socket'
2
3
 
3
4
  # = Datadog::Statsd: A DogStatsd client (https://www.datadoghq.com)
@@ -15,12 +16,137 @@ require 'socket'
15
16
  # statsd = Datadog::Statsd.new 'localhost', 8125, :namespace => 'account'
16
17
  # statsd.increment 'activate'
17
18
  # @example Create a statsd client with global tags
18
- # statsd = Datadog::Statsd.new 'localhost', 8125, :tags => 'tag1:true'
19
+ # statsd = Datadog::Statsd.new 'localhost', 8125, tags: 'tag1:true'
19
20
  module Datadog
20
21
  class Statsd
21
22
 
22
- DEFAULT_HOST = '127.0.0.1'
23
- DEFAULT_PORT = 8125
23
+ class Connection
24
+ DEFAULT_HOST = '127.0.0.1'
25
+ DEFAULT_PORT = 8125
26
+
27
+ # StatsD host. Defaults to 127.0.0.1.
28
+ attr_reader :host
29
+
30
+ # StatsD port. Defaults to 8125.
31
+ attr_reader :port
32
+
33
+ # DogStatsd unix socket path. Not used by default.
34
+ attr_reader :socket_path
35
+
36
+ def initialize(host, port, socket_path, logger)
37
+ @host = host || DEFAULT_HOST
38
+ @port = port || DEFAULT_PORT
39
+ @socket_path = socket_path
40
+ @logger = logger
41
+ end
42
+
43
+ def write(message)
44
+ @logger.debug { "Statsd: #{message}" } if @logger
45
+ if @socket_path.nil?
46
+ socket.send(message, 0)
47
+ else
48
+ socket.sendmsg_nonblock(message)
49
+ end
50
+ rescue StandardError => boom
51
+ # Give up on this socket if it looks like it is bad
52
+ bad_socket = !@socket_path.nil? && (
53
+ boom.is_a?(Errno::ECONNREFUSED) ||
54
+ boom.is_a?(Errno::ECONNRESET) ||
55
+ boom.is_a?(Errno::ENOENT)
56
+ )
57
+ if bad_socket
58
+ @socket = nil
59
+ return
60
+ end
61
+
62
+ # Try once to reconnect if the socket has been closed
63
+ retries ||= 1
64
+ if retries <= 1 && boom.is_a?(IOError) && boom.message =~ /closed stream/i
65
+ retries += 1
66
+ begin
67
+ @socket = connect
68
+ retry
69
+ rescue StandardError => e
70
+ boom = e
71
+ end
72
+ end
73
+
74
+ @logger.error { "Statsd: #{boom.class} #{boom}" } if @logger
75
+ nil
76
+ end
77
+
78
+ # Close the underlying socket
79
+ def close
80
+ @socket && @socket.close
81
+ end
82
+
83
+ private
84
+
85
+ def socket
86
+ @socket ||= connect
87
+ end
88
+
89
+ def connect
90
+ if @socket_path.nil?
91
+ socket = UDPSocket.new
92
+ socket.connect(@host, @port)
93
+ else
94
+ socket = Socket.new(Socket::AF_UNIX, Socket::SOCK_DGRAM)
95
+ socket.connect(Socket.pack_sockaddr_un(@socket_path))
96
+ end
97
+ socket
98
+ end
99
+ end
100
+
101
+ class Batch
102
+ def initialize(connection, max_buffer_bytes)
103
+ @connection = connection
104
+ @max_buffer_bytes = max_buffer_bytes
105
+ @depth = 0
106
+ reset
107
+ end
108
+
109
+ def open
110
+ @depth += 1
111
+ yield
112
+ ensure
113
+ @depth -= 1
114
+ flush if !open?
115
+ end
116
+
117
+ def open?
118
+ @depth > 0
119
+ end
120
+
121
+ def add(message)
122
+ message_bytes = message.bytesize
123
+
124
+ unless @buffer_bytes == 0
125
+ if @buffer_bytes + 1 + message_bytes >= @max_buffer_bytes
126
+ flush
127
+ else
128
+ @buffer << NEW_LINE
129
+ @buffer_bytes += 1
130
+ end
131
+ end
132
+
133
+ @buffer << message
134
+ @buffer_bytes += message_bytes
135
+ end
136
+
137
+ def flush
138
+ return if @buffer_bytes == 0
139
+ @connection.write @buffer
140
+ reset
141
+ end
142
+
143
+ private
144
+
145
+ def reset
146
+ @buffer = String.new
147
+ @buffer_bytes = 0
148
+ end
149
+ end
24
150
 
25
151
  # Create a dictionary to assign a key to every parameter's name, except for tags (treated differently)
26
152
  # Goal: Simple and fast to add some other parameters
@@ -46,78 +172,66 @@ module Datadog
46
172
  CRITICAL = 2
47
173
  UNKNOWN = 3
48
174
 
175
+ MAX_EVENT_SIZE = 8 * 1024
176
+
49
177
  COUNTER_TYPE = 'c'.freeze
50
178
  GAUGE_TYPE = 'g'.freeze
51
179
  HISTOGRAM_TYPE = 'h'.freeze
52
180
  DISTRIBUTION_TYPE = 'd'.freeze
53
181
  TIMING_TYPE = 'ms'.freeze
54
182
  SET_TYPE = 's'.freeze
55
- VERSION = "3.3.0".freeze
183
+ VERSION = "4.0.0".freeze
56
184
 
57
185
  # A namespace to prepend to all statsd calls. Defaults to no namespace.
58
186
  attr_reader :namespace
59
187
 
60
- # StatsD host. Defaults to 127.0.0.1.
61
- attr_reader :host
62
-
63
- # StatsD port. Defaults to 8125.
64
- attr_reader :port
65
-
66
- # DogStatsd unix socket path. Not used by default.
67
- attr_reader :socket_path
68
-
69
188
  # Global tags to be added to every statsd call. Defaults to no tags.
70
189
  attr_reader :tags
71
190
 
72
191
  # Buffer containing the statsd message before they are sent in batch
73
192
  attr_reader :buffer
74
193
 
75
- # Maximum number of metrics in the buffer before it is flushed
76
- attr_accessor :max_buffer_size
194
+ # Maximum buffer size in bytes before it is flushed
195
+ attr_reader :max_buffer_bytes
77
196
 
78
- class << self
79
- # Set to a standard logger instance to enable debug logging.
80
- attr_accessor :logger
81
- end
82
-
83
- # Return the current version of the library.
84
- # deprecated, but cannot be removed since uses might use it to check the version against older releases
85
- def self.VERSION
86
- VERSION
87
- end
197
+ # Connection
198
+ attr_reader :connection
88
199
 
89
200
  # @param [String] host your statsd host
90
201
  # @param [Integer] port your statsd port
91
- # @option opts [String] :namespace set a namespace to be prepended to every metric name
92
- # @option opts [Array<String>] :tags tags to be added to every metric
93
- def initialize(host = DEFAULT_HOST, port = DEFAULT_PORT, opts = {}, max_buffer_size=50)
94
- self.host, self.port = host, port
95
- @socket_path = opts[:socket_path]
96
- @prefix = nil
97
- @socket = connect_to_socket if @socket_path.nil?
98
- self.namespace = opts[:namespace]
99
- self.tags = opts[:tags]
100
- @buffer = Array.new
101
- self.max_buffer_size = max_buffer_size
102
- @batch_nesting_depth = 0
103
- end
202
+ # @option [String] namespace set a namespace to be prepended to every metric name
203
+ # @option [Array<String>] tags tags to be added to every metric
204
+ # @option [Loger] logger for debugging
205
+ # @option [Integer] max_buffer_bytes max bytes to buffer when using #batch
206
+ # @option [String] socket_path unix socket path
207
+ def initialize(
208
+ host = nil,
209
+ port = nil,
210
+ namespace: nil,
211
+ tags: nil,
212
+ max_buffer_bytes: 8192,
213
+ socket_path: nil,
214
+ logger: nil
215
+ )
216
+ @connection = Connection.new(host, port, socket_path, logger)
217
+ @logger = logger
104
218
 
105
- def namespace=(namespace) #:nodoc:
106
219
  @namespace = namespace
107
- @prefix = namespace.nil? ? nil : "#{namespace}.".freeze
108
- end
220
+ @prefix = @namespace ? "#{@namespace}.".freeze : nil
109
221
 
110
- def host=(host) #:nodoc:
111
- @host = host || DEFAULT_HOST
112
- end
222
+ raise ArgumentError, 'tags must be a Array<String>' unless tags.nil? or tags.is_a? Array
223
+ @tags = (tags || []).compact.map! {|tag| escape_tag_content(tag)}
113
224
 
114
- def port=(port) #:nodoc:
115
- @port = port || DEFAULT_PORT
225
+ @batch = Batch.new @connection, max_buffer_bytes
116
226
  end
117
227
 
118
- def tags=(tags) #:nodoc:
119
- raise ArgumentError, 'tags must be a Array<String>' unless tags.nil? or tags.is_a? Array
120
- @tags = (tags || []).compact.map! {|tag| escape_tag_content(tag)}
228
+ # yield a new instance to a block and close it when done
229
+ # for short-term use-cases that don't want to close the socket manually
230
+ def self.open(*args)
231
+ instance = new(*args)
232
+ yield instance
233
+ ensure
234
+ instance.close
121
235
  end
122
236
 
123
237
  # Sends an increment (count = 1) for the given stat to the statsd server.
@@ -128,7 +242,7 @@ module Datadog
128
242
  # @option opts [Array<String>] :tags An array of tags
129
243
  # @option opts [Numeric] :by increment value, default 1
130
244
  # @see #count
131
- def increment(stat, opts={})
245
+ def increment(stat, opts=EMPTY_OPTIONS)
132
246
  opts = {:sample_rate => opts} if opts.is_a? Numeric
133
247
  incr_value = opts.fetch(:by, 1)
134
248
  count stat, incr_value, opts
@@ -142,7 +256,7 @@ module Datadog
142
256
  # @option opts [Array<String>] :tags An array of tags
143
257
  # @option opts [Numeric] :by decrement value, default 1
144
258
  # @see #count
145
- def decrement(stat, opts={})
259
+ def decrement(stat, opts=EMPTY_OPTIONS)
146
260
  opts = {:sample_rate => opts} if opts.is_a? Numeric
147
261
  decr_value = - opts.fetch(:by, 1)
148
262
  count stat, decr_value, opts
@@ -155,7 +269,7 @@ module Datadog
155
269
  # @param [Hash] opts the options to create the metric with
156
270
  # @option opts [Numeric] :sample_rate sample rate, 1 for always
157
271
  # @option opts [Array<String>] :tags An array of tags
158
- def count(stat, count, opts={})
272
+ def count(stat, count, opts=EMPTY_OPTIONS)
159
273
  opts = {:sample_rate => opts} if opts.is_a? Numeric
160
274
  send_stats stat, count, COUNTER_TYPE, opts
161
275
  end
@@ -173,7 +287,7 @@ module Datadog
173
287
  # @option opts [Array<String>] :tags An array of tags
174
288
  # @example Report the current user count:
175
289
  # $statsd.gauge('user.count', User.count)
176
- def gauge(stat, value, opts={})
290
+ def gauge(stat, value, opts=EMPTY_OPTIONS)
177
291
  opts = {:sample_rate => opts} if opts.is_a? Numeric
178
292
  send_stats stat, value, GAUGE_TYPE, opts
179
293
  end
@@ -187,7 +301,7 @@ module Datadog
187
301
  # @option opts [Array<String>] :tags An array of tags
188
302
  # @example Report the current user count:
189
303
  # $statsd.histogram('user.count', User.count)
190
- def histogram(stat, value, opts={})
304
+ def histogram(stat, value, opts=EMPTY_OPTIONS)
191
305
  send_stats stat, value, HISTOGRAM_TYPE, opts
192
306
  end
193
307
 
@@ -203,7 +317,7 @@ module Datadog
203
317
  # @option opts [Array<String>] :tags An array of tags
204
318
  # @example Report the current user count:
205
319
  # $statsd.distribution('user.count', User.count)
206
- def distribution(stat, value, opts={})
320
+ def distribution(stat, value, opts=EMPTY_OPTIONS)
207
321
  send_stats stat, value, DISTRIBUTION_TYPE, opts
208
322
  end
209
323
 
@@ -217,7 +331,7 @@ module Datadog
217
331
  # @param [Hash] opts the options to create the metric with
218
332
  # @option opts [Numeric] :sample_rate sample rate, 1 for always
219
333
  # @option opts [Array<String>] :tags An array of tags
220
- def timing(stat, ms, opts={})
334
+ def timing(stat, ms, opts=EMPTY_OPTIONS)
221
335
  opts = {:sample_rate => opts} if opts.is_a? Numeric
222
336
  send_stats stat, ms, TIMING_TYPE, opts
223
337
  end
@@ -235,7 +349,7 @@ module Datadog
235
349
  # @see #timing
236
350
  # @example Report the time (in ms) taken to activate an account
237
351
  # $statsd.time('account.activate') { @account.activate! }
238
- def time(stat, opts={})
352
+ def time(stat, opts=EMPTY_OPTIONS)
239
353
  opts = {:sample_rate => opts} if opts.is_a? Numeric
240
354
  start = (PROCESS_TIME_SUPPORTED ? Process.clock_gettime(Process::CLOCK_MONOTONIC) : Time.now.to_f)
241
355
  return yield
@@ -243,6 +357,7 @@ module Datadog
243
357
  finished = (PROCESS_TIME_SUPPORTED ? Process.clock_gettime(Process::CLOCK_MONOTONIC) : Time.now.to_f)
244
358
  timing(stat, ((finished - start) * 1000).round, opts)
245
359
  end
360
+
246
361
  # Sends a value to be tracked as a set to the statsd server.
247
362
  #
248
363
  # @param [String] stat stat name.
@@ -252,7 +367,7 @@ module Datadog
252
367
  # @option opts [Array<String>] :tags An array of tags
253
368
  # @example Record a unique visitory by id:
254
369
  # $statsd.set('visitors.uniques', User.id)
255
- def set(stat, value, opts={})
370
+ def set(stat, value, opts=EMPTY_OPTIONS)
256
371
  opts = {:sample_rate => opts} if opts.is_a? Numeric
257
372
  send_stats stat, value, SET_TYPE, opts
258
373
  end
@@ -268,31 +383,8 @@ module Datadog
268
383
  # @option opts [String, nil] :message (nil) A message to associate with this service check status
269
384
  # @example Report a critical service check status
270
385
  # $statsd.service_check('my.service.check', Statsd::CRITICAL, :tags=>['urgent'])
271
- def service_check(name, status, opts={})
272
- service_check_string = format_service_check(name, status, opts)
273
- send_to_socket service_check_string
274
- end
275
-
276
- def format_service_check(name, status, opts={})
277
- sc_string = "_sc|#{name}|#{status}"
278
-
279
- SC_OPT_KEYS.each do |key, shorthand_key|
280
- next unless opts[key]
281
-
282
- if key == :tags
283
- if tags_string = tags_as_string(opts)
284
- sc_string << "|##{tags_string}"
285
- end
286
- elsif key == :message
287
- message = remove_pipes(opts[:message])
288
- escaped_message = escape_service_check_message(message)
289
- sc_string << "|m:#{escaped_message}"
290
- else
291
- value = remove_pipes(opts[key])
292
- sc_string << "|#{shorthand_key}#{value}"
293
- end
294
- end
295
- return sc_string
386
+ def service_check(name, status, opts=EMPTY_OPTIONS)
387
+ send_stat format_service_check(name, status, opts)
296
388
  end
297
389
 
298
390
  # This end point allows you to post events to the stream. You can tag them, set priority and even aggregate them with other events.
@@ -313,11 +405,8 @@ module Datadog
313
405
  # @option opts [Array<String>] :tags tags to be added to every metric
314
406
  # @example Report an awful event:
315
407
  # $statsd.event('Something terrible happened', 'The end is near if we do nothing', :alert_type=>'warning', :tags=>['end_of_times','urgent'])
316
- def event(title, text, opts={})
317
- event_string = format_event(title, text, opts)
318
- raise "Event #{title} payload is too big (more that 8KB), event discarded" if event_string.length > 8 * 1024
319
-
320
- send_to_socket event_string
408
+ def event(title, text, opts=EMPTY_OPTIONS)
409
+ send_stat format_event(title, text, opts)
321
410
  end
322
411
 
323
412
  # Send several metrics in the same UDP Packet
@@ -328,18 +417,56 @@ module Datadog
328
417
  # s.gauge('users.online',156)
329
418
  # s.increment('page.views')
330
419
  # end
331
- def batch()
332
- @batch_nesting_depth += 1
333
- yield self
334
- ensure
335
- @batch_nesting_depth -= 1
336
- flush_buffer if @batch_nesting_depth == 0
420
+ def batch
421
+ @batch.open { yield self }
337
422
  end
338
423
 
339
- def format_event(title, text, opts={})
424
+ # Close the underlying socket
425
+ def close
426
+ @connection.close
427
+ end
428
+
429
+ private
430
+
431
+ NEW_LINE = "\n".freeze
432
+ ESC_NEW_LINE = "\\n".freeze
433
+ COMMA = ",".freeze
434
+ PIPE = "|".freeze
435
+ DOT = ".".freeze
436
+ DOUBLE_COLON = "::".freeze
437
+ UNDERSCORE = "_".freeze
438
+ PROCESS_TIME_SUPPORTED = (RUBY_VERSION >= "2.1.0")
439
+ EMPTY_OPTIONS = {}.freeze
440
+
441
+ private_constant :NEW_LINE, :ESC_NEW_LINE, :COMMA, :PIPE, :DOT,
442
+ :DOUBLE_COLON, :UNDERSCORE, :EMPTY_OPTIONS
443
+
444
+ def format_service_check(name, status, opts=EMPTY_OPTIONS)
445
+ sc_string = "_sc|#{name}|#{status}".dup
446
+
447
+ SC_OPT_KEYS.each do |key, shorthand_key|
448
+ next unless opts[key]
449
+
450
+ if key == :tags
451
+ if tags_string = tags_as_string(opts)
452
+ sc_string << "|##{tags_string}"
453
+ end
454
+ elsif key == :message
455
+ message = remove_pipes(opts[:message])
456
+ escaped_message = escape_service_check_message(message)
457
+ sc_string << "|m:#{escaped_message}"
458
+ else
459
+ value = remove_pipes(opts[key])
460
+ sc_string << "|#{shorthand_key}#{value}"
461
+ end
462
+ end
463
+ sc_string
464
+ end
465
+
466
+ def format_event(title, text, opts=EMPTY_OPTIONS)
340
467
  escaped_title = escape_event_content(title)
341
468
  escaped_text = escape_event_content(text)
342
- event_string_data = "_e{#{escaped_title.length},#{escaped_text.length}}:#{escaped_title}|#{escaped_text}"
469
+ event_string_data = "_e{#{escaped_title.length},#{escaped_text.length}}:#{escaped_title}|#{escaped_text}".dup
343
470
 
344
471
  # We construct the string to be sent by adding '|key:value' parts to it when needed
345
472
  # All pipes ('|') in the metadata are removed. Title and Text can keep theirs
@@ -355,33 +482,17 @@ module Datadog
355
482
  event_string_data << "|##{tags_string}"
356
483
  end
357
484
 
358
- raise "Event #{title} payload is too big (more that 8KB), event discarded" if event_string_data.length > 8192 # 8 * 1024 = 8192
359
- return event_string_data
360
- end
361
-
362
- # Close the underlying socket
363
- def close()
364
- @socket.close
485
+ raise "Event #{title} payload is too big (more that 8KB), event discarded" if event_string_data.length > MAX_EVENT_SIZE
486
+ event_string_data
365
487
  end
366
488
 
367
- private
368
-
369
- NEW_LINE = "\n".freeze
370
- ESC_NEW_LINE = "\\n".freeze
371
- COMMA = ",".freeze
372
- PIPE = "|".freeze
373
- DOT = ".".freeze
374
- DOUBLE_COLON = "::".freeze
375
- UNDERSCORE = "_".freeze
376
- PROCESS_TIME_SUPPORTED = (RUBY_VERSION >= "2.1.0")
377
-
378
- private_constant :NEW_LINE, :ESC_NEW_LINE, :COMMA, :PIPE, :DOT,
379
- :DOUBLE_COLON, :UNDERSCORE
380
-
381
489
  def tags_as_string(opts)
382
- tag_arr = opts[:tags] || []
383
- tag_arr = tag_arr.map { |tag| escape_tag_content(tag) }
384
- tag_arr = tags + tag_arr # @tags are normalized when set, so not need to normalize them again
490
+ if tag_arr = opts[:tags]
491
+ tag_arr = tag_arr.map { |tag| escape_tag_content(tag) }
492
+ tag_arr = tags + tag_arr # @tags are normalized when set, so not need to normalize them again
493
+ else
494
+ tag_arr = tags
495
+ end
385
496
  tag_arr.join(COMMA) unless tag_arr.empty?
386
497
  end
387
498
 
@@ -403,10 +514,10 @@ module Datadog
403
514
  escape_event_content(msg).gsub('m:'.freeze, 'm\:'.freeze)
404
515
  end
405
516
 
406
- def send_stats(stat, delta, type, opts={})
517
+ def send_stats(stat, delta, type, opts=EMPTY_OPTIONS)
407
518
  sample_rate = opts[:sample_rate] || 1
408
519
  if sample_rate == 1 or rand < sample_rate
409
- full_stat = ''
520
+ full_stat = ''.dup
410
521
  full_stat << @prefix if @prefix
411
522
 
412
523
  stat = stat.is_a?(String) ? stat.dup : stat.to_s
@@ -437,62 +548,11 @@ module Datadog
437
548
  end
438
549
 
439
550
  def send_stat(message)
440
- if @batch_nesting_depth > 0
441
- @buffer << message
442
- flush_buffer if @buffer.length >= @max_buffer_size
443
- else
444
- send_to_socket(message)
445
- end
446
- end
447
-
448
- def flush_buffer
449
- return @buffer if @buffer.empty?
450
- send_to_socket(@buffer.join(NEW_LINE))
451
- @buffer = Array.new
452
- end
453
-
454
- def connect_to_socket
455
- if !@socket_path.nil?
456
- socket = Socket.new(Socket::AF_UNIX, Socket::SOCK_DGRAM)
457
- socket.connect(Socket.pack_sockaddr_un(@socket_path))
458
- else
459
- socket = UDPSocket.new
460
- socket.connect(@host, @port)
461
- end
462
- socket
463
- end
464
-
465
- def sock
466
- @socket ||= connect_to_socket
467
- end
468
-
469
- def send_to_socket(message)
470
- self.class.logger.debug { "Statsd: #{message}" } if self.class.logger
471
- if @socket_path.nil?
472
- sock.send(message, 0)
551
+ if @batch.open?
552
+ @batch.add message
473
553
  else
474
- sock.sendmsg_nonblock(message)
554
+ @connection.write(message)
475
555
  end
476
- rescue => boom
477
- if @socket_path && (boom.is_a?(Errno::ECONNREFUSED) ||
478
- boom.is_a?(Errno::ECONNRESET) ||
479
- boom.is_a?(Errno::ENOENT))
480
- return @socket = nil
481
- end
482
- # Try once to reconnect if the socket has been closed
483
- retries ||= 1
484
- if retries <= 1 && boom.is_a?(IOError) && boom.message =~ /closed stream/i
485
- retries += 1
486
- begin
487
- @socket = connect_to_socket
488
- retry
489
- rescue => e
490
- boom = e
491
- end
492
- end
493
-
494
- self.class.logger.error { "Statsd: #{boom.class} #{boom}" } if self.class.logger
495
- nil
496
556
  end
497
557
  end
498
558
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dogstatsd-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rein Henrichs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-04 00:00:00.000000000 Z
11
+ date: 2018-08-20 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A Ruby DogStastd client
14
14
  email: code@datadoghq.com
@@ -33,7 +33,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
33
33
  requirements:
34
34
  - - ">="
35
35
  - !ruby/object:Gem::Version
36
- version: '0'
36
+ version: 2.0.0
37
37
  required_rubygems_version: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - ">="
@@ -41,7 +41,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
41
41
  version: '0'
42
42
  requirements: []
43
43
  rubyforge_project:
44
- rubygems_version: 2.7.1
44
+ rubygems_version: 2.7.7
45
45
  signing_key:
46
46
  specification_version: 4
47
47
  summary: A Ruby DogStatsd client