statsd-instrument 2.3.2 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/workflows/benchmark.yml +32 -0
  4. data/.github/workflows/ci.yml +47 -0
  5. data/.gitignore +1 -0
  6. data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +1027 -0
  7. data/.rubocop.yml +50 -0
  8. data/.yardopts +5 -0
  9. data/CHANGELOG.md +288 -2
  10. data/CONTRIBUTING.md +28 -6
  11. data/Gemfile +5 -0
  12. data/README.md +54 -46
  13. data/Rakefile +4 -2
  14. data/benchmark/README.md +29 -0
  15. data/benchmark/datagram-client +41 -0
  16. data/benchmark/send-metrics-to-dev-null-log +47 -0
  17. data/benchmark/send-metrics-to-local-udp-receiver +57 -0
  18. data/lib/statsd/instrument/assertions.rb +179 -30
  19. data/lib/statsd/instrument/backend.rb +3 -2
  20. data/lib/statsd/instrument/backends/capture_backend.rb +4 -1
  21. data/lib/statsd/instrument/backends/logger_backend.rb +3 -3
  22. data/lib/statsd/instrument/backends/null_backend.rb +2 -0
  23. data/lib/statsd/instrument/backends/udp_backend.rb +39 -45
  24. data/lib/statsd/instrument/capture_sink.rb +27 -0
  25. data/lib/statsd/instrument/client.rb +313 -0
  26. data/lib/statsd/instrument/datagram.rb +75 -0
  27. data/lib/statsd/instrument/datagram_builder.rb +101 -0
  28. data/lib/statsd/instrument/dogstatsd_datagram_builder.rb +71 -0
  29. data/lib/statsd/instrument/environment.rb +108 -29
  30. data/lib/statsd/instrument/helpers.rb +16 -8
  31. data/lib/statsd/instrument/log_sink.rb +24 -0
  32. data/lib/statsd/instrument/matchers.rb +14 -11
  33. data/lib/statsd/instrument/metric.rb +72 -45
  34. data/lib/statsd/instrument/metric_expectation.rb +32 -18
  35. data/lib/statsd/instrument/null_sink.rb +13 -0
  36. data/lib/statsd/instrument/railtie.rb +2 -1
  37. data/lib/statsd/instrument/rubocop/measure_as_dist_argument.rb +39 -0
  38. data/lib/statsd/instrument/rubocop/metaprogramming_positional_arguments.rb +42 -0
  39. data/lib/statsd/instrument/rubocop/metric_prefix_argument.rb +37 -0
  40. data/lib/statsd/instrument/rubocop/metric_return_value.rb +32 -0
  41. data/lib/statsd/instrument/rubocop/metric_value_keyword_argument.rb +36 -0
  42. data/lib/statsd/instrument/rubocop/positional_arguments.rb +99 -0
  43. data/lib/statsd/instrument/rubocop/splat_arguments.rb +31 -0
  44. data/lib/statsd/instrument/rubocop.rb +64 -0
  45. data/lib/statsd/instrument/statsd_datagram_builder.rb +14 -0
  46. data/lib/statsd/instrument/strict.rb +235 -0
  47. data/lib/statsd/instrument/udp_sink.rb +62 -0
  48. data/lib/statsd/instrument/version.rb +3 -1
  49. data/lib/statsd/instrument.rb +340 -163
  50. data/lib/statsd-instrument.rb +2 -0
  51. data/statsd-instrument.gemspec +13 -10
  52. data/test/assertions_test.rb +167 -156
  53. data/test/benchmark/clock_gettime.rb +27 -0
  54. data/test/benchmark/default_tags.rb +47 -0
  55. data/test/benchmark/metrics.rb +9 -8
  56. data/test/benchmark/tags.rb +5 -3
  57. data/test/capture_backend_test.rb +4 -2
  58. data/test/capture_sink_test.rb +44 -0
  59. data/test/client_test.rb +164 -0
  60. data/test/compatibility/dogstatsd_datagram_compatibility_test.rb +162 -0
  61. data/test/datagram_builder_test.rb +120 -0
  62. data/test/deprecations_test.rb +132 -0
  63. data/test/dogstatsd_datagram_builder_test.rb +32 -0
  64. data/test/environment_test.rb +75 -8
  65. data/test/helpers/rubocop_helper.rb +47 -0
  66. data/test/helpers_test.rb +2 -1
  67. data/test/integration_test.rb +31 -7
  68. data/test/log_sink_test.rb +37 -0
  69. data/test/logger_backend_test.rb +10 -8
  70. data/test/matchers_test.rb +42 -28
  71. data/test/metric_test.rb +18 -22
  72. data/test/null_sink_test.rb +13 -0
  73. data/test/rubocop/measure_as_dist_argument_test.rb +44 -0
  74. data/test/rubocop/metaprogramming_positional_arguments_test.rb +58 -0
  75. data/test/rubocop/metric_prefix_argument_test.rb +38 -0
  76. data/test/rubocop/metric_return_value_test.rb +78 -0
  77. data/test/rubocop/metric_value_keyword_argument_test.rb +39 -0
  78. data/test/rubocop/positional_arguments_test.rb +110 -0
  79. data/test/rubocop/splat_arguments_test.rb +27 -0
  80. data/test/statsd_datagram_builder_test.rb +22 -0
  81. data/test/statsd_instrumentation_test.rb +109 -100
  82. data/test/statsd_test.rb +113 -79
  83. data/test/test_helper.rb +12 -1
  84. data/test/udp_backend_test.rb +38 -36
  85. data/test/udp_sink_test.rb +85 -0
  86. metadata +85 -5
  87. data/.travis.yml +0 -12
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+ require 'statsd/instrument/rubocop'
5
+
6
+ module Rubocop
7
+ class MetricPrefixArgumentTest < Minitest::Test
8
+ include RubocopHelper
9
+
10
+ def setup
11
+ @cop = RuboCop::Cop::StatsD::MetricPrefixArgument.new
12
+ end
13
+
14
+ def test_ok_for_metric_method_without_prefix_argument
15
+ assert_no_offenses("StatsD.measure('foo', 123) {}")
16
+ assert_no_offenses("StatsD.increment('foo', 123, sample_rate: 3, no_prefix: true)")
17
+ assert_no_offenses("StatsD.gauge('foo', 123)")
18
+ end
19
+
20
+ def test_ok_for_metaprogramming_method_without_prefix_argument
21
+ assert_no_offenses("statsd_measure(:method, 'metric_name')")
22
+ assert_no_offenses("statsd_count(:method, 'metric_name', sample_rate: 1, no_pefix: true)")
23
+ assert_no_offenses("statsd_count_if(:method, 'metric_name', sample_rate: 1) {}")
24
+ end
25
+
26
+ def test_offense_when_using_as_dist_with_measure_metric_method
27
+ assert_offense("StatsD.measure('foo', 123, sample_rate: 1, prefix: 'pre', tags: ['bar'])")
28
+ assert_offense("StatsD.gauge('foo', 123, prefix: nil)")
29
+ assert_offense("StatsD.increment('foo', prefix: 'pre', &block)")
30
+ assert_offense("StatsD.set('foo', prefix: 'pre') { } ")
31
+ end
32
+
33
+ def test_offense_when_using_as_dist_with_measure_metaprogramming_method
34
+ assert_offense("statsd_measure(:method, 'foo', prefix: 'foo')")
35
+ assert_offense("statsd_count_if(:method, 'foo', prefix: nil) { } ")
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+ require 'statsd/instrument/rubocop'
5
+
6
+ module Rubocop
7
+ class MetricReturnValueTest < Minitest::Test
8
+ include RubocopHelper
9
+
10
+ def setup
11
+ @cop = RuboCop::Cop::StatsD::MetricReturnValue.new
12
+ end
13
+
14
+ def test_ok_for_non_metric_method
15
+ assert_no_offenses('backend = StatsD.backend')
16
+ end
17
+
18
+ def test_ok_as_naked_statement
19
+ assert_no_offenses("StatsD.increment('foo')")
20
+ assert_no_offenses("StatsD.measure('foo') { foo }")
21
+ end
22
+
23
+ def test_ok_as_multiple_statement
24
+ assert_no_offenses <<~RUBY
25
+ StatsD.increment 'foo'
26
+ StatsD.increment 'bar'
27
+ RUBY
28
+ end
29
+
30
+ def test_ok_inside_block
31
+ assert_no_offenses <<~RUBY
32
+ block do
33
+ StatsD.measure
34
+ end
35
+ RUBY
36
+ end
37
+
38
+ def test_ok_when_passing_a_block_as_param
39
+ assert_no_offenses("block_result = StatsD.measure('foo', &block)")
40
+ end
41
+
42
+ def test_ok_when_passing_a_curly_braces_block
43
+ assert_no_offenses("block_result = StatsD.measure('foo') { measure_me }")
44
+ end
45
+
46
+ def test_ok_when_passing_do_end_block
47
+ assert_no_offenses <<~RUBY
48
+ block_result = StatsD.measure('foo') do
49
+ return_something_useful
50
+ end
51
+ RUBY
52
+ end
53
+
54
+ def test_offense_in_assignment
55
+ assert_offense("metric = StatsD.increment('foo')")
56
+ end
57
+
58
+ def test_offense_in_multi_assignment
59
+ assert_offense("foo, metric = bar, StatsD.increment('foo')")
60
+ end
61
+
62
+ def test_offense_in_hash
63
+ assert_offense("{ metric: StatsD.increment('foo') }")
64
+ end
65
+
66
+ def test_offense_in_method_call
67
+ assert_offense("process(StatsD.increment('foo'))")
68
+ end
69
+
70
+ def test_offense_when_returning
71
+ assert_offense("return StatsD.increment('foo')")
72
+ end
73
+
74
+ def test_offense_when_yielding
75
+ assert_offense("yield StatsD.increment('foo')")
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+ require 'statsd/instrument/rubocop'
5
+
6
+ module Rubocop
7
+ class MetricValueKeywordArgumentTest < Minitest::Test
8
+ include RubocopHelper
9
+
10
+ def setup
11
+ @cop = RuboCop::Cop::StatsD::MetricValueKeywordArgument.new
12
+ end
13
+
14
+ def test_ok_for_method_without_arguments
15
+ assert_no_offenses("StatsD.increment")
16
+ end
17
+
18
+ def test_ok_for_non_metric_method
19
+ assert_no_offenses("StatsD.backend('foo', value: 1)")
20
+ end
21
+
22
+ def test_ok_with_no_keywords
23
+ assert_no_offenses("StatsD.increment('foo', 1)")
24
+ end
25
+
26
+ def test_ok_with_no_matching_keyword
27
+ assert_no_offenses("StatsD.increment('foo', 1, tags: ['foo'])")
28
+ assert_no_offenses("StatsD.increment('foo', 1, tags: { value: 'bar' })")
29
+ end
30
+
31
+ def test_offense_with_value_keyword
32
+ assert_offense("StatsD.increment('foo', value: 1)")
33
+ assert_offense("StatsD.increment('foo', :value => 1)")
34
+ assert_offense("StatsD.increment('foo', 'value' => 1)")
35
+ assert_offense("StatsD.increment('foo', sample_rate: 0.1, value: 1, tags: ['foo'])")
36
+ assert_offense("StatsD.increment('foo', value: 1, &block)")
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+ require 'statsd/instrument/rubocop'
5
+
6
+ module Rubocop
7
+ class PositionalArgumentsTest < Minitest::Test
8
+ include RubocopHelper
9
+
10
+ def setup
11
+ @cop = RuboCop::Cop::StatsD::PositionalArguments.new
12
+ end
13
+
14
+ def test_no_offenses
15
+ assert_no_offenses("StatsD.increment 'foo'")
16
+ assert_no_offenses("StatsD.gauge('foo', 2)")
17
+ assert_no_offenses("StatsD.increment('foo', 2, tags: ['foo:bar'])")
18
+ assert_no_offenses("StatsD.increment('foo', 2, sample_rate: 0.1, tags: { foo: 'bar' })")
19
+ assert_no_offenses("StatsD.increment('foo', 2) { foo }")
20
+ assert_no_offenses("StatsD.increment('foo', 2, &block)")
21
+ assert_no_offenses("StatsD.gauge('foo', 2, **kwargs)")
22
+ end
23
+
24
+ def test_no_offense_for_now_when_using_value_keyword_argumenr
25
+ assert_no_offenses("StatsD.increment 'foo', value: 3")
26
+ assert_no_offenses("StatsD.increment 'foo', value: 3, sample_rate: 0.5")
27
+ assert_no_offenses("StatsD.increment('foo', value: 3, tags: ['foo']) { foo }")
28
+ end
29
+
30
+ def test_offense_when_using_method_or_constant
31
+ assert_offense("StatsD.gauge('foo', 2, SAMPLE_RATE_CONSTANT)")
32
+ assert_offense("StatsD.gauge('foo', 2, method_ruturning_a_hash)")
33
+ end
34
+
35
+ def test_offense_when_using_local_variable
36
+ assert_offense("lambda { |x| StatsD.gauge('foo', 2, x) }")
37
+ assert_offense(<<~RUBY)
38
+ x = foo
39
+ StatsD.gauge('foo', 2, x)
40
+ RUBY
41
+ end
42
+
43
+ def test_offense_when_using_splat
44
+ assert_offense("StatsD.gauge('foo', 2, *options)")
45
+ end
46
+
47
+ def test_no_autocorrect_when_using_method_or_constant
48
+ assert_no_autocorrect("StatsD.gauge('foo', 2, SAMPLE_RATE_CONSTANT)")
49
+ assert_no_autocorrect("StatsD.gauge('foo', 2, method_ruturning_a_hash)")
50
+ end
51
+
52
+ def test_autocorrect_only_sample_rate
53
+ corrected = autocorrect_source("StatsD.increment('foo', 2, 0.5)")
54
+ assert_equal "StatsD.increment('foo', 2, sample_rate: 0.5)", corrected
55
+ end
56
+
57
+ def test_autocorrect_only_sample_rate_as_int
58
+ corrected = autocorrect_source("StatsD.increment('foo', 2, 1)")
59
+ assert_equal "StatsD.increment('foo', 2, sample_rate: 1)", corrected
60
+ end
61
+
62
+ def test_autocorrect_only_tags
63
+ corrected = autocorrect_source("StatsD.increment('foo', 2, nil, ['foo', 'bar'])")
64
+ assert_equal "StatsD.increment('foo', 2, tags: ['foo', 'bar'])", corrected
65
+ end
66
+
67
+ def test_autocorrect_sample_rate_and_tags_as_array
68
+ corrected = autocorrect_source("StatsD.increment('foo', 2, 0.5, ['foo', 'bar'])")
69
+ assert_equal "StatsD.increment('foo', 2, sample_rate: 0.5, tags: ['foo', 'bar'])", corrected
70
+ end
71
+
72
+ def test_autocorrect_sample_rate_and_tags_as_hash_with_curly_braces
73
+ corrected = autocorrect_source("StatsD.increment('foo', 2, 0.5, { foo: 'bar' })")
74
+ assert_equal "StatsD.increment('foo', 2, sample_rate: 0.5, tags: { foo: 'bar' })", corrected
75
+ end
76
+
77
+ def test_autocorrect_sample_rate_and_tags_as_hash_without_curly_braces
78
+ corrected = autocorrect_source("StatsD.increment('foo', 2, 0.5, foo: 'bar')")
79
+ assert_equal "StatsD.increment('foo', 2, sample_rate: 0.5, tags: { foo: 'bar' })", corrected
80
+ end
81
+
82
+ def test_autocorrect_sample_rate_and_block_pass
83
+ corrected = autocorrect_source("StatsD.distribution('foo', 2, 0.5, &block)")
84
+ assert_equal "StatsD.distribution('foo', 2, sample_rate: 0.5, &block)", corrected
85
+ end
86
+
87
+ def test_autocorrect_sample_rate_tags_and_block_pass
88
+ corrected = autocorrect_source("StatsD.measure('foo', 2, nil, foo: 'bar', &block)")
89
+ assert_equal "StatsD.measure('foo', 2, tags: { foo: 'bar' }, &block)", corrected
90
+ end
91
+
92
+ def test_autocorrect_sample_rate_and_curly_braces_block
93
+ corrected = autocorrect_source("StatsD.measure('foo', 2, 0.5) { foo }")
94
+ assert_equal "StatsD.measure('foo', 2, sample_rate: 0.5) { foo }", corrected
95
+ end
96
+
97
+ def test_autocorrect_sample_rate_and_do_end_block
98
+ corrected = autocorrect_source(<<~RUBY)
99
+ StatsD.distribution 'foo', 124, 0.6, ['bar'] do
100
+ foo
101
+ end
102
+ RUBY
103
+ assert_equal <<~RUBY, corrected
104
+ StatsD.distribution 'foo', 124, sample_rate: 0.6, tags: ['bar'] do
105
+ foo
106
+ end
107
+ RUBY
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+ require 'statsd/instrument/rubocop'
5
+
6
+ module Rubocop
7
+ class SplatArgumentsTest < Minitest::Test
8
+ include RubocopHelper
9
+
10
+ def setup
11
+ @cop = RuboCop::Cop::StatsD::SplatArguments.new
12
+ end
13
+
14
+ def test_no_offenses
15
+ assert_no_offenses("StatsD.increment 'foo'")
16
+ assert_no_offenses("StatsD.gauge('foo', 2, tags: 'foo')")
17
+ assert_no_offenses("StatsD.measure('foo', 2, **kwargs)")
18
+ assert_no_offenses("StatsD.measure('foo', 2, **kwargs) { }")
19
+ end
20
+
21
+ def test_offenses
22
+ assert_offense("StatsD.increment(*increment_arguments)")
23
+ assert_offense("StatsD.gauge('foo', 2, *options)")
24
+ assert_offense("StatsD.measure('foo', 2, *options, &block)")
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ require 'statsd/instrument/client'
6
+
7
+ class StatsDDatagramBuilderTest < Minitest::Test
8
+ def setup
9
+ @datagram_builder = StatsD::Instrument::StatsDDatagramBuilder.new
10
+ end
11
+
12
+ def test_raises_on_unsupported_metrics
13
+ assert_raises(NotImplementedError) { @datagram_builder.h('fo:o', 10, nil, nil) }
14
+ assert_raises(NotImplementedError) { @datagram_builder.d('fo:o', 10, nil, nil) }
15
+ assert_raises(NotImplementedError) { @datagram_builder.kv('fo:o', 10, nil, nil) }
16
+ end
17
+
18
+ def test_raises_when_using_tags
19
+ assert_raises(NotImplementedError) { @datagram_builder.c('fo:o', 10, nil, foo: 'bar') }
20
+ assert_raises(NotImplementedError) { StatsD::Instrument::StatsDDatagramBuilder.new(default_tags: ['foo']) }
21
+ end
22
+ end
@@ -1,73 +1,75 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
- module ActiveMerchant; end
4
- class ActiveMerchant::Base
5
- def ssl_post(arg)
6
- if arg
7
- 'OK'
8
- else
9
- raise 'Not OK'
10
- end
11
- end
5
+ class StatsDInstrumentationTest < Minitest::Test
6
+ module ActiveMerchant
7
+ class Base
8
+ extend StatsD::Instrument
12
9
 
