dogstatsd-ruby 5.4.0 → 5.6.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 +11 -3
- data/lib/datadog/statsd/connection.rb +1 -1
- data/lib/datadog/statsd/connection_cfg.rb +56 -7
- data/lib/datadog/statsd/forwarder.rb +11 -4
- data/lib/datadog/statsd/message_buffer.rb +9 -1
- data/lib/datadog/statsd/sender.rb +12 -5
- data/lib/datadog/statsd/single_thread_sender.rb +20 -4
- data/lib/datadog/statsd/timer.rb +1 -0
- data/lib/datadog/statsd/version.rb +1 -1
- data/lib/datadog/statsd.rb +31 -2
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20363c18876c0641ab23a8cee8d28c22de3e4210420e398d639d6a7b384da168
|
4
|
+
data.tar.gz: 851d63e75192dd81451f7a94abba7efe5c81e9c4afdc2dce8102a76e44a10d9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 72f565700a7ddf32ca56a686617e840c53ad167770be812a66ad6af5d1641c96f89796fe147c1565c38c7d83be14fc638e0f8ce76a00e62e980f43a510826d18
|
7
|
+
data.tar.gz: 659bbd4b5b669a11bf62f723387d0263d76a243bda5c6b5de101700b20ad2991d6fd6535832857acdd15b0f809faff80cb1e9f459e1ddacb3262a6be27c4785f
|
data/README.md
CHANGED
@@ -81,8 +81,6 @@ Version v5.x of `dogstatsd-ruby` is using a sender thread for flushing. This pro
|
|
81
81
|
|
82
82
|
If you are using [Sidekiq](https://github.com/mperham/sidekiq), please make sure to close the client instances that are instantiated. [See this example on using DogStatsD-ruby v5.x with Sidekiq](https://github.com/DataDog/dogstatsd-ruby/blob/master/examples/sidekiq_example.rb).
|
83
83
|
|
84
|
-
If you are using [Puma](https://github.com/puma/puma) or [Unicorn](https://yhbt.net/unicorn.git), please make sure to create the instance of DogStatsD in the workers, not in the main process before it forks to create its workers. See [this comment for more details](https://github.com/DataDog/dogstatsd-ruby/issues/179#issuecomment-845570345).
|
85
|
-
|
86
84
|
Applications that run into issues but can't apply these recommendations should use the `single_thread` mode which disables the use of the sender thread.
|
87
85
|
Here is how to instantiate a client in this mode:
|
88
86
|
|
@@ -185,7 +183,7 @@ There is also an implicit message which closes the queue which will cause the se
|
|
185
183
|
statsd = Datadog::Statsd.new('localhost', 8125)
|
186
184
|
```
|
187
185
|
|
188
|
-
The message queue's maximum size (in messages) is given by the `sender_queue_size` argument, and has appropriate defaults for UDP (2048)
|
186
|
+
The message queue's maximum size (in messages) is given by the `sender_queue_size` argument, and has appropriate defaults for UDP (2048), UDS (512) and `single_thread: true` (1).
|
189
187
|
|
190
188
|
The `buffer_flush_interval`, if enabled, is implemented with an additional thread which manages the timing of those flushes. This additional thread is used even if `single_thread: true`.
|
191
189
|
|
@@ -211,6 +209,16 @@ By default, instances of `Datadog::Statsd` are thread-safe and we recommend that
|
|
211
209
|
|
212
210
|
When using the `single_thread: true` mode, instances of `Datadog::Statsd` are still thread-safe, but you may run into contention on heavily-threaded applications, so we don’t recommend (for performance reasons) reusing these instances.
|
213
211
|
|
212
|
+
### Delaying serialization
|
213
|
+
|
214
|
+
By default, message serialization happens synchronously whenever stat methods such as `#increment` gets called, blocking the caller. If the blocking is impacting your program's performance, you may want to consider the `delay_serialization: true` mode.
|
215
|
+
|
216
|
+
The `delay_serialization: true` mode delays the serialization of metrics to avoid the wait when submitting metrics. Serialization will still have to happen at some point, but it might be postponed until a more convenient time, such as after an HTTP request has completed.
|
217
|
+
|
218
|
+
In `single_thread: true` mode, you'll probably want to set `sender_queue_size:` from it's default of `1` to some greater value, so that it can benefit from `delay_serialization: true`. Messages will then be queued unserialized in the sender queue and processed normally whenever `sender_queue_size` is reached or `#flush` is called. You might set `sender_queue_size: Float::INFINITY` to allow for an unbounded queue that will only be processed on explicit `#flush`.
|
219
|
+
|
220
|
+
In `single_thread: false` mode, `delay_serialization: true`, will cause serialization to happen inside the sender thread.
|
221
|
+
|
214
222
|
## Versioning
|
215
223
|
|
216
224
|
This Ruby gem is using [Semantic Versioning](https://guides.rubygems.org/patterns/#semantic-versioning) but please note that supported Ruby versions can change in a minor release of this library.
|
@@ -23,12 +23,25 @@ module Datadog
|
|
23
23
|
|
24
24
|
private
|
25
25
|
|
26
|
+
ERROR_MESSAGE = "Valid environment variables combination for connection configuration:\n" +
|
27
|
+
" - DD_DOGSTATSD_URL for UDP or UDS connection.\n" +
|
28
|
+
" Example for UDP: DD_DOGSTATSD_URL='udp://localhost:8125'\n" +
|
29
|
+
" Example for UDS: DD_DOGSTATSD_URL='unix:///path/to/unix.sock'\n" +
|
30
|
+
" or\n" +
|
31
|
+
" - DD_AGENT_HOST and DD_DOGSTATSD_PORT for an UDP connection. E.g. DD_AGENT_HOST='localhost' DD_DOGSTATSD_PORT=8125\n" +
|
32
|
+
" or\n" +
|
33
|
+
" - DD_DOGSTATSD_SOCKET for an UDS connection: E.g. DD_DOGSTATSD_SOCKET='/path/to/unix.sock'\n" +
|
34
|
+
" Note that DD_DOGSTATSD_URL has priority on other environment variables."
|
35
|
+
|
26
36
|
DEFAULT_HOST = '127.0.0.1'
|
27
37
|
DEFAULT_PORT = 8125
|
28
38
|
|
39
|
+
UDP_PREFIX = 'udp://'
|
40
|
+
UDS_PREFIX = 'unix://'
|
41
|
+
|
29
42
|
def initialize_with_constructor_args(host: nil, port: nil, socket_path: nil)
|
30
43
|
try_initialize_with(host: host, port: port, socket_path: socket_path,
|
31
|
-
|
44
|
+
error_message:
|
32
45
|
"Both UDP: (host/port #{host}:#{port}) and UDS (socket_path #{socket_path}) " +
|
33
46
|
"constructor arguments were given. Use only one or the other.",
|
34
47
|
)
|
@@ -36,13 +49,11 @@ module Datadog
|
|
36
49
|
|
37
50
|
def initialize_with_env_vars()
|
38
51
|
try_initialize_with(
|
52
|
+
dogstatsd_url: ENV['DD_DOGSTATSD_URL'],
|
39
53
|
host: ENV['DD_AGENT_HOST'],
|
40
54
|
port: ENV['DD_DOGSTATSD_PORT'] && ENV['DD_DOGSTATSD_PORT'].to_i,
|
41
55
|
socket_path: ENV['DD_DOGSTATSD_SOCKET'],
|
42
|
-
|
43
|
-
"Both UDP (DD_AGENT_HOST/DD_DOGSTATSD_PORT #{ENV['DD_AGENT_HOST']}:#{ENV['DD_DOGSTATSD_PORT']}) " +
|
44
|
-
"and UDS (DD_DOGSTATSD_SOCKET #{ENV['DD_DOGSTATSD_SOCKET']}) environment variables are set. " +
|
45
|
-
"Set only one or the other.",
|
56
|
+
error_message: ERROR_MESSAGE,
|
46
57
|
)
|
47
58
|
end
|
48
59
|
|
@@ -50,9 +61,13 @@ module Datadog
|
|
50
61
|
try_initialize_with(host: DEFAULT_HOST, port: DEFAULT_PORT)
|
51
62
|
end
|
52
63
|
|
53
|
-
def try_initialize_with(host: nil, port: nil, socket_path: nil,
|
64
|
+
def try_initialize_with(dogstatsd_url: nil, host: nil, port: nil, socket_path: nil, error_message: ERROR_MESSAGE)
|
54
65
|
if (host || port) && socket_path
|
55
|
-
raise ArgumentError,
|
66
|
+
raise ArgumentError, error_message
|
67
|
+
end
|
68
|
+
|
69
|
+
if dogstatsd_url
|
70
|
+
host, port, socket_path = parse_dogstatsd_url(str: dogstatsd_url.to_s)
|
56
71
|
end
|
57
72
|
|
58
73
|
if host || port
|
@@ -71,6 +86,40 @@ module Datadog
|
|
71
86
|
|
72
87
|
return false
|
73
88
|
end
|
89
|
+
|
90
|
+
def parse_dogstatsd_url(str:)
|
91
|
+
# udp socket connection
|
92
|
+
|
93
|
+
if str.start_with?(UDP_PREFIX)
|
94
|
+
dogstatsd_url = str[UDP_PREFIX.size..str.size]
|
95
|
+
host = nil
|
96
|
+
port = nil
|
97
|
+
|
98
|
+
if dogstatsd_url.include?(":")
|
99
|
+
parts = dogstatsd_url.split(":")
|
100
|
+
if parts.size > 2
|
101
|
+
raise ArgumentError, "Error: DD_DOGSTATSD_URL wrong format for an UDP connection. E.g. 'udp://localhost:8125'"
|
102
|
+
end
|
103
|
+
|
104
|
+
host = parts[0]
|
105
|
+
port = parts[1].to_i
|
106
|
+
else
|
107
|
+
host = dogstatsd_url
|
108
|
+
end
|
109
|
+
|
110
|
+
return host, port, nil
|
111
|
+
end
|
112
|
+
|
113
|
+
# unix socket connection
|
114
|
+
|
115
|
+
if str.start_with?(UDS_PREFIX)
|
116
|
+
return nil, nil, str[UDS_PREFIX.size..str.size]
|
117
|
+
end
|
118
|
+
|
119
|
+
# malformed value
|
120
|
+
|
121
|
+
raise ArgumentError, "Error: DD_DOGSTATSD_URL has been provided but is not starting with 'udp://' nor 'unix://'"
|
122
|
+
end
|
74
123
|
end
|
75
124
|
end
|
76
125
|
end
|
@@ -21,15 +21,19 @@ module Datadog
|
|
21
21
|
|
22
22
|
single_thread: false,
|
23
23
|
|
24
|
-
logger: nil
|
24
|
+
logger: nil,
|
25
|
+
|
26
|
+
serializer:
|
25
27
|
)
|
26
28
|
@transport_type = connection_cfg.transport_type
|
27
29
|
|
28
|
-
if telemetry_flush_interval
|
29
|
-
|
30
|
+
@telemetry = if telemetry_flush_interval
|
31
|
+
Telemetry.new(telemetry_flush_interval,
|
30
32
|
global_tags: global_tags,
|
31
33
|
transport_type: @transport_type
|
32
34
|
)
|
35
|
+
else
|
36
|
+
nil
|
33
37
|
end
|
34
38
|
|
35
39
|
@connection = connection_cfg.make_connection(logger: logger, telemetry: telemetry)
|
@@ -50,8 +54,10 @@ module Datadog
|
|
50
54
|
max_payload_size: buffer_max_payload_size,
|
51
55
|
max_pool_size: buffer_max_pool_size || DEFAULT_BUFFER_POOL_SIZE,
|
52
56
|
overflowing_stategy: buffer_overflowing_stategy,
|
57
|
+
serializer: serializer
|
53
58
|
)
|
54
59
|
|
60
|
+
sender_queue_size ||= 1 if single_thread
|
55
61
|
sender_queue_size ||= (@transport_type == :udp ?
|
56
62
|
UDP_DEFAULT_SENDER_QUEUE_SIZE : UDS_DEFAULT_SENDER_QUEUE_SIZE)
|
57
63
|
|
@@ -59,7 +65,8 @@ module Datadog
|
|
59
65
|
SingleThreadSender.new(
|
60
66
|
buffer,
|
61
67
|
logger: logger,
|
62
|
-
flush_interval: buffer_flush_interval
|
68
|
+
flush_interval: buffer_flush_interval,
|
69
|
+
queue_size: sender_queue_size) :
|
63
70
|
Sender.new(
|
64
71
|
buffer,
|
65
72
|
logger: logger,
|
@@ -8,7 +8,8 @@ module Datadog
|
|
8
8
|
def initialize(connection,
|
9
9
|
max_payload_size: nil,
|
10
10
|
max_pool_size: DEFAULT_BUFFER_POOL_SIZE,
|
11
|
-
overflowing_stategy: :drop
|
11
|
+
overflowing_stategy: :drop,
|
12
|
+
serializer:
|
12
13
|
)
|
13
14
|
raise ArgumentError, 'max_payload_size keyword argument must be provided' unless max_payload_size
|
14
15
|
raise ArgumentError, 'max_pool_size keyword argument must be provided' unless max_pool_size
|
@@ -17,12 +18,19 @@ module Datadog
|
|
17
18
|
@max_payload_size = max_payload_size
|
18
19
|
@max_pool_size = max_pool_size
|
19
20
|
@overflowing_stategy = overflowing_stategy
|
21
|
+
@serializer = serializer
|
20
22
|
|
21
23
|
@buffer = String.new
|
22
24
|
clear_buffer
|
23
25
|
end
|
24
26
|
|
25
27
|
def add(message)
|
28
|
+
# Serializes the message if it hasn't been already. Part of the
|
29
|
+
# delay_serialization feature.
|
30
|
+
if message.is_a?(Array)
|
31
|
+
message = @serializer.to_stat(*message[0], **message[1])
|
32
|
+
end
|
33
|
+
|
26
34
|
message_size = message.bytesize
|
27
35
|
|
28
36
|
return nil unless message_size > 0 # to avoid adding empty messages to the buffer
|
@@ -20,8 +20,10 @@ module Datadog
|
|
20
20
|
@mx = Mutex.new
|
21
21
|
@queue_class = queue_class
|
22
22
|
@thread_class = thread_class
|
23
|
-
if flush_interval
|
24
|
-
|
23
|
+
@flush_timer = if flush_interval
|
24
|
+
Datadog::Statsd::Timer.new(flush_interval) { flush(sync: true) }
|
25
|
+
else
|
26
|
+
nil
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
@@ -82,7 +84,10 @@ module Datadog
|
|
82
84
|
if message_queue.length <= @queue_size
|
83
85
|
message_queue << message
|
84
86
|
else
|
85
|
-
|
87
|
+
if @telemetry
|
88
|
+
bytesize = message.respond_to?(:bytesize) ? message.bytesize : 0
|
89
|
+
@telemetry.dropped_queue(packets: 1, bytes: bytesize)
|
90
|
+
end
|
86
91
|
end
|
87
92
|
end
|
88
93
|
|
@@ -102,10 +107,11 @@ module Datadog
|
|
102
107
|
# to close the sender nor trying to continue to `#add` more message
|
103
108
|
# into the sender.
|
104
109
|
def stop(join_worker: true)
|
110
|
+
@flush_timer.stop if @flush_timer
|
111
|
+
|
105
112
|
message_queue = @message_queue
|
106
113
|
message_queue.close if message_queue
|
107
114
|
|
108
|
-
@flush_timer.stop if @flush_timer
|
109
115
|
sender_thread = @sender_thread
|
110
116
|
sender_thread.join if sender_thread && join_worker
|
111
117
|
end
|
@@ -114,10 +120,11 @@ module Datadog
|
|
114
120
|
# to close the sender nor trying to continue to `#add` more message
|
115
121
|
# into the sender.
|
116
122
|
def stop(join_worker: true)
|
123
|
+
@flush_timer.stop if @flush_timer
|
124
|
+
|
117
125
|
message_queue = @message_queue
|
118
126
|
message_queue << :close if message_queue
|
119
127
|
|
120
|
-
@flush_timer.stop if @flush_timer
|
121
128
|
sender_thread = @sender_thread
|
122
129
|
sender_thread.join if sender_thread && join_worker
|
123
130
|
end
|
@@ -7,12 +7,16 @@ module Datadog
|
|
7
7
|
# It is using current Process.PID to check it is the result of a recent fork
|
8
8
|
# and it is reseting the MessageBuffer if that's the case.
|
9
9
|
class SingleThreadSender
|
10
|
-
def initialize(message_buffer, logger: nil, flush_interval: nil)
|
10
|
+
def initialize(message_buffer, logger: nil, flush_interval: nil, queue_size: 1)
|
11
11
|
@message_buffer = message_buffer
|
12
12
|
@logger = logger
|
13
13
|
@mx = Mutex.new
|
14
|
-
|
15
|
-
|
14
|
+
@message_queue_size = queue_size
|
15
|
+
@message_queue = []
|
16
|
+
@flush_timer = if flush_interval
|
17
|
+
Datadog::Statsd::Timer.new(flush_interval) { flush }
|
18
|
+
else
|
19
|
+
nil
|
16
20
|
end
|
17
21
|
# store the pid for which this sender has been created
|
18
22
|
update_fork_pid
|
@@ -24,15 +28,21 @@ module Datadog
|
|
24
28
|
# not send, they belong to the parent process, let's clear the buffer.
|
25
29
|
if forked?
|
26
30
|
@message_buffer.reset
|
31
|
+
@message_queue.clear
|
27
32
|
@flush_timer.start if @flush_timer && @flush_timer.stop?
|
28
33
|
update_fork_pid
|
29
34
|
end
|
30
|
-
|
35
|
+
|
36
|
+
@message_queue << message
|
37
|
+
if @message_queue.size >= @message_queue_size
|
38
|
+
drain_message_queue
|
39
|
+
end
|
31
40
|
}
|
32
41
|
end
|
33
42
|
|
34
43
|
def flush(*)
|
35
44
|
@mx.synchronize {
|
45
|
+
drain_message_queue
|
36
46
|
@message_buffer.flush()
|
37
47
|
}
|
38
48
|
end
|
@@ -51,6 +61,12 @@ module Datadog
|
|
51
61
|
|
52
62
|
private
|
53
63
|
|
64
|
+
def drain_message_queue
|
65
|
+
while msg = @message_queue.shift
|
66
|
+
@message_buffer.add(msg)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
54
70
|
# below are "fork management" methods to be able to clean the MessageBuffer
|
55
71
|
# if it detects that it is running in a unknown PID.
|
56
72
|
|
data/lib/datadog/statsd/timer.rb
CHANGED
data/lib/datadog/statsd.rb
CHANGED
@@ -76,11 +76,12 @@ module Datadog
|
|
76
76
|
# @option [Logger] logger for debugging
|
77
77
|
# @option [Integer] buffer_max_payload_size max bytes to buffer
|
78
78
|
# @option [Integer] buffer_max_pool_size max messages to buffer
|
79
|
-
# @option [Integer] sender_queue_size size of the sender queue in number of buffers
|
79
|
+
# @option [Integer] sender_queue_size size of the sender queue in number of buffers
|
80
80
|
# @option [Numeric] buffer_flush_interval interval in second to flush buffer
|
81
81
|
# @option [String] socket_path unix socket path
|
82
82
|
# @option [Float] default sample rate if not overridden
|
83
83
|
# @option [Boolean] single_thread flushes the metrics on the main thread instead of in a companion thread
|
84
|
+
# @option [Boolean] delay_serialization delays stat serialization
|
84
85
|
def initialize(
|
85
86
|
host = nil,
|
86
87
|
port = nil,
|
@@ -100,6 +101,7 @@ module Datadog
|
|
100
101
|
logger: nil,
|
101
102
|
|
102
103
|
single_thread: false,
|
104
|
+
delay_serialization: false,
|
103
105
|
|
104
106
|
telemetry_enable: true,
|
105
107
|
telemetry_flush_interval: DEFAULT_TELEMETRY_FLUSH_INTERVAL
|
@@ -112,6 +114,7 @@ module Datadog
|
|
112
114
|
@prefix = @namespace ? "#{@namespace}.".freeze : nil
|
113
115
|
@serializer = Serialization::Serializer.new(prefix: @prefix, global_tags: tags)
|
114
116
|
@sample_rate = sample_rate
|
117
|
+
@delay_serialization = delay_serialization
|
115
118
|
|
116
119
|
@forwarder = Forwarder.new(
|
117
120
|
connection_cfg: ConnectionCfg.new(
|
@@ -133,6 +136,7 @@ module Datadog
|
|
133
136
|
sender_queue_size: sender_queue_size,
|
134
137
|
|
135
138
|
telemetry_flush_interval: telemetry_enable ? telemetry_flush_interval : nil,
|
139
|
+
serializer: serializer
|
136
140
|
)
|
137
141
|
end
|
138
142
|
|
@@ -237,6 +241,26 @@ module Datadog
|
|
237
241
|
send_stats(stat, value, DISTRIBUTION_TYPE, opts)
|
238
242
|
end
|
239
243
|
|
244
|
+
# Reports execution time of the provided block as a distribution.
|
245
|
+
#
|
246
|
+
# If the block fails, the stat is still reported, then the error
|
247
|
+
# is reraised
|
248
|
+
#
|
249
|
+
# @param [String] stat stat name.
|
250
|
+
# @param [Numeric] value distribution value.
|
251
|
+
# @param [Hash] opts the options to create the metric with
|
252
|
+
# @option opts [Numeric] :sample_rate sample rate, 1 for always
|
253
|
+
# @option opts [Array<String>] :tags An array of tags
|
254
|
+
# @example Report the time (in ms) taken to activate an account
|
255
|
+
# $statsd.distribution_time('account.activate') { @account.activate! }
|
256
|
+
def distribution_time(stat, opts = EMPTY_OPTIONS)
|
257
|
+
opts = { sample_rate: opts } if opts.is_a?(Numeric)
|
258
|
+
start = now
|
259
|
+
yield
|
260
|
+
ensure
|
261
|
+
distribution(stat, ((now - start) * 1000).round, opts)
|
262
|
+
end
|
263
|
+
|
240
264
|
# Sends a timing (in ms) for the given stat to the statsd server. The
|
241
265
|
# sample_rate determines what percentage of the time this report is sent. The
|
242
266
|
# statsd server then uses the sample_rate to correctly track the average
|
@@ -405,7 +429,12 @@ module Datadog
|
|
405
429
|
sample_rate = opts[:sample_rate] || @sample_rate || 1
|
406
430
|
|
407
431
|
if sample_rate == 1 || opts[:pre_sampled] || rand <= sample_rate
|
408
|
-
full_stat =
|
432
|
+
full_stat =
|
433
|
+
if @delay_serialization
|
434
|
+
[[stat, delta, type], {tags: opts[:tags], sample_rate: sample_rate}]
|
435
|
+
else
|
436
|
+
serializer.to_stat(stat, delta, type, tags: opts[:tags], sample_rate: sample_rate)
|
437
|
+
end
|
409
438
|
|
410
439
|
forwarder.send_message(full_stat)
|
411
440
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dogstatsd-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rein Henrichs
|
8
8
|
- Karim Bogtob
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-07-10 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: A Ruby DogStatsd client
|
15
15
|
email: code@datadoghq.com
|
@@ -44,9 +44,9 @@ licenses:
|
|
44
44
|
- MIT
|
45
45
|
metadata:
|
46
46
|
bug_tracker_uri: https://github.com/DataDog/dogstatsd-ruby/issues
|
47
|
-
changelog_uri: https://github.com/DataDog/dogstatsd-ruby/blob/v5.
|
48
|
-
documentation_uri: https://www.rubydoc.info/gems/dogstatsd-ruby/5.
|
49
|
-
source_code_uri: https://github.com/DataDog/dogstatsd-ruby/tree/v5.
|
47
|
+
changelog_uri: https://github.com/DataDog/dogstatsd-ruby/blob/v5.6.0/CHANGELOG.md
|
48
|
+
documentation_uri: https://www.rubydoc.info/gems/dogstatsd-ruby/5.6.0
|
49
|
+
source_code_uri: https://github.com/DataDog/dogstatsd-ruby/tree/v5.6.0
|
50
50
|
post_install_message: |2+
|
51
51
|
|
52
52
|
If you are upgrading from v4.x of the dogstatsd-ruby library, note the major change to the threading model:
|
@@ -66,8 +66,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
66
|
- !ruby/object:Gem::Version
|
67
67
|
version: '0'
|
68
68
|
requirements: []
|
69
|
-
rubygems_version: 3.2.
|
70
|
-
signing_key:
|
69
|
+
rubygems_version: 3.2.3
|
70
|
+
signing_key:
|
71
71
|
specification_version: 4
|
72
72
|
summary: A Ruby DogStatsd client
|
73
73
|
test_files: []
|
74
|
+
...
|