statsd-instrument 2.9.2 → 3.0.0.pre1

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +0 -11
  3. data/benchmark/send-metrics-to-dev-null-log +4 -2
  4. data/benchmark/send-metrics-to-local-udp-receiver +7 -6
  5. data/lib/statsd/instrument.rb +35 -69
  6. data/lib/statsd/instrument/assertions.rb +14 -14
  7. data/lib/statsd/instrument/client.rb +0 -10
  8. data/lib/statsd/instrument/environment.rb +1 -23
  9. data/lib/statsd/instrument/expectation.rb +14 -14
  10. data/lib/statsd/instrument/helpers.rb +1 -30
  11. data/lib/statsd/instrument/railtie.rb +0 -4
  12. data/lib/statsd/instrument/strict.rb +12 -118
  13. data/lib/statsd/instrument/version.rb +1 -1
  14. data/test/assertions_test.rb +9 -21
  15. data/test/client_test.rb +11 -0
  16. data/test/environment_test.rb +1 -37
  17. data/test/integration_test.rb +9 -24
  18. data/test/statsd_instrumentation_test.rb +25 -50
  19. data/test/statsd_test.rb +2 -29
  20. metadata +4 -26
  21. data/benchmark/datagram-client +0 -40
  22. data/lib/statsd/instrument/backend.rb +0 -18
  23. data/lib/statsd/instrument/backends/capture_backend.rb +0 -32
  24. data/lib/statsd/instrument/backends/logger_backend.rb +0 -20
  25. data/lib/statsd/instrument/backends/null_backend.rb +0 -9
  26. data/lib/statsd/instrument/backends/udp_backend.rb +0 -152
  27. data/lib/statsd/instrument/legacy_client.rb +0 -301
  28. data/lib/statsd/instrument/metric.rb +0 -155
  29. data/test/assertions_on_legacy_client_test.rb +0 -344
  30. data/test/capture_backend_test.rb +0 -26
  31. data/test/compatibility/dogstatsd_datagram_compatibility_test.rb +0 -161
  32. data/test/deprecations_test.rb +0 -139
  33. data/test/logger_backend_test.rb +0 -22
  34. data/test/metric_test.rb +0 -47
  35. data/test/udp_backend_test.rb +0 -228
@@ -5,15 +5,6 @@ require 'test_helper'
5
5
  class StatsDTest < Minitest::Test
6
6
  include StatsD::Instrument::Assertions
7
7
 
8
- def teardown
9
- StatsD.default_tags = nil
10
- end
11
-
12
- def test_statsd_passed_collections_to_backend
13
- StatsD.backend.expects(:collect_metric).with(instance_of(StatsD::Instrument::Metric))
14
- StatsD.increment('test')
15
- end
16
-
17
8
  def test_statsd_measure_with_explicit_value
18
9
  metric = capture_statsd_call { StatsD.measure('values.foobar', 42) }
19
10
  assert_equal 'values.foobar', metric.name
@@ -21,10 +12,6 @@ class StatsDTest < Minitest::Test
21
12
  assert_equal :ms, metric.type
22
13
  end
23
14
 
24
- def test_statsd_measure_without_value_or_block
25
- assert_raises(ArgumentError) { StatsD.measure('values.foobar', tags: 123) }
26
- end
27
-
28
15
  def test_statsd_measure_with_explicit_value_and_sample_rate
29
16
  metric = capture_statsd_call { StatsD.measure('values.foobar', 42, sample_rate: 0.1) }
30
17
  assert_equal 0.1, metric.sample_rate
@@ -85,7 +72,7 @@ class StatsDTest < Minitest::Test
85
72
 
86
73
  def test_statsd_increment_with_hash_argument
87
74
  metric = capture_statsd_call { StatsD.increment('values.foobar', tags: ['test']) }
88
- assert_equal StatsD.default_sample_rate, metric.sample_rate
75
+ assert_equal StatsD.singleton_client.default_sample_rate, metric.sample_rate
89
76
  assert_equal ['test'], metric.tags
90
77
  assert_equal 1, metric.value
91
78
  end
@@ -98,7 +85,7 @@ class StatsDTest < Minitest::Test
98
85
  end
99
86
 
100
87
  def test_statsd_gauge_without_value