13
- def post_with_block(&block)
14
- yield if block_given?
15
- end
16
- end
10
+ def ssl_post(arg)
11
+ if arg
12
+ 'OK'
13
+ else
14
+ raise 'Not OK'
15
+ end
16
+ end
17
17
 
18
- class ActiveMerchant::Gateway < ActiveMerchant::Base
19
- def purchase(arg)
20
- ssl_post(arg)
21
- true
22
- rescue
23
- false
24
- end
18
+ def post_with_block(&block)
19
+ block.call if block_given?
20
+ end
21
+ end
25
22
 
26
- def self.sync
27
- true
28
- end
23
+ class Gateway < Base
24
+ def purchase(arg)
25
+ ssl_post(arg)
26
+ true
27
+ rescue
28
+ false
29
+ end
29
30
 
30
- def self.singleton_class
31
- class << self; self; end
32
- end
33
- end
31
+ def self.sync
32
+ true
33
+ end
34
+ end
34
35
 
35
- class ActiveMerchant::UniqueGateway < ActiveMerchant::Base
36
- def ssl_post(arg)
37
- {:success => arg}
38
- end
36
+ class UniqueGateway < Base
37
+ def ssl_post(arg)
38
+ { success: arg }
39
+ end
39
40
 
40
- def purchase(arg)
41
- ssl_post(arg)
41
+ def purchase(arg)
42
+ ssl_post(arg)
43
+ end
44
+ end
42
45
  end
