statsd-instrument 2.3.2 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/workflows/ci.yml +31 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +1027 -0
  6. data/.rubocop.yml +21 -0
  7. data/CHANGELOG.md +41 -0
  8. data/CONTRIBUTING.md +26 -6
  9. data/Gemfile +2 -0
  10. data/Rakefile +3 -1
  11. data/lib/statsd/instrument/assertions.rb +24 -18
  12. data/lib/statsd/instrument/backend.rb +3 -2
  13. data/lib/statsd/instrument/backends/capture_backend.rb +2 -1
  14. data/lib/statsd/instrument/backends/logger_backend.rb +3 -3
  15. data/lib/statsd/instrument/backends/null_backend.rb +2 -0
  16. data/lib/statsd/instrument/backends/udp_backend.rb +20 -17
  17. data/lib/statsd/instrument/environment.rb +2 -0
  18. data/lib/statsd/instrument/helpers.rb +6 -2
  19. data/lib/statsd/instrument/matchers.rb +14 -11
  20. data/lib/statsd/instrument/metric.rb +34 -21
  21. data/lib/statsd/instrument/metric_expectation.rb +32 -18
  22. data/lib/statsd/instrument/railtie.rb +2 -1
  23. data/lib/statsd/instrument/version.rb +3 -1
  24. data/lib/statsd/instrument.rb +85 -36
  25. data/lib/statsd-instrument.rb +2 -0
  26. data/statsd-instrument.gemspec +13 -10
  27. data/test/assertions_test.rb +15 -4
  28. data/test/benchmark/default_tags.rb +47 -0
  29. data/test/benchmark/metrics.rb +9 -8
  30. data/test/benchmark/tags.rb +5 -3
  31. data/test/capture_backend_test.rb +4 -2
  32. data/test/environment_test.rb +2 -1
  33. data/test/helpers_test.rb +2 -1
  34. data/test/integration_test.rb +27 -7
  35. data/test/logger_backend_test.rb +10 -8
  36. data/test/matchers_test.rb +34 -20
  37. data/test/metric_test.rb +15 -4
  38. data/test/statsd_instrumentation_test.rb +7 -7
  39. data/test/statsd_test.rb +100 -10
  40. data/test/test_helper.rb +2 -0
  41. data/test/udp_backend_test.rb +5 -28
  42. metadata +23 -5
  43. data/.travis.yml +0 -12
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This Railtie runs some initializers that will set the logger to <tt>Rails#logger</tt>,
2
4
  # and will initialize the {StatsD#backend} based on the Rails environment.
3
5
  #
4
6
  # @see StatsD::Instrument::Environment
5
7
  class StatsD::Instrument::Railtie < Rails::Railtie
6
-
7
8
  initializer 'statsd-instrument.use_rails_logger' do
8
9
  ::StatsD.logger = Rails.logger
9
10
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module StatsD
2
4
  module Instrument
3
- VERSION = "2.3.2"
5
+ VERSION = "2.4.0"
4
6
  end
5
7
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'socket'
2
4
  require 'logger'
3
5
 
@@ -28,6 +30,10 @@ require 'logger'
28
30
  # The logger to use in case of any errors. The logger is also used as default logger
29
31
  # for the LoggerBackend (although this can be overwritten).
30
32
  #
33
+ # @!attribute default_tags
34
+ # The tags to apply to all metrics.
35
+ # @return [Array<String>, Hash<String, String>, nil] The default tags, or <tt>nil</tt> when no default tags is used
36
+ #
31
37
  # @see StatsD::Instrument::Backends::LoggerBackend
32
38
  # @return [Logger]
33
39
  #
@@ -58,20 +64,26 @@ module StatsD
58
64
 
59
65
  if Process.respond_to?(:clock_gettime)
60
66
  # @private
61
- def self.duration
62
- start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
63
- yield
64
- Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
67
+ def self.current_timestamp
68
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
65
69
  end
66
70
  else
67
71
  # @private
68
- def self.duration
69
- start = Time.now
70
- yield
71
- Time.now - start
72
+ def self.current_timestamp
73
+ Time.now
72
74
  end
73
75
  end
74
76
 