101
- assert_raises(ArgumentError) { StatsD.gauge('values.foobar', tags: 123) }
88
+ assert_raises(ArgumentError) { StatsD.gauge('values.foobar') }
102
89
  end
103
90
 
104
91
  def test_statsd_set
@@ -200,20 +187,6 @@ class StatsDTest < Minitest::Test
200
187
  end
201
188
  end
202
189
 
203
- def test_statsd_default_tags_get_normalized
204
- StatsD.default_tags = { first_tag: 'first_value', second_tag: 'second_value' }
205
- assert_equal ['first_tag:first_value', 'second_tag:second_value'], StatsD.default_tags
206
- end
207
-
208
- def test_name_prefix
209
- StatsD.legacy_singleton_client.stubs(:prefix).returns('prefix')
210
- m = capture_statsd_call { StatsD.increment('counter') }
211
- assert_equal 'prefix.counter', m.name
212
-
213
- m = capture_statsd_call { StatsD.increment('counter', no_prefix: true) }
214
- assert_equal 'counter', m.name
215
- end
216
-
217
190
  protected
218
191
 
219
192
  def capture_statsd_call(&block)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: statsd-instrument
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.2
4
+ version: 3.0.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jesse Storimer
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2019-11-06 00:00:00.000000000 Z
13
+ date: 2019-11-01 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -133,17 +133,11 @@ files:
133
133
  - README.md
134
134
  - Rakefile
135
135
  - benchmark/README.md
136
- - benchmark/datagram-client
137
136
  - benchmark/send-metrics-to-dev-null-log
138
137
  - benchmark/send-metrics-to-local-udp-receiver
139
138
  - lib/statsd-instrument.rb
140
139
  - lib/statsd/instrument.rb
141
140
  - lib/statsd/instrument/assertions.rb
142
- - lib/statsd/instrument/backend.rb
143
- - lib/statsd/instrument/backends/capture_backend.rb
144
- - lib/statsd/instrument/backends/logger_backend.rb
145
- - lib/statsd/instrument/backends/null_backend.rb
146
- - lib/statsd/instrument/backends/udp_backend.rb
147
141
  - lib/statsd/instrument/capture_sink.rb
148
142
  - lib/statsd/instrument/client.rb
149
143
  - lib/statsd/instrument/datagram.rb
@@ -153,10 +147,8 @@ files:
153
147
  - lib/statsd/instrument/environment.rb
154
148
  - lib/statsd/instrument/expectation.rb
155
149
  - lib/statsd/instrument/helpers.rb
156
- - lib/statsd/instrument/legacy_client.rb
157
150
  - lib/statsd/instrument/log_sink.rb
158
151
  - lib/statsd/instrument/matchers.rb
159
- - lib/statsd/instrument/metric.rb
160
152
  - lib/statsd/instrument/null_sink.rb
161
153
  - lib/statsd/instrument/railtie.rb
162
154
  - lib/statsd/instrument/rubocop.rb
@@ -174,28 +166,22 @@ files:
174
166
  - lib/statsd/instrument/version.rb
175
167
  - shipit.rubygems.yml
176
168
  - statsd-instrument.gemspec
177
- - test/assertions_on_legacy_client_test.rb
178
169
  - test/assertions_test.rb
179
170
  - test/benchmark/clock_gettime.rb
180
171
  - test/benchmark/default_tags.rb
181
172
  - test/benchmark/metrics.rb
182
173
  - test/benchmark/tags.rb
183
- - test/capture_backend_test.rb
184
174
  - test/capture_sink_test.rb
185
175
  - test/client_test.rb
186
- - test/compatibility/dogstatsd_datagram_compatibility_test.rb
187
176
  - test/datagram_builder_test.rb
188
177
  - test/datagram_test.rb
189
- - test/deprecations_test.rb
190
178
  - test/dogstatsd_datagram_builder_test.rb
191
179
  - test/environment_test.rb
192
180
  - test/helpers/rubocop_helper.rb
193
181
  - test/helpers_test.rb
194
182
  - test/integration_test.rb
195
183
  - test/log_sink_test.rb
196
- - test/logger_backend_test.rb
197
184
  - test/matchers_test.rb
198
- - test/metric_test.rb
199
185
  - test/null_sink_test.rb