43
- end
44
46
 
45
- class GatewaySubClass < ActiveMerchant::Gateway
46
- end
47
+ class GatewaySubClass < ActiveMerchant::Gateway
48
+ def metric_name
49
+ 'subgateway'
50
+ end
51
+ end
47
52
 
48
- class InstrumentedClass
49
- extend StatsD::Instrument
53
+ class InstrumentedClass
54
+ extend StatsD::Instrument
50
55
 
51
- def public_and_instrumented
52
- end
53
- statsd_count :public_and_instrumented, 'InstrumentedClass.public_and_instrumented'
56
+ def public_and_instrumented
57
+ end
58
+ statsd_count :public_and_instrumented, 'InstrumentedClass.public_and_instrumented'
54
59
 
55
- protected
60
+ protected
56
61
 
57
- def protected_and_instrumented
58
- end
59
- statsd_count :protected_and_instrumented, 'InstrumentedClass.protected_and_instrumented'
62
+ def protected_and_instrumented
63
+ end
64
+ statsd_count :protected_and_instrumented, 'InstrumentedClass.protected_and_instrumented'
60
65
 
61
- private
66
+ private
62
67
 
63
- def private_and_instrumented
68
+ def private_and_instrumented
69
+ end
70
+ statsd_count :private_and_instrumented, 'InstrumentedClass.private_and_instrumented'
64
71
  end