77
+ # Even though this method is considered private, and is no longer used internally,
78
+ # applications in the wild rely on it. As a result, we cannot remove this method
79
+ # until the next major version.
80
+ # @private
81
+ def self.duration
82
+ start = current_timestamp
83
+ yield
84
+ current_timestamp - start
85
+ end
86
+
75
87
  # Adds execution duration instrumentation to a method as a timing.
76
88
  #
77
89
  # @param method [Symbol] The name of the method to instrument.
@@ -82,7 +94,8 @@ module StatsD
82
94
  def statsd_measure(method, name, *metric_options)
83
95
  add_to_method(method, name, :measure) do
84
96
  define_method(method) do |*args, &block|
85
- StatsD.measure(StatsD::Instrument.generate_metric_name(name, self, *args), *metric_options) { super(*args, &block) }
97
+ metric_name = StatsD::Instrument.generate_metric_name(name, self, *args)
98
+ StatsD.measure(metric_name, *metric_options) { super(*args, &block) }
86
99
  end
87
100
  end
88
101
  end
@@ -98,7 +111,8 @@ module StatsD
98
111
  def statsd_distribution(method, name, *metric_options)
99
112
  add_to_method(method, name, :distribution) do
100
113
  define_method(method) do |*args, &block|
101
- StatsD.distribution(StatsD::Instrument.generate_metric_name(name, self, *args), *metric_options) { super(*args, &block) }
114
+ metric_name = StatsD::Instrument.generate_metric_name(name, self, *args)
115
+ StatsD.distribution(metric_name, *metric_options) { super(*args, &block) }
102
116
  end
103
117
  end
104
118
  end
@@ -127,20 +141,27 @@ module StatsD
127
141
  truthiness = false
128
142
  raise
129
143
  else
130
- truthiness = (yield(result) rescue false) if block_given?
144
+ if block_given?
145
+ begin
146
+ truthiness = yield(result)
147
+ rescue
148
+ truthiness = false
149
+ end
150
+ end
131
151
  result
132
152
  ensure
133
153
  suffix = truthiness == false ? 'failure' : 'success'
134
- StatsD.increment("#{StatsD::Instrument.generate_metric_name(name, self, *args)}.#{suffix}", 1, *metric_options)
154
+ metric_name = "#{StatsD::Instrument.generate_metric_name(name, self, *args)}.#{suffix}"
155
+ StatsD.increment(metric_name, 1, *metric_options)
135
156
  end
136
157
  end
137
158
  end
138
159
  end
139
160
 
140
- # Adds success and failure counter instrumentation to a method.
161
+ # Adds success counter instrumentation to a method.
141
162
  #
142
163
  # A method call will be considered successful if it does not raise an exception, and the result is true-y.
143
- # Only for successful calls, the metric will be icnremented
164
+ # Only for successful calls, the metric will be incremented.
144
165
  #
145
166
  # @param method (see #statsd_measure)
146
167
  # @param name (see #statsd_measure)
@@ -159,10 +180,19 @@ module StatsD
159
180
  truthiness = false
160
181
  raise
161
182
  else
162
- truthiness = (yield(result) rescue false) if block_given?
183
+ if block_given?
184
+ begin
185
+ truthiness = yield(result)
186
+ rescue
187
+ truthiness = false
188
+ end
189
+ end
163
190
  result
164
191
  ensure
165
- StatsD.increment(StatsD::Instrument.generate_metric_name(name, self, *args), *metric_options) if truthiness
192
+ if truthiness
193
+ metric_name = StatsD::Instrument.generate_metric_name(name, self, *args)
194
+ StatsD.increment(metric_name, *metric_options)
195
+ end
166
196
  end
167
197
  end
168
198
  end
@@ -180,7 +210,8 @@ module StatsD
180
210
  def statsd_count(method, name, *metric_options)
181
211
  add_to_method(method, name, :count) do
182
212
  define_method(method) do |*args, &block|
183
- StatsD.increment(StatsD::Instrument.generate_metric_name(name, self, *args), 1, *metric_options)
213
+ metric_name = StatsD::Instrument.generate_metric_name(name, self, *args)
214
+ StatsD.increment(metric_name, 1, *metric_options)
184
215
  super(*args, &block)
185
216
  end
186
217
  end