200
186
  - test/rubocop/measure_as_dist_argument_test.rb
201
187
  - test/rubocop/metaprogramming_positional_arguments_test.rb
@@ -209,7 +195,6 @@ files:
209
195
  - test/statsd_instrumentation_test.rb
210
196
  - test/statsd_test.rb
211
197
  - test/test_helper.rb
212
- - test/udp_backend_test.rb
213
198
  - test/udp_sink_test.rb
214
199
  homepage: https://github.com/Shopify/statsd-instrument
215
200
  licenses:
@@ -226,37 +211,31 @@ required_ruby_version: !ruby/object:Gem::Requirement
226
211
  version: '0'
227
212
  required_rubygems_version: !ruby/object:Gem::Requirement
228
213
  requirements:
229
- - - ">="
214
+ - - ">"
230
215
  - !ruby/object:Gem::Version
231
- version: '0'
216
+ version: 1.3.1
232
217
  requirements: []
233
218
  rubygems_version: 3.0.3
234
219
  signing_key:
235
220
  specification_version: 4
236
221
  summary: A StatsD client for Ruby apps
237
222
  test_files:
238
- - test/assertions_on_legacy_client_test.rb
239
223
  - test/assertions_test.rb
240
224
  - test/benchmark/clock_gettime.rb
241
225
  - test/benchmark/default_tags.rb
242
226
  - test/benchmark/metrics.rb
243
227
  - test/benchmark/tags.rb
244
- - test/capture_backend_test.rb
245
228
  - test/capture_sink_test.rb
246
229
  - test/client_test.rb
247
- - test/compatibility/dogstatsd_datagram_compatibility_test.rb
248
230
  - test/datagram_builder_test.rb
249
231
  - test/datagram_test.rb
250
- - test/deprecations_test.rb
251
232
  - test/dogstatsd_datagram_builder_test.rb
252
233
  - test/environment_test.rb
253
234
  - test/helpers/rubocop_helper.rb
254
235
  - test/helpers_test.rb
255
236
  - test/integration_test.rb
256
237
  - test/log_sink_test.rb
257
- - test/logger_backend_test.rb
258
238
  - test/matchers_test.rb
259
- - test/metric_test.rb
260
239
  - test/null_sink_test.rb
261
240
  - test/rubocop/measure_as_dist_argument_test.rb
262
241
  - test/rubocop/metaprogramming_positional_arguments_test.rb
@@ -270,5 +249,4 @@ test_files:
270
249
  - test/statsd_instrumentation_test.rb
271
250
  - test/statsd_test.rb
272
251
  - test/test_helper.rb
273
- - test/udp_backend_test.rb
274
252
  - test/udp_sink_test.rb