65
- statsd_count :private_and_instrumented, 'InstrumentedClass.private_and_instrumented'
66
- end
67
-
68
- ActiveMerchant::Base.extend StatsD::Instrument
69
72
 
70
- class StatsDInstrumentationTest < Minitest::Test
71
73
  include StatsD::Instrument::Assertions
72
74
 
73
75
  def test_statsd_count_if
@@ -87,7 +89,7 @@ class StatsDInstrumentationTest < Minitest::Test
87
89
  end
88
90
 
89
91
  assert_statsd_increment('ActiveMerchant.Base.post_with_block') do
90
- assert_equal 'true', ActiveMerchant::Base.new.post_with_block { 'true' }
92
+ assert_equal 'true', ActiveMerchant::Base.new.post_with_block { 'true' }
91
93
  assert_equal 'false', ActiveMerchant::Base.new.post_with_block { 'false' }
92
94
  end
93
95
  ensure
@@ -108,7 +110,7 @@ class StatsDInstrumentationTest < Minitest::Test
108
110
  end
109
111
 
110
112
  def test_statsd_count_success
111
- ActiveMerchant::Gateway.statsd_count_success :ssl_post, 'ActiveMerchant.Gateway', 0.5
113
+ ActiveMerchant::Gateway.statsd_count_success :ssl_post, 'ActiveMerchant.Gateway', sample_rate: 0.5
112
114
 
