statsd-instrument 2.3.2 → 2.4.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/.github/CODEOWNERS +1 -0
- data/.github/workflows/ci.yml +31 -0
- data/.gitignore +1 -0
- data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +1027 -0
- data/.rubocop.yml +21 -0
- data/CHANGELOG.md +41 -0
- data/CONTRIBUTING.md +26 -6
- data/Gemfile +2 -0
- data/Rakefile +3 -1
- data/lib/statsd/instrument/assertions.rb +24 -18
- data/lib/statsd/instrument/backend.rb +3 -2
- data/lib/statsd/instrument/backends/capture_backend.rb +2 -1
- data/lib/statsd/instrument/backends/logger_backend.rb +3 -3
- data/lib/statsd/instrument/backends/null_backend.rb +2 -0
- data/lib/statsd/instrument/backends/udp_backend.rb +20 -17
- data/lib/statsd/instrument/environment.rb +2 -0
- data/lib/statsd/instrument/helpers.rb +6 -2
- data/lib/statsd/instrument/matchers.rb +14 -11
- data/lib/statsd/instrument/metric.rb +34 -21
- data/lib/statsd/instrument/metric_expectation.rb +32 -18
- data/lib/statsd/instrument/railtie.rb +2 -1
- data/lib/statsd/instrument/version.rb +3 -1
- data/lib/statsd/instrument.rb +85 -36
- data/lib/statsd-instrument.rb +2 -0
- data/statsd-instrument.gemspec +13 -10
- data/test/assertions_test.rb +15 -4
- data/test/benchmark/default_tags.rb +47 -0
- data/test/benchmark/metrics.rb +9 -8
- data/test/benchmark/tags.rb +5 -3
- data/test/capture_backend_test.rb +4 -2
- data/test/environment_test.rb +2 -1
- data/test/helpers_test.rb +2 -1
- data/test/integration_test.rb +27 -7
- data/test/logger_backend_test.rb +10 -8
- data/test/matchers_test.rb +34 -20
- data/test/metric_test.rb +15 -4
- data/test/statsd_instrumentation_test.rb +7 -7
- data/test/statsd_test.rb +100 -10
- data/test/test_helper.rb +2 -0
- data/test/udp_backend_test.rb +5 -28
- metadata +23 -5
- 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
|
data/lib/statsd/instrument.rb
CHANGED
@@ -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.
|
62
|
-
|
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.
|
69
|
-
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
252
|
-
|
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
|
-
|
267
|
-
when private_method_defined?(method)
|
302
|
+
if private_method_defined?(method)
|
268
303
|
:private
|
269
|
-
|
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
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
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
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
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.
|
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)
|
data/lib/statsd-instrument.rb
CHANGED
data/statsd-instrument.gemspec
CHANGED
@@ -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
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
11
|
-
spec.homepage
|
12
|
-
spec.summary
|
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
|
16
|
+
spec.license = "MIT"
|
15
17
|
|
16
|
-
spec.files
|
17
|
-
spec.executables
|
18
|
-
spec.test_files
|
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
|
data/test/assertions_test.rb
CHANGED
@@ -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:
|
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
|
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
|
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
|
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
|
data/test/benchmark/metrics.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'statsd-instrument'
|
2
4
|
require 'benchmark/ips'
|
3
5
|
|
4
|
-
def
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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('
|
18
|
-
|
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
|
data/test/benchmark/tags.rb
CHANGED
@@ -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(:
|
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
|
7
|
-
@metric2 = StatsD::Instrument::Metric
|
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
|
data/test/environment_test.rb
CHANGED
data/test/helpers_test.rb
CHANGED
data/test/integration_test.rb
CHANGED
@@ -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
|
-
@
|
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
|
data/test/logger_backend_test.rb
CHANGED
@@ -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
|
9
|
-
@metric2 = StatsD::Instrument::Metric
|
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
|
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
|