@@ -248,8 +279,13 @@ module StatsD
248
279
  def add_to_method(method, name, action, &block)
249
280
  instrumentation_module = statsd_instrumentation_for(method, name, action)
250
281
 
251
- raise ArgumentError, "already instrumented #{method} for #{self.name}" if instrumentation_module.method_defined?(method)
252
- raise ArgumentError, "could not find method #{method} for #{self.name}" unless method_defined?(method) || private_method_defined?(method)
282
+ if instrumentation_module.method_defined?(method)
283
+ raise ArgumentError, "Already instrumented #{method} for #{self.name}"
284
+ end
285
+
286
+ unless method_defined?(method) || private_method_defined?(method)
287
+ raise ArgumentError, "could not find method #{method} for #{self.name}"
288
+ end
253
289
 
254
290
  method_scope = method_visibility(method)
255
291
 
@@ -263,10 +299,9 @@ module StatsD
263
299
  end
264
300
 
265
301
  def method_visibility(method)
266
- case
267
- when private_method_defined?(method)
302
+ if private_method_defined?(method)
268
303
  :private
269
- when protected_method_defined?(method)
304
+ elsif protected_method_defined?(method)
270
305
  :protected
271
306
  else
272
307
  :public
@@ -276,6 +311,11 @@ module StatsD
276
311
 
277
312
  attr_accessor :logger, :default_sample_rate, :prefix
278
313
  attr_writer :backend
314
+ attr_reader :default_tags
315
+
316
+ def default_tags=(tags)
317
+ @default_tags = StatsD::Instrument::Metric.normalize_tags(tags)
318
+ end
279
319
 
280
320
  def backend
281
321
  @backend ||= StatsD::Instrument::Environment.default_backend
@@ -310,11 +350,16 @@ module StatsD
310
350
  value, metric_options = parse_options(value, metric_options)
311
351
  type = (!metric_options.empty? && metric_options.first[:as_dist] ? :d : :ms)
312
352
 
313
- result = nil
314
- value = 1000 * StatsD::Instrument.duration { result = block.call } if block_given?
315
- metric = collect_metric(type, key, value, metric_options)
316
- result = metric unless block_given?
317
- result
353
+ return collect_metric(type, key, value, metric_options) unless block_given?
354
+
355
+ start = StatsD::Instrument.current_timestamp
356
+ begin
357
+ block.call
358
+ ensure
359
+ # Ensure catches both a raised exception and a return in the invoked block
360
+ value = 1000 * (StatsD::Instrument.current_timestamp - start)
361
+ collect_metric(type, key, value, metric_options)
362
+ end
318
363
  end
319
364
 
320
365
  # Emits a counter metric.
@@ -371,13 +416,18 @@ module StatsD
371
416
  # http_response = StatsD.distribution('HTTP.call.duration') do
372
417
  # HTTP.get(url)
373
418
  # end
374
- def distribution(key, value=nil, *metric_options, &block)
419
+ def distribution(key, value = nil, *metric_options, &block)
375
420
  value, metric_options = parse_options(value, metric_options)
376
- result = nil
377
- value = 1000 * StatsD::Instrument.duration { result = block.call } if block_given?
378
- metric = collect_metric(:d, key, value, metric_options)
379
- result = metric unless block_given?
380
- result
421
+
422
+ return collect_metric(:d, key, value, metric_options) unless block_given?
423
+
424
+ start = StatsD::Instrument.current_timestamp
425
+ begin
426
+ block.call
427
+ ensure
428
+ value = 1000 * (StatsD::Instrument.current_timestamp - start)
429
+ collect_metric(:d, key, value, metric_options)
430
+ end
381
431
  end
382
432
 
383
433
  # Emits a key/value metric.
@@ -426,7 +476,7 @@ module StatsD
426
476
  # @param args [Array] The list of non-required arguments.
427
477
  # @return [Hash] The hash of optional arguments.
428
478
  def hash_argument(args)
429
- return {} if args.length == 0
479
+ return {} if args.empty?
430
480
  return args.first if args.length == 1 && args.first.is_a?(Hash)
431
481
 
432
482
  order = [:sample_rate, :tags]
@@ -434,8 +484,7 @@ module StatsD
434
484
  args.each_with_index do |value, index|
435
485
  hash[order[index]] = value