113
115
  assert_statsd_increment('ActiveMerchant.Gateway.success', sample_rate: 0.5, times: 1) do
114
116
  ActiveMerchant::Gateway.new.purchase(true)
@@ -168,11 +170,22 @@ class StatsDInstrumentationTest < Minitest::Test
168
170
  end
169
171
 
170
172
  def test_statsd_count_with_name_as_lambda
171
- metric_namer = lambda { |object, args| object.class.to_s.downcase + ".insert." + args.first.to_s }
173
+ metric_namer = lambda { |object, args| "#{object.metric_name}.#{args.first}" }
172
174
  ActiveMerchant::Gateway.statsd_count(:ssl_post, metric_namer)
173
175
 
174
- assert_statsd_increment('gatewaysubclass.insert.true') do
175
- GatewaySubClass.new.purchase(true)
176
+ assert_statsd_increment('subgateway.foo') do
177
+ GatewaySubClass.new.purchase('foo')
178
+ end
179
+ ensure
180
+ ActiveMerchant::Gateway.statsd_remove_count(:ssl_post, metric_namer)
181
+ end
182
+
183
+ def test_statsd_count_with_name_as_proc
184
+ metric_namer = proc { |object, args| "#{object.metric_name}.#{args.first}" }
185
+ ActiveMerchant::Gateway.statsd_count(:ssl_post, metric_namer)
186
+
187
+ assert_statsd_increment('subgateway.foo') do
188
+ GatewaySubClass.new.purchase('foo')
176
189
  end
177
190
  ensure
178
191
  ActiveMerchant::Gateway.statsd_remove_count(:ssl_post, metric_namer)
@@ -225,47 +238,16 @@ class StatsDInstrumentationTest < Minitest::Test
225
238
  ActiveMerchant::Base.statsd_remove_measure :post_with_block, 'ActiveMerchant.Base.post_with_block'
226
239
  end
227
240
 
228
- def test_statsd_measure_with_value
229
- ActiveMerchant::UniqueGateway.statsd_measure :ssl_post, 'ActiveMerchant.Gateway.ssl_post', 1
230
-
231
- assert_statsd_measure('ActiveMerchant.Gateway.ssl_post') do
232
- ActiveMerchant::UniqueGateway.new.purchase(true)
233
- end
234
- ensure
235
- ActiveMerchant::UniqueGateway.statsd_remove_measure :ssl_post, 'ActiveMerchant.Gateway.ssl_post'
236
- end
237
-
238
- def test_statsd_measure_with_value_and_options
239
- ActiveMerchant::UniqueGateway.statsd_measure :ssl_post, 'ActiveMerchant.Gateway.ssl_post', 1, sample_rate: 0.45
241
+ def test_statsd_measure_with_sample_rate
242
+ ActiveMerchant::UniqueGateway.statsd_measure :ssl_post, 'ActiveMerchant.Gateway.ssl_post', sample_rate: 0.1
240
243
 
241
- assert_statsd_measure('ActiveMerchant.Gateway.ssl_post', sample_rate: 0.45) do
244
+ assert_statsd_measure('ActiveMerchant.Gateway.ssl_post', sample_rate: 0.1) do
242
245
  ActiveMerchant::UniqueGateway.new.purchase(true)
243
246
  end
244
247
  ensure
245
248
  ActiveMerchant::UniqueGateway.statsd_remove_measure :ssl_post, 'ActiveMerchant.Gateway.ssl_post'
246
249
  end
247
250
 
248
- def test_statsd_measure_with_value_and_distribution
249
- ActiveMerchant::UniqueGateway.statsd_measure :ssl_post, 'ActiveMerchant.Gateway.ssl_post', 1, as_dist: true
250
-
251
- assert_statsd_distribution('ActiveMerchant.Gateway.ssl_post') do
252
- ActiveMerchant::UniqueGateway.new.purchase(true)
253
- end
254
- ensure
255
- ActiveMerchant::UniqueGateway.statsd_remove_measure :ssl_post, 'ActiveMerchant.Gateway.ssl_post'
256
- end
257
-
258
- def test_statsd_measure_without_value_as_distribution
259
- ActiveMerchant::UniqueGateway.statsd_measure :ssl_post, 'ActiveMerchant.Gateway.ssl_post', as_dist: true
260
-
261
- assert_statsd_distribution('ActiveMerchant.Gateway.ssl_post') do
262
- ActiveMerchant::UniqueGateway.new.purchase(true)
263
- end
264
- ensure
265
- ActiveMerchant::UniqueGateway.statsd_remove_measure :ssl_post, 'ActiveMerchant.Gateway.ssl_post'
266
- end
267
-
268
-
269
251
  def test_statsd_distribution
270
252
  ActiveMerchant::UniqueGateway.statsd_distribution :ssl_post, 'ActiveMerchant.Gateway.ssl_post', sample_rate: 0.3
271
253
 
@@ -303,20 +285,20 @@ class StatsDInstrumentationTest < Minitest::Test
303
285
  ActiveMerchant::Base.statsd_remove_distribution :post_with_block, 'ActiveMerchant.Base.post_with_block'
304
286
  end
305
287
 
306
- def test_statsd_distribution_with_value
307
- ActiveMerchant::UniqueGateway.statsd_distribution :ssl_post, 'ActiveMerchant.Gateway.ssl_post', 1
288
+ def test_statsd_distribution_with_tags
289
+ ActiveMerchant::UniqueGateway.statsd_distribution :ssl_post, 'ActiveMerchant.Gateway.ssl_post', tags: ['foo']
308
290
 
309
- assert_statsd_distribution('ActiveMerchant.Gateway.ssl_post') do
291
+ assert_statsd_distribution('ActiveMerchant.Gateway.ssl_post', tags: ['foo']) do
310
292
  ActiveMerchant::UniqueGateway.new.purchase(true)
311
293
  end
312
294
  ensure
313
295
  ActiveMerchant::UniqueGateway.statsd_remove_distribution :ssl_post, 'ActiveMerchant.Gateway.ssl_post'
314
296
  end
315
297
 
316
- def test_statsd_distribution_with_value_and_options
317
- ActiveMerchant::UniqueGateway.statsd_distribution :ssl_post, 'ActiveMerchant.Gateway.ssl_post', 1, sample_rate: 0.45
298
+ def test_statsd_distribution_with_sample_rate
299
+ ActiveMerchant::UniqueGateway.statsd_distribution :ssl_post, 'ActiveMerchant.Gateway.ssl_post', sample_rate: 0.1
318
300
 
319
- assert_statsd_distribution('ActiveMerchant.Gateway.ssl_post', sample_rate: 0.45) do
301
+ assert_statsd_distribution('ActiveMerchant.Gateway.ssl_post', sample_rate: 0.1) do
320
302
  ActiveMerchant::UniqueGateway.new.purchase(true)
321
303
  end
322
304
  ensure
@@ -345,6 +327,34 @@ class StatsDInstrumentationTest < Minitest::Test
345
327
  ActiveMerchant::Gateway.singleton_class.statsd_remove_count :sync, 'ActiveMerchant.Gateway.sync'
346
328
  end
347
329
 
330
+ def test_statsd_respects_global_prefix_changes
331
+ StatsD.prefix = 'Foo'
332
+ ActiveMerchant::Gateway.singleton_class.extend StatsD::Instrument
333
+ ActiveMerchant::Gateway.singleton_class.statsd_count :sync, 'ActiveMerchant.Gateway.sync'
334
+ StatsD.prefix = 'Quc'
335
+
336
+ statsd_calls = capture_statsd_calls { ActiveMerchant::Gateway.sync }
337
+ assert_equal 1, statsd_calls.length
338
+ assert_equal "Quc.ActiveMerchant.Gateway.sync", statsd_calls.first.name
339
+ ensure
340
+ StatsD.prefix = nil
341
+ ActiveMerchant::Gateway.singleton_class.statsd_remove_count :sync, 'ActiveMerchant.Gateway.sync'
342
+ end
343
+
344
+ def test_statsd_macro_can_disable_prefix
345
+ StatsD.prefix = 'Foo'
346
+ ActiveMerchant::Gateway.singleton_class.extend StatsD::Instrument
347
+ ActiveMerchant::Gateway.singleton_class.statsd_count_success :sync, 'ActiveMerchant.Gateway.sync', no_prefix: true
348
+ StatsD.prefix = 'Quc'
349
+
350
+ statsd_calls = capture_statsd_calls { ActiveMerchant::Gateway.sync }
351
+ assert_equal 1, statsd_calls.length
352
+ assert_equal "ActiveMerchant.Gateway.sync.success", statsd_calls.first.name
353
+ ensure
354
+ StatsD.prefix = nil
355
+ ActiveMerchant::Gateway.singleton_class.statsd_remove_count_success :sync, 'ActiveMerchant.Gateway.sync'
356
+ end
357
+
348
358
  def test_statsd_doesnt_change_method_scope_of_public_method
349
359
  assert_scope InstrumentedClass, :public_and_instrumented, :public
350
360
 
@@ -412,10 +422,9 @@ class StatsDInstrumentationTest < Minitest::Test
412
422
  private
413
423
 
414
424
  def assert_scope(klass, method, expected_scope)
415
- method_scope = case
416
- when klass.private_method_defined?(method)
425
+ method_scope = if klass.private_method_defined?(method)
417
426
  :private
418
- when klass.protected_method_defined?(method)
427
+ elsif klass.protected_method_defined?(method)
419
428
  :protected
420
429
  else
421
430
  :public