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.
- checksums.yaml +4 -4
- data/README.md +5 -0
- data/lib/datadog/statsd.rb +236 -176
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d2b1b9e7ec2a48c5305f6acda103d0b7a09787801dd899a38fb665f5389e4f3
|
4
|
+
data.tar.gz: 3d974fffb4ace3bc248e69dcdaabb4c556e6783a25d65af98cb65bdccafc52ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
data/lib/datadog/statsd.rb
CHANGED
@@ -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, :
|
19
|
+
# statsd = Datadog::Statsd.new 'localhost', 8125, tags: 'tag1:true'
|
19
20
|
module Datadog
|
20
21
|
class Statsd
|
21
22
|
|
22
|
-
|
23
|
-
|
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 = "
|
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
|
76
|
-
|
194
|
+
# Maximum buffer size in bytes before it is flushed
|
195
|
+
attr_reader :max_buffer_bytes
|
77
196
|
|
78
|
-
|
79
|
-
|
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
|
92
|
-
# @option
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
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
|
108
|
-
end
|
220
|
+
@prefix = @namespace ? "#{@namespace}.".freeze : nil
|
109
221
|
|
110
|
-
|
111
|
-
@
|
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
|
-
|
115
|
-
@port = port || DEFAULT_PORT
|
225
|
+
@batch = Batch.new @connection, max_buffer_bytes
|
116
226
|
end
|
117
227
|
|
118
|
-
|
119
|
-
|
120
|
-
|
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
|
-
|
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
|
-
|
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
|
-
@
|
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
|
-
|
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 >
|
359
|
-
|
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
|
-
|
384
|
-
|
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 @
|
441
|
-
@
|
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
|
-
|
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:
|
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-
|
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:
|
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.
|
44
|
+
rubygems_version: 2.7.7
|
45
45
|
signing_key:
|
46
46
|
specification_version: 4
|
47
47
|
summary: A Ruby DogStatsd client
|