@@ -1,40 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'bundler/setup'
5
- require 'benchmark/ips'
6
- require 'socket'
7
-
8
- # Set up an UDP listener to which we can send StatsD packets
9
- legacy_receiver = UDPSocket.new
10
- legacy_receiver.bind('localhost', 0)
11
-
12
- ENV['ENV'] = "production"
13
- ENV['STATSD_ADDR'] = "#{legacy_receiver.addr[2]}:#{legacy_receiver.addr[1]}"
14
- ENV['STATSD_IMPLEMENTATION'] ||= 'datadog'
15
-
16
- require 'statsd-instrument'
17
-
18
- legacy_client = StatsD
19
-
20
- # Set up an UDP listener to which we can send StatsD packets
21
- new_client_receiver = UDPSocket.new
22
- new_client_receiver.bind('localhost', 0)
23
-
24
- udp_sink = StatsD::Instrument::UDPSink.new(new_client_receiver.addr[2], new_client_receiver.addr[1])
25
- new_client = StatsD::Instrument::Client.new(sink: udp_sink, default_sample_rate: StatsD.default_sample_rate)
26
-
27
- Benchmark.ips do |bench|
28
- bench.report("Legacy client (sample rate: #{StatsD.default_sample_rate})") do
29
- legacy_client.increment('StatsD.increment')
30
- end
31
-
32
- bench.report("New client (sample rate: #{StatsD.default_sample_rate})") do
33
- new_client.increment('StatsD.increment')
34
- end
35
-
36
- bench.compare!
37
- end
38
-
39
- legacy_receiver.close
40
- new_client_receiver.close
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # This abstract class specifies the interface a backend implementation should conform to.
4
- # @abstract
5
- class StatsD::Instrument::Backend
6
- # Collects a metric.
7
- #
8
- # @param metric [StatsD::Instrument::Metric] The metric to collect
9
- # @return [void]
10
- def collect_metric(_metric)
11
- raise NotImplementedError, "Use a concrete backend implementation"
12
- end
13
- end
14
-
15
- require 'statsd/instrument/backends/logger_backend'
16
- require 'statsd/instrument/backends/null_backend'
17
- require 'statsd/instrument/backends/capture_backend'
18
- require 'statsd/instrument/backends/udp_backend'
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module StatsD::Instrument::Backends
4
- # The capture backend is used to capture the metrics that are collected, so you can
5
- # run assertions on them.
6
- #
7
- # @!attribute collected_metrics [r]
8
- # @return [Array<StatsD::Instrument::Metric>] The list of metrics that were collected.
9
- # @see StatsD::Instrument::Assertions
10
- class CaptureBackend < StatsD::Instrument::Backend
11
- attr_reader :collected_metrics
12
- attr_accessor :parent
13
-
14
- def initialize
15
- reset
16
- end
17
-
18
- # Adds a metric to the ist of collected metrics.
19
- # @param metric [StatsD::Instrument::Metric] The metric to collect.
20
- # @return [void]
21
- def collect_metric(metric)
22
- parent&.collect_metric(metric)
23
- @collected_metrics << metric
24
- end
25
-
26
- # Resets the list of collected metrics to an empty list.
27
- # @return [void]
28
- def reset
29
- @collected_metrics = []
30
- end
31
- end
32
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module StatsD::Instrument::Backends
4
- # The logger backend simply logs every metric to a logger
5
- # @!attribute logger
6
- # @return [Logger]
7
- class LoggerBackend < StatsD::Instrument::Backend
8
- attr_accessor :logger
9
-
10
- def initialize(logger)
11
- @logger = logger
12
- end
13
-
14
- # @param metric [StatsD::Instrument::Metric]
15
- # @return [void]
16
- def collect_metric(metric)
17
- logger.info("[StatsD] #{metric}")
18
- end
19
- end
20
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module StatsD::Instrument::Backends
4
- # The null backend does nothing when receiving a metric, effectively disabling the gem completely.
5
- class NullBackend < StatsD::Instrument::Backend
6
- def collect_metric(metric)
7
- end
8
- end
9
- end
@@ -1,152 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'monitor'
4
-
5
- module StatsD::Instrument::Backends
6
- class UDPBackend < StatsD::Instrument::Backend
7
- BASE_SUPPORTED_METRIC_TYPES = { c: true, ms: true, g: true, s: true }
8
-
9
- class DogStatsDProtocol
10
- SUPPORTED_METRIC_TYPES = BASE_SUPPORTED_METRIC_TYPES.merge(h: true, _e: true, _sc: true, d: true)
11
-
12
- SERVICE_CHECK_STATUSES = { ok: 0, warning: 1, critical: 2, unknown: 3 }
13
-
14
- def generate_packet(metric)
15
- packet = +""
16
-
17
- if metric.type == :_e
18
- escaped_title = metric.name.gsub("\n", "\\n")
19
- escaped_text = metric.value.gsub("\n", "\\n")
20
-
21
- packet << "_e{#{escaped_title.size},#{escaped_text.size}}:#{escaped_title}|#{escaped_text}"
22
- packet << "|h:#{metric.metadata[:hostname]}" if metric.metadata[:hostname]
23
- packet << "|d:#{metric.metadata[:timestamp].to_i}" if metric.metadata[:timestamp]
24
- packet << "|k:#{metric.metadata[:aggregation_key]}" if metric.metadata[:aggregation_key]
25
- packet << "|p:#{metric.metadata[:priority]}" if metric.metadata[:priority]
26
- packet << "|s:#{metric.metadata[:source_type_name]}" if metric.metadata[:source_type_name]
27
- packet << "|t:#{metric.metadata[:alert_type]}" if metric.metadata[:alert_type]
28
- packet << "|##{metric.tags.join(',')}" if metric.tags
29
-
30
- elsif metric.type == :_sc
31
- status = metric.value.is_a?(Integer) ? metric.value : SERVICE_CHECK_STATUSES.fetch(metric.value.to_sym)
32
-
33
- packet << "_sc|#{metric.name}|#{status}"
34
- packet << "|h:#{metric.metadata[:hostname]}" if metric.metadata[:hostname]
35
- packet << "|d:#{metric.metadata[:timestamp].to_i}" if metric.metadata[:timestamp]
36
- packet << "|##{metric.tags.join(',')}" if metric.tags
37
- packet << "|m:#{metric.metadata[:message]}" if metric.metadata[:message]
38
-
39
- else
40
- packet << "#{metric.name}:#{metric.value}|#{metric.type}"
41
- packet << "|@#{metric.sample_rate}" if metric.sample_rate < 1
42
- packet << "|##{metric.tags.join(',')}" if metric.tags
43
- end
44
-
45
- packet
46
- end
47
- end
48
-
49
- class StatsiteStatsDProtocol
50
- SUPPORTED_METRIC_TYPES = BASE_SUPPORTED_METRIC_TYPES.merge(kv: true)
51
-
52
- def generate_packet(metric)
53
- packet = +"#{metric.name}:#{metric.value}|#{metric.type}"
54
- packet << "|@#{metric.sample_rate}" unless metric.sample_rate == 1
55
- packet << "\n"
56
- packet
57
- end
58
- end
59
-
60
- class StatsDProtocol
61
- SUPPORTED_METRIC_TYPES = BASE_SUPPORTED_METRIC_TYPES
62
-
63
- def generate_packet(metric)
64
- packet = +"#{metric.name}:#{metric.value}|#{metric.type}"
65
- packet << "|@#{metric.sample_rate}" if metric.sample_rate < 1
66
- packet
67
- end
68
- end
69
-
70
- DEFAULT_IMPLEMENTATION = :statsd
71
-
72
- include MonitorMixin
73
-
74
- attr_reader :host, :port, :implementation
75
-
76
- def initialize(server = nil, implementation = nil)
77
- super()
78
- self.server = server || "localhost:8125"
79
- self.implementation = (implementation || DEFAULT_IMPLEMENTATION).to_sym
80
- end
81
-
82
- def implementation=(value)
83
- @packet_factory = case value
84
- when :datadog
85
- DogStatsDProtocol.new
86
- when :statsite
87
- StatsiteStatsDProtocol.new
88
- else
89
- StatsDProtocol.new
90
- end
91
- @implementation = value
92
- end
93
-
94
- def collect_metric(metric)
95
- unless @packet_factory.class::SUPPORTED_METRIC_TYPES[metric.type]
96
- StatsD.logger.warn("[StatsD] Metric type #{metric.type.inspect} is not supported " \
97
- "on #{implementation} implementation.")
98
- return false
99
- end
100
-
101
- if metric.sample_rate < 1.0 && rand > metric.sample_rate
102
- return false
103
- end
104
-
105
- write_packet(@packet_factory.generate_packet(metric))
106
- end
107
-
108
- def server=(connection_string)
109
- @host, @port = connection_string.split(':', 2)
110
- @port = @port.to_i
111
- invalidate_socket
112
- end
113
-
114
- def host=(host)
115
- @host = host
116
- invalidate_socket
117
- end
118
-
119
- def port=(port)
120
- @port = port
121
- invalidate_socket
122
- end
123
-
124
- def socket
125
- if @socket.nil?
126
- @socket = UDPSocket.new
127
- @socket.connect(host, port)
128
- end
129
- @socket
130
- end
131
-
132
- def write_packet(command)
133
- synchronize do
134
- socket.send(command, 0) > 0
135
- end
136
- rescue ThreadError
137
- # In cases where a TERM or KILL signal has been sent, and we send stats as
138
- # part of a signal handler, locks cannot be acquired, so we do our best
139
- # to try and send the command without a lock.
140
- socket.send(command, 0) > 0
141
- rescue SocketError, IOError, SystemCallError => e
142
- StatsD.logger.error("[StatsD] #{e.class.name}: #{e.message}")
143
- invalidate_socket
144
- end
145
-
146
- def invalidate_socket
147
- synchronize do
148
- @socket = nil
149
- end
150
- end
151
- end
152
- end