436
486
  end
437
-
438
- return hash
487
+ hash
439
488
  end
440
489
 
441
490
  def parse_options(value, metric_options)
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'statsd/instrument'
@@ -1,21 +1,23 @@
1
+ # frozen-string-literal: true
1
2
  # encoding: utf-8
3
+
2
4
  lib = File.expand_path('../lib', __FILE__)
3
5
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
6
  require 'statsd/instrument/version'
5
7
 
6
8
  Gem::Specification.new do |spec|
7
- spec.name = "statsd-instrument"
8
- spec.version = StatsD::Instrument::VERSION
9
- spec.authors = ["Jesse Storimer", "Tobias Lutke", "Willem van Bergen"]
10
- spec.email = ["jesse@shopify.com"]
11
- spec.homepage = "https://github.com/Shopify/statsd-instrument"
12
- spec.summary = %q{A StatsD client for Ruby apps}
9
+ spec.name = "statsd-instrument"
10
+ spec.version = StatsD::Instrument::VERSION
11
+ spec.authors = ["Jesse Storimer", "Tobias Lutke", "Willem van Bergen"]
12
+ spec.email = ["jesse@shopify.com"]
13
+ spec.homepage = "https://github.com/Shopify/statsd-instrument"
14
+ spec.summary = %q{A StatsD client for Ruby apps}
13
15
  spec.description = %q{A StatsD client for Ruby apps. Provides metaprogramming methods to inject StatsD instrumentation into your code.}
14
- spec.license = "MIT"
16
+ spec.license = "MIT"
15
17
 
16
- spec.files = `git ls-files`.split($/)
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.files = `git ls-files`.split($/)
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
21
  spec.require_paths = ["lib"]
20
22
 
21
23
  spec.add_development_dependency 'rake'
@@ -23,5 +25,6 @@ Gem::Specification.new do |spec|
23
25
  spec.add_development_dependency 'rspec'
24
26
  spec.add_development_dependency 'mocha'
25
27
  spec.add_development_dependency 'yard'
28
+ spec.add_development_dependency 'rubocop'
26
29
  spec.add_development_dependency 'benchmark-ips'
27
30
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class AssertionsTest < Minitest::Test
@@ -163,6 +165,15 @@ class AssertionsTest < Minitest::Test
163
165
  end
164
166
  end
165
167
 
168
+ def test_tags_friendly_error
169
+ @test_case.assert_statsd_increment('counter', tags: { class: "AnotherJob" }) do
170
+ StatsD.increment('counter', tags: { class: "MyJob" })
171
+ end
172
+ rescue MiniTest::Assertion => assertion
173
+ assert_match(/Captured metrics with the same key/, assertion.message)
174
+ assert_match(/MyJob/, assertion.message)
175
+ end
176
+
166
177
  def test_multiple_metrics_are_not_order_dependent
167
178
  assert_no_assertion_triggered do
168
179
  foo_1_metric = StatsD::Instrument::MetricExpectation.new(type: :c, name: 'counter', times: 1, tags: ['foo:1'])
@@ -262,7 +273,7 @@ class AssertionsTest < Minitest::Test
262
273
  def test_assert_statsd_call_with_wrong_sample_rate_type
263
274
  assert_assertion_triggered "Unexpected sample rate type for metric counter, must be numeric" do
264
275
  @test_case.assert_statsd_increment('counter', tags: ['a', 'b']) do
265
- StatsD.increment('counter', sample_rate: 'abc', tags: ['a', 'b'])
276
+ StatsD.increment('counter', sample_rate: 'abc', tags: ['a', 'b'])
266
277
  end
267
278
  end
268
279
  end
@@ -309,7 +320,7 @@ class AssertionsTest < Minitest::Test
309
320
  def assert_no_assertion_triggered(&block)
310
321
  block.call
311
322
  rescue MiniTest::Assertion => assertion
312
- flunk "No assertion trigger expected, but one was triggered with message #{assertion.message}."
323
+ flunk("No assertion trigger expected, but one was triggered with message #{assertion.message}.")
313
324
  else
314
325
  pass
315
326
  end
@@ -318,12 +329,12 @@ class AssertionsTest < Minitest::Test
318
329
  block.call
319
330
  rescue MiniTest::Assertion => assertion
320
331
  if message
321
- assert_equal message, assertion.message, "Assertion triggered, but message was not what was expected."
332
+ assert_equal(message, assertion.message, "Assertion triggered, but message was not what was expected.")
322
333
  else
323
334
  pass
324
335
  end
325
336
  assertion
326
337
  else
327
- flunk "No assertion was triggered, but one was expected."
338
+ flunk("No assertion was triggered, but one was expected.")
328
339
  end
329
340
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'statsd-instrument'
4
+ require 'benchmark/ips'
5
+
6
+ StatsD.logger = Logger.new('/dev/null')
7
+
8
+ class Suite
9
+ def warming(*args)
10
+ StatsD.default_tags = if args[0] == "with default tags"
11
+ { first_tag: 'first_value', second_tag: 'second_value' }
12
+ end
13
+ puts "warming with default tags: #{StatsD.default_tags}"
14
+ end
15
+
16
+ def running(*args)
17
+ StatsD.default_tags = if args[0] == "with default tags"
18
+ { first_tag: 'first_value', second_tag: 'second_value' }
19
+ end
20
+ puts "running with default tags: #{StatsD.default_tags}"
21
+ end
22
+
23
+ def warmup_stats(*)
24
+ end
25
+
26
+ def add_report(*)
27
+ end
28
+ end
29
+
30
+ suite = Suite.new
31
+
32
+ Benchmark.ips do |bench|
33
+ bench.config(suite: suite)
34
+ bench.report("without default tags") do
35
+ StatsD.increment('GoogleBase.insert', tags: {
36
+ first_tag: 'first_value',
37
+ second_tag: 'second_value',
38
+ third_tag: 'third_value',
39
+ })
40
+ end
41
+
42
+ bench.report("with default tags") do
43
+ StatsD.increment('GoogleBase.insert', tags: { third_tag: 'third_value' })
44
+ end
45
+
46
+ bench.compare!
47
+ end
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'statsd-instrument'
2
4
  require 'benchmark/ips'
3
5
 
4
- def helperFunction()
5
- a = 10
6
- a += a
7
- a -= a
8
- a *= a
6
+ def helper_function
7
+ a = 10
8
+ a += a
9
+ a -= a
10
+ a * a
9
11
  end
10
12
 
11
13
  Benchmark.ips do |bench|
@@ -14,8 +16,8 @@ Benchmark.ips do |bench|
14
16
  end
15
17
 
16
18
  bench.report("measure metric benchmark") do
17
- StatsD.measure('helperFunction') do
18
- helperFunction()
19
+ StatsD.measure('helper_function') do
20
+ helper_function
19
21
  end
20
22
  end
21
23
 
@@ -34,5 +36,4 @@ Benchmark.ips do |bench|
34
36
  bench.report("service check metric benchmark") do
35
37
  StatsD.service_check('shipit.redis_connection', 'ok')
36
38
  end
37
-
38
39
  end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'statsd-instrument'
2
4
  require 'benchmark/ips'
3
5
 
4
6
  Benchmark.ips do |bench|
5
7
  bench.report("normalized tags with simple hash") do
6
- StatsD::Instrument::Metric.normalize_tags(:tag => 'value')
8
+ StatsD::Instrument::Metric.normalize_tags(tag: 'value')
7
9
  end
8
10
 
9
11
  bench.report("normalized tags with simple array") do
@@ -11,14 +13,14 @@ Benchmark.ips do |bench|
11
13
  end
12
14
 
13
15
  bench.report("normalized tags with large hash") do
14
- StatsD::Instrument::Metric.normalize_tags({
16
+ StatsD::Instrument::Metric.normalize_tags(
15
17
  mobile: true,
16
18
  pod: "1",
17
19
  protocol: "https",
18
20
  country: "Langbortistan",
19
21
  complete: true,
20
22
  shop: "omg shop that has a longer name",
21
- })
23
+ )
22
24
  end
23
25
 
24
26
  bench.report("normalized tags with large array") do
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class CaptureBackendTest < Minitest::Test
4
6
  def setup
5
7
  @backend = StatsD::Instrument::Backends::CaptureBackend.new
6
- @metric1 = StatsD::Instrument::Metric::new(type: :c, name: 'mock.counter')
7
- @metric2 = StatsD::Instrument::Metric::new(type: :ms, name: 'mock.measure', value: 123)
8
+ @metric1 = StatsD::Instrument::Metric.new(type: :c, name: 'mock.counter')
9
+ @metric2 = StatsD::Instrument::Metric.new(type: :ms, name: 'mock.measure', value: 123)
8
10
  end
9
11
 
10
12
  def test_collecting_metric
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module Rails; end
4
6
 
5
7
  class EnvironmentTest < Minitest::Test
6
-
7
8
  def setup
8
9
  ENV['STATSD_ADDR'] = nil
9
10
  ENV['IMPLEMENTATION'] = nil
data/test/helpers_test.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class HelpersTest < Minitest::Test
@@ -21,4 +23,3 @@ class HelpersTest < Minitest::Test
21
23
  assert_equal 12, metrics[1].value
22
24
  end
23
25
  end
24
-
@@ -1,20 +1,40 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class IntegrationTest < Minitest::Test
4
-
5
6
  def setup
6
- @old_backend, StatsD.backend = StatsD.backend, StatsD::Instrument::Backends::UDPBackend.new("localhost:31798")
7
+ @server = UDPSocket.new
8
+ @server.bind('localhost', 0)
9
+ port = @server.addr[1]
10
+
11
+ @old_backend = StatsD.backend
12
+ StatsD.backend = StatsD::Instrument::Backends::UDPBackend.new("localhost:#{port}")
7
13
  end
8
-
14
+
9
15
  def teardown
16
+ @server.close
10
17
  StatsD.backend = @old_backend
11
18
  end
12
19
 
13
20
  def test_live_local_udp_socket
14
- server = UDPSocket.new
15
- server.bind('localhost', 31798)
16
-
17
21
  StatsD.increment('counter')
18
- assert_equal "counter:1|c", server.recvfrom(100).first
22
+ assert_equal "counter:1|c", @server.recvfrom(100).first
23
+ end
24
+
25
+ def test_synchronize_in_exit_handler_handles_thread_error_and_exits_cleanly
26
+ pid = fork do
27
+ Signal.trap('TERM') do
28
+ StatsD.increment('exiting')
29
+ Process.exit!(0)
30
+ end
31
+
32
+ sleep 100
33
+ end
34
+
35
+ Process.kill('TERM', pid)
36
+ Process.waitpid(pid)
37
+
38
+ assert_equal "exiting:1|c", @server.recvfrom(100).first
19
39
  end
20
40
  end
@@ -1,20 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class LoggerBackendTest < Minitest::Test
4
6
  def setup
5
7
  logger = Logger.new(@io = StringIO.new)
6
- logger.formatter = lambda { |_,_,_, msg| "#{msg}\n" }
8
+ logger.formatter = lambda { |_, _, _, msg| "#{msg}\n" }
7
9
  @backend = StatsD::Instrument::Backends::LoggerBackend.new(logger)
8
- @metric1 = StatsD::Instrument::Metric::new(type: :c, name: 'mock.counter', tags: { a: 'b', c: 'd'})
9
- @metric2 = StatsD::Instrument::Metric::new(type: :ms, name: 'mock.measure', value: 123, sample_rate: 0.3)
10
+ @metric1 = StatsD::Instrument::Metric.new(type: :c, name: 'mock.counter', tags: { a: 'b', c: 'd' })
11
+ @metric2 = StatsD::Instrument::Metric.new(type: :ms, name: 'mock.measure', value: 123, sample_rate: 0.3)
10
12
  end
11
13
 
12
14
  def test_logs_metrics
13
15
  @backend.collect_metric(@metric1)
14
- assert_equal @io.string, "[StatsD] increment mock.counter:1 #a:b #c:d\n"
15
- @io.string = ""
16
-
17
16
  @backend.collect_metric(@metric2)
18
- assert_equal @io.string, "[StatsD] measure mock.measure:123 @0.3\n"
17
+ assert_equal <<~LOG, @io.string
18
+ [StatsD] increment mock.counter:1 #a:b #c:d
19
+ [StatsD] measure mock.measure:123 @0.3
20
+ LOG
19
21
  end
20
- end
22
+ end