statsd-instrument 3.9.7 → 3.9.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f878f6a9d5a1ebb2aa0459eec131628d04a19b85b9cd7bc4b0493f5bc946423f
4
- data.tar.gz: 41e2a93dd2257655bc64235aebf4637751101f69da4f342aeaab5a3b56bf21e3
3
+ metadata.gz: 6aa9b8412d646528092adba3cbfcf173e80c4c9f6a69ce2a49db6c74d74fded6
4
+ data.tar.gz: 38aaac366290965b067e2e167bffa030aa90d185e595e7c6ed1d687683607bb0
5
5
  SHA512:
6
- metadata.gz: 4aaf2c5f29bcf2c815298d8047208be603c360d2c3c4cd342fd77c0337f310fffb51c0d3706338d922e0125fdad824084097828910ef422933f2526411904523
7
- data.tar.gz: ba4d68b8078cb033ec887f35d8682c7771291b3197a054269aa5e44ab6538f29f0b261e3b8c6a5259e02cf3a7f9aa0376ad21fb7cd709b50fc4b516e7ba6b4cf
6
+ metadata.gz: 32cbfe82af236e100778e9367ed1c7cf5a1b4c2ed4bed6969d1e319738eddfe192c0e521c2917ac4b4af5ac1e4e36f3f551828fa9fc69a06e9009d015726f465
7
+ data.tar.gz: 0ac5714732d77dcda2ac89ea92dfd51ae99ed1cc021766eaed26e7b28310181c51c5a095ed545862be513a8b17348811715dff2760f6a9ae58dd431a5337080a
@@ -4,16 +4,12 @@ on: push
4
4
 
5
5
  jobs:
6
6
  test:
7
- name: Ruby ${{ matrix.ruby }} on ubuntu-latest
8
- runs-on: ubuntu-latest
7
+ name: Ruby ${{ matrix.ruby }} on ubuntu-22.04
8
+ runs-on: ubuntu-22.04
9
9
  strategy:
10
10
  fail-fast: false
11
11
  matrix:
12
- ruby: ['2.6', '2.7', '3.0', '3.1', '3.2', '3.3', 'ruby-head', 'jruby-9.4.8.0', 'truffleruby-22.3.1']
13
- # Windows on macOS builds started failing, so they are disabled for now
14
- # platform: [windows-2019, macOS-10.14, ubuntu-18.04]
15
- # exclude:
16
- # ...
12
+ ruby: ['2.7', '3.0', '3.1', '3.2', '3.3', 'ruby-head', 'jruby-9.4.9.0', 'truffleruby-22.3.1']
17
13
 
18
14
  steps:
19
15
  - uses: actions/checkout@v4
data/CHANGELOG.md CHANGED
@@ -6,6 +6,11 @@ section below.
6
6
 
7
7
  ## Unreleased changes
8
8
 
9
+ ## Version 3.9.8
10
+
11
+ - [#390](https://github.com/Shopify/statsd-instrument/pull/391) - Fixing bug in Environment when using UDS. The max packet size option was not being passed to the
12
+ UDS connection, causing messages that were too large to be dropped (specially sensitive when used together with BatchedSink).
13
+
9
14
  ## Version 3.9.7
10
15
 
11
16
  - [#389](https://github.com/Shopify/statsd-instrument/pull/389) - Fixing bug with BatchedSink constructor when using UDS, the constructor was not properly passing the Sink to the BatchedSink.
data/Makefile ADDED
@@ -0,0 +1,11 @@
1
+ .PHONY: test lint update
2
+ test:
3
+ bundle exec rake test
4
+
5
+ lint:
6
+ bundle exec rake lint_fix
7
+
8
+ update:
9
+ bundle update
10
+
11
+ check: update lint test
@@ -10,6 +10,24 @@ require "datadog/statsd"
10
10
  require "forwardable"
11
11
  require "vernier"
12
12
 
13
+ module Datadog
14
+ class Statsd
15
+ class Telemetry
16
+ def flush
17
+ ["bytes", "packets"].each do |kind|
18
+ ["sent", "dropped", "dropped_queue", "dropped_writer"].each do |measure|
19
+ var = "#{kind}_#{measure}"
20
+ puts "#{var}: #{instance_variable_get("@#{var}".to_sym)}"
21
+ end
22
+ end
23
+ puts "-" * 10
24
+
25
+ []
26
+ end
27
+ end
28
+ end
29
+ end
30
+
13
31
  class DatadogShim
14
32
  extend Forwardable
15
33
 
@@ -222,3 +240,40 @@ benchmark_implementation(
222
240
  if ENABLE_PROFILING
223
241
  Vernier.stop_profile
224
242
  end
243
+
244
+ if ENABLE_PROFILING
245
+ Vernier.start_profile(out: "tmp/benchmark_profile_datadog.json")
246
+ end
247
+ benchmark_implementation(
248
+ "Datadog client with UDP and delayed serialization",
249
+ {
250
+ buffer_max_payload_size: 4096,
251
+ delay_serialization: true,
252
+ telemetry_flush_interval: 1,
253
+ # The datadog implemtation will drop metrics if the queue is full
254
+ # to imitate the behavior of the implementation of this gem, we set
255
+ # the queue size to infinity to avoid dropping metrics.
256
+ sender_queue_size: Float::INFINITY,
257
+ },
258
+ true,
259
+ )
260
+ if ENABLE_PROFILING
261
+ Vernier.stop_profile
262
+ end
263
+
264
+ if ENABLE_PROFILING
265
+ Vernier.start_profile(out: "tmp/benchmark_profile_datadog.json")
266
+ end
267
+ benchmark_implementation(
268
+ "UDP - Datadog gem - using: delay_serialization, multi-threaded, allow dropping samples",
269
+ {
270
+ buffer_max_payload_size: 4096,
271
+ delay_serialization: true,
272
+ telemetry_flush_interval: 1,
273
+ sender_queue_size: 250_000,
274
+ },
275
+ true,
276
+ )
277
+ if ENABLE_PROFILING
278
+ Vernier.stop_profile
279
+ end
@@ -459,7 +459,6 @@ module StatsD
459
459
  # @note Supported by the Datadog implementation only.
460
460
  def event(title, text, timestamp: nil, hostname: nil, aggregation_key: nil, priority: nil,
461
461
  source_type_name: nil, alert_type: nil, tags: nil, no_prefix: false)
462
-
463
462
  emit(datagram_builder(no_prefix: no_prefix)._e(
464
463
  title,
465
464
  text,
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StatsD
4
+ module Instrument
5
+ module ConnectionBehavior
6
+ def close
7
+ @socket&.close
8
+ rescue IOError, SystemCallError => e
9
+ StatsD.logger.debug do
10
+ "[#{self.class.name}] Error closing socket: #{e.class}: #{e.message}"
11
+ end
12
+ ensure
13
+ @socket = nil
14
+ end
15
+
16
+ def send_buffer_size
17
+ if socket
18
+ send_buffer_size_from_socket(socket)
19
+ else
20
+ @max_packet_size
21
+ end
22
+ end
23
+
24
+ def type
25
+ raise NotImplementedError, "#{self.class} must implement #type"
26
+ end
27
+
28
+ private
29
+
30
+ def send_buffer_size_from_socket(original_socket)
31
+ original_socket.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).int
32
+ end
33
+
34
+ def setup_socket(original_socket)
35
+ original_socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, @max_packet_size.to_i)
36
+ if send_buffer_size_from_socket(original_socket) < @max_packet_size
37
+ StatsD.logger.warn do
38
+ "[#{self.class.name}] Could not set socket send buffer size to #{@max_packet_size} " \
39
+ "allowed size by environment/OS is (#{send_buffer_size_from_socket(original_socket)})."
40
+ end
41
+ end
42
+ original_socket
43
+ rescue IOError => e
44
+ StatsD.logger.debug do
45
+ "[#{self.class.name}] Failed to create socket: #{e.class}: #{e.message}"
46
+ end
47
+ nil
48
+ end
49
+ end
50
+ end
51
+ end
@@ -33,7 +33,6 @@ module StatsD
33
33
  # @see https://docs.datadoghq.com/developers/dogstatsd/datagram_shell/#events
34
34
  def _e(title, text, timestamp: nil, hostname: nil, aggregation_key: nil, priority: nil,
35
35
  source_type_name: nil, alert_type: nil, tags: nil)
36
-
37
36
  escaped_title = "#{@prefix}#{title}".gsub("\n", '\n')
38
37
  escaped_text = text.gsub("\n", '\n')
39
38
 
@@ -104,10 +104,10 @@ module StatsD
104
104
 
105
105
  def statsd_max_packet_size
106
106
  if statsd_uds_send?
107
- return Float(env.fetch("STATSD_MAX_PACKET_SIZE", StatsD::Instrument::UdsConnection::DEFAULT_MAX_PACKET_SIZE))
107
+ Integer(env.fetch("STATSD_MAX_PACKET_SIZE", StatsD::Instrument::UdsConnection::DEFAULT_MAX_PACKET_SIZE))
108
+ else
109
+ Integer(env.fetch("STATSD_MAX_PACKET_SIZE", StatsD::Instrument::UdpConnection::DEFAULT_MAX_PACKET_SIZE))
108
110
  end
109
-
110
- Float(env.fetch("STATSD_MAX_PACKET_SIZE", StatsD::Instrument::UdpConnection::DEFAULT_MAX_PACKET_SIZE))
111
111
  end
112
112
 
113
113
  def statsd_batch_statistics_interval
@@ -140,19 +140,32 @@ module StatsD
140
140
  case environment
141
141
  when "production", "staging"
142
142
  connection = if statsd_uds_send?
143
- StatsD::Instrument::UdsConnection.new(statsd_socket_path)
143
+ StatsD::Instrument::UdsConnection.new(
144
+ statsd_socket_path,
145
+ max_packet_size: statsd_max_packet_size,
146
+ )
144
147
  else
145
148
  host, port = statsd_addr.split(":")
146
- StatsD::Instrument::UdpConnection.new(host, port.to_i)
149
+ StatsD::Instrument::UdpConnection.new(
150
+ host,
151
+ port.to_i,
152
+ max_packet_size: statsd_max_packet_size,
153
+ )
147
154
  end
148
155
 
149
156
  sink = StatsD::Instrument::Sink.new(connection)
150
157
  if statsd_batching?
151
- # if we are batching, wrap the sink in a batched sink
158
+ current_send_buffer_size = connection.send_buffer_size
159
+ if current_send_buffer_size < statsd_max_packet_size
160
+ StatsD.logger.warn do
161
+ "[StatsD::Instrument::Environment] Send buffer size #{current_send_buffer_size} differs from " \
162
+ "max packet size #{statsd_max_packet_size}. Using send buffer size as max packet size."
163
+ end
164
+ end
152
165
  return StatsD::Instrument::BatchedSink.new(
153
166
  sink,
154
167
  buffer_capacity: statsd_buffer_capacity,
155
- max_packet_size: statsd_max_packet_size,
168
+ max_packet_size: [current_send_buffer_size, statsd_max_packet_size].min,
156
169
  statistics_interval: statsd_batch_statistics_interval,
157
170
  )
158
171
  end
@@ -36,7 +36,6 @@ module StatsD
36
36
 
37
37
  def initialize(client: nil, type:, name:, value: nil,
38
38
  sample_rate: nil, tags: nil, no_prefix: false, times: 1)
39
-
40
39
  @type = type
41
40
  @name = no_prefix ? name : StatsD::Instrument::Helpers.prefix_metric(name, client: client)
42
41
  @value = normalized_value_for_type(type, value) if value
@@ -40,12 +40,15 @@ module StatsD
40
40
  connection.send_datagram(datagram)
41
41
  rescue SocketError, IOError, SystemCallError => error
42
42
  StatsD.logger.debug do
43
- "[#{self.class.name}] Resetting connection because of #{error.class}: #{error.message}"
43
+ "[#{self.class.name}] [#{connection.class.name}] " \
44
+ "Resetting connection because of #{error.class}: #{error.message}"
44
45
  end
45
46
  invalidate_connection
46
47
  if retried
47
48
  StatsD.logger.warn do
48
- "[#{self.class.name}] Events were dropped because of #{error.class}: #{error.message}"
49
+ "[#{self.class.name}] [#{connection.class.name}] " \
50
+ "Events were dropped (after retrying) because of #{error.class}: #{error.message}. " \
51
+ "Message size: #{datagram.bytesize} bytes."
49
52
  end
50
53
  else
51
54
  retried = true
@@ -65,7 +65,6 @@ module StatsD
65
65
 
66
66
  def event(title, text, tags: nil, no_prefix: false,
67
67
  hostname: nil, timestamp: nil, aggregation_key: nil, priority: nil, source_type_name: nil, alert_type: nil)
68
-
69
68
  super
70
69
  end
71
70
 
@@ -3,24 +3,22 @@
3
3
  module StatsD
4
4
  module Instrument
5
5
  class UdpConnection
6
+ include ConnectionBehavior
7
+
6
8
  DEFAULT_MAX_PACKET_SIZE = 1_472
7
9
 
8
10
  attr_reader :host, :port
9
11
 
10
- def initialize(host, port)
12
+ def initialize(host, port, max_packet_size: DEFAULT_MAX_PACKET_SIZE)
11
13
  @host = host
12
14
  @port = port
15
+ @max_packet_size = max_packet_size
13
16
  end
14
17
 
15
18
  def send_datagram(message)
16
19
  socket.send(message, 0)
17
20
  end
18
21
 
19
- def close
20
- @socket&.close
21
- @socket = nil
22
- end
23
-
24
22
  def type
25
23
  :udp
26
24
  end
@@ -29,9 +27,10 @@ module StatsD
29
27
 
30
28
  def socket
31
29
  @socket ||= begin
32
- socket = UDPSocket.new
33
- socket.connect(@host, @port)
34
- socket
30
+ udp_socket = UDPSocket.new
31
+ setup_socket(udp_socket)&.tap do |s|
32
+ s.connect(@host, @port)
33
+ end
35
34
  end
36
35
  end
37
36
  end
@@ -3,6 +3,8 @@
3
3
  module StatsD
4
4
  module Instrument
5
5
  class UdsConnection
6
+ include ConnectionBehavior
7
+
6
8
  DEFAULT_MAX_PACKET_SIZE = 8_192
7
9
 
8
10
  def initialize(socket_path, max_packet_size: DEFAULT_MAX_PACKET_SIZE)
@@ -17,12 +19,7 @@ module StatsD
17
19
  end
18
20
 
19
21
  def send_datagram(message)
20
- socket.sendmsg(message, 0)
21
- end
22
-
23
- def close
24
- @socket&.close
25
- @socket = nil
22
+ socket&.sendmsg(message, 0)
26
23
  end
27
24
 
28
25
  def host
@@ -41,10 +38,10 @@ module StatsD
41
38
 
42
39
  def socket
43
40
  @socket ||= begin
44
- socket = Socket.new(Socket::AF_UNIX, Socket::SOCK_DGRAM)
45
- socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, @max_packet_size.to_i)
46
- socket.connect(Socket.pack_sockaddr_un(@socket_path))
47
- socket
41
+ unix_socket = Socket.new(Socket::AF_UNIX, Socket::SOCK_DGRAM)
42
+ setup_socket(unix_socket)&.tap do |s|
43
+ s.connect(Socket.pack_sockaddr_un(@socket_path))
44
+ end
48
45
  end
49
46
  end
50
47
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module StatsD
4
4
  module Instrument
5
- VERSION = "3.9.7"
5
+ VERSION = "3.9.8"
6
6
  end
7
7
  end
@@ -401,6 +401,7 @@ require "statsd/instrument/environment"
401
401
  require "statsd/instrument/helpers"
402
402
  require "statsd/instrument/assertions"
403
403
  require "statsd/instrument/expectation"
404
+ require "statsd/instrument/connection_behavior"
404
405
  require "statsd/instrument/uds_connection"
405
406
  require "statsd/instrument/udp_connection"
406
407
  require "statsd/instrument/sink"
@@ -76,4 +76,93 @@ class EnvironmentTest < Minitest::Test
76
76
  )
77
77
  assert_kind_of(StatsD::Instrument::Sink, env.client.sink)
78
78
  end
79
+
80
+ def test_client_from_env_uses_uds_sink_with_correct_packet_size_in_production
81
+ skip_on_jruby("JRuby does not support UNIX domain sockets")
82
+ socket_path = "/tmp/statsd-test-#{Process.pid}.sock"
83
+
84
+ # Create a UDS server socket
85
+ server = Socket.new(Socket::AF_UNIX, Socket::SOCK_DGRAM)
86
+ server.bind(Socket.pack_sockaddr_un(socket_path))
87
+
88
+ env = StatsD::Instrument::Environment.new(
89
+ "STATSD_ENV" => "production",
90
+ "STATSD_SOCKET_PATH" => socket_path,
91
+ "STATSD_MAX_PACKET_SIZE" => "65507",
92
+ "STATSD_USE_NEW_CLIENT" => "1",
93
+ )
94
+
95
+ begin
96
+ client = env.client
97
+ sink = client.sink
98
+ connection = sink.connection
99
+
100
+ assert_kind_of(StatsD::Instrument::UdsConnection, connection)
101
+ assert_equal(65507, connection.instance_variable_get(:@max_packet_size))
102
+ ensure
103
+ server.close
104
+ File.unlink(socket_path) if File.exist?(socket_path)
105
+ end
106
+ end
107
+
108
+ def test_client_from_env_uses_default_packet_size_for_uds_when_not_specified
109
+ skip_on_jruby("JRuby does not support UNIX domain sockets")
110
+ socket_path = "/tmp/statsd-test-#{Process.pid}-default.sock"
111
+
112
+ # Create a UDS server socket
113
+ server = Socket.new(Socket::AF_UNIX, Socket::SOCK_DGRAM)
114
+ server.bind(Socket.pack_sockaddr_un(socket_path))
115
+
116
+ env = StatsD::Instrument::Environment.new(
117
+ "STATSD_ENV" => "production",
118
+ "STATSD_SOCKET_PATH" => socket_path,
119
+ "STATSD_USE_NEW_CLIENT" => "1",
120
+ )
121
+
122
+ begin
123
+ client = env.client
124
+ sink = client.sink
125
+ connection = sink.connection
126
+
127
+ assert_kind_of(StatsD::Instrument::UdsConnection, connection)
128
+ assert_equal(
129
+ StatsD::Instrument::UdsConnection::DEFAULT_MAX_PACKET_SIZE,
130
+ connection.instance_variable_get(:@max_packet_size),
131
+ )
132
+ ensure
133
+ server.close
134
+ File.unlink(socket_path) if File.exist?(socket_path)
135
+ end
136
+ end
137
+
138
+ def test_client_from_env_uses_batched_uds_sink_with_correct_packet_size
139
+ skip_on_jruby("JRuby does not support UNIX domain sockets")
140
+ socket_path = "/tmp/statsd-test-#{Process.pid}-batched.sock"
141
+
142
+ # Create a UDS server socket
143
+ server = Socket.new(Socket::AF_UNIX, Socket::SOCK_DGRAM)
144
+ server.bind(Socket.pack_sockaddr_un(socket_path))
145
+
146
+ env = StatsD::Instrument::Environment.new(
147
+ "STATSD_ENV" => "production",
148
+ "STATSD_SOCKET_PATH" => socket_path,
149
+ "STATSD_MAX_PACKET_SIZE" => "65507",
150
+ "STATSD_BUFFER_CAPACITY" => "1000",
151
+ "STATSD_USE_NEW_CLIENT" => "1",
152
+ )
153
+
154
+ begin
155
+ client = env.client
156
+ sink = client.sink
157
+ assert_kind_of(StatsD::Instrument::BatchedSink, sink)
158
+
159
+ underlying_sink = sink.instance_variable_get(:@sink)
160
+ connection = underlying_sink.connection
161
+ assert_kind_of(StatsD::Instrument::UdsConnection, connection)
162
+ assert_equal(65507, connection.instance_variable_get(:@max_packet_size))
163
+ ensure
164
+ server.close
165
+ File.unlink(socket_path) if File.exist?(socket_path)
166
+ end
167
+ end
79
168
  end
data/test/test_helper.rb CHANGED
@@ -30,6 +30,15 @@ module StatsD
30
30
  end
31
31
  end
32
32
 
33
+ # Add helper methods available to all tests
34
+ module Minitest
35
+ class Test
36
+ def skip_on_jruby(message = "Test skipped on JRuby")
37
+ skip(message) if RUBY_ENGINE == "jruby"
38
+ end
39
+ end
40
+ end
41
+
33
42
  StatsD.logger = Logger.new(File::NULL)
34
43
 
35
44
  Thread.abort_on_exception = true
@@ -149,9 +149,27 @@ class UDPSinkTest < Minitest::Test
149
149
  UDPSocket.stubs(:new).returns(socket = mock("socket"))
150
150
 
151
151
  seq = sequence("connect_fail_connect_succeed")
152
+
153
+ # First attempt
154
+ socket.expects(:setsockopt)
155
+ .with(Socket::SOL_SOCKET, Socket::SO_SNDBUF, StatsD::Instrument::UdpConnection::DEFAULT_MAX_PACKET_SIZE)
156
+ .in_sequence(seq)
157
+ socket.expects(:getsockopt)
158
+ .with(Socket::SOL_SOCKET, Socket::SO_SNDBUF)
159
+ .returns(mock(int: StatsD::Instrument::UdpConnection::DEFAULT_MAX_PACKET_SIZE))
160
+ .in_sequence(seq)
152
161
  socket.expects(:connect).with("localhost", 8125).in_sequence(seq)
153
162
  socket.expects(:send).raises(Errno::EDESTADDRREQ).in_sequence(seq)
154
163
  socket.expects(:close).in_sequence(seq)
164
+
165
+ # Second attempt after error
166
+ socket.expects(:setsockopt)
167
+ .with(Socket::SOL_SOCKET, Socket::SO_SNDBUF, StatsD::Instrument::UdpConnection::DEFAULT_MAX_PACKET_SIZE)
168
+ .in_sequence(seq)
169
+ socket.expects(:getsockopt)
170
+ .with(Socket::SOL_SOCKET, Socket::SO_SNDBUF)
171
+ .returns(mock(int: StatsD::Instrument::UdpConnection::DEFAULT_MAX_PACKET_SIZE))
172
+ .in_sequence(seq)
155
173
  socket.expects(:connect).with("localhost", 8125).in_sequence(seq)
156
174
  socket.expects(:send).twice.returns(1).in_sequence(seq)
157
175
  socket.expects(:close).in_sequence(seq)
@@ -161,7 +179,8 @@ class UDPSinkTest < Minitest::Test
161
179
  udp_sink << "bar:1|c"
162
180
 
163
181
  assert_equal(
164
- "[#{@sink_class}] Resetting connection because of " \
182
+ "[#{@sink_class}] [#{@sink_class.for_addr("localhost:8125").connection.class}] " \
183
+ "Resetting connection because of " \
165
184
  "Errno::EDESTADDRREQ: Destination address required\n",
166
185
  logs.string,
167
186
  )
@@ -35,10 +35,6 @@ module UdsTestHelper
35
35
  @sink ||= build_sink(@socket_path)
36
36
  end
37
37
 
38
- def skip_on_jruby(message = "JRuby does not support UNIX domain sockets")
39
- skip(message) if RUBY_PLATFORM == "java"
40
- end
41
-
42
38
  def read_datagrams(count, timeout: ENV["CI"] ? 5 : 1)
43
39
  datagrams = []
44
40
  count.times do
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: statsd-instrument
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.9.7
4
+ version: 3.9.8
5
5
  platform: ruby
6
+ original_platform: ''
6
7
  authors:
7
8
  - Jesse Storimer
8
9
  - Tobias Lutke
9
10
  - Willem van Bergen
10
- autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-11-06 00:00:00.000000000 Z
13
+ date: 2024-12-19 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: A StatsD client for Ruby apps. Provides metaprogramming methods to inject
16
16
  StatsD instrumentation into your code.
@@ -34,6 +34,7 @@ files:
34
34
  - CONTRIBUTING.md
35
35
  - Gemfile
36
36
  - LICENSE
37
+ - Makefile
37
38
  - README.md
38
39
  - Rakefile
39
40
  - benchmark/README.md
@@ -49,6 +50,7 @@ files:
49
50
  - lib/statsd/instrument/batched_sink.rb
50
51
  - lib/statsd/instrument/capture_sink.rb
51
52
  - lib/statsd/instrument/client.rb
53
+ - lib/statsd/instrument/connection_behavior.rb
52
54
  - lib/statsd/instrument/datagram.rb
53
55
  - lib/statsd/instrument/datagram_builder.rb
54
56
  - lib/statsd/instrument/dogstatsd_datagram.rb
@@ -115,7 +117,6 @@ licenses:
115
117
  - MIT
116
118
  metadata:
117
119
  allowed_push_host: https://rubygems.org
118
- post_install_message:
119
120
  rdoc_options: []
120
121
  require_paths:
121
122
  - lib
@@ -130,8 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
131
  - !ruby/object:Gem::Version
131
132
  version: '0'
132
133
  requirements: []
133
- rubygems_version: 3.5.23
134
- signing_key:
134
+ rubygems_version: 3.6.1
135
135
  specification_version: 4
136
136
  summary: A StatsD client for Ruby apps
137
137
  test_files: