statsd-instrument 3.5.5 → 3.5.7

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: 0b4caa06189952666d3dd979521ec76bcf4bbf4265605c2d9d30198773f74ab8
4
- data.tar.gz: ec65748283c1a32434f6388e24b167133ba53ec36353c4ec5f8ccfe920657b58
3
+ metadata.gz: 4b7e23789eaa2e8f4589989b748c3bd60b31b6916b58f92a845e96c4876fb6ff
4
+ data.tar.gz: d19bcff247d6b3dcabbb9142955c8f1781fd54a7b235ffcae41fb59643babbe0
5
5
  SHA512:
6
- metadata.gz: af4a6f52973f439a4d9246fff0d68c74751173998b1a76c9fdbff87ac001f2718ccc8fe2c5abb6d5bdaa5555f9c82150f196c8fe6f819e913a6828ef269a2e14
7
- data.tar.gz: 79f76342bc46cf2d07fd96f1d72bbe5bc2367251ff93b05b6c4ed938fe96d85bf44c8178ca4f1f4a7186f10921bfbaea456b2ce2d32e64db806ec526b2894d71
6
+ metadata.gz: 3bd9c53e5050773c076b08219965d4c25f509989b3c00ff8fe16c0299e01135b4ca19a02fb7617a5d55737cc776529e865be9f17340f9f8ac406a28562e37f82
7
+ data.tar.gz: 9a5edafd0f72d4da58ca5ce1783c36755e99d458aff9d338af1abc583e9d23b1ccc825b192ef9f97b5f519b41d576755e3e797892f55483e3154795089618612
@@ -9,7 +9,7 @@ jobs:
9
9
  strategy:
10
10
  fail-fast: false
11
11
  matrix:
12
- ruby: ['2.6', '2.7', '3.0', '3.1', 'ruby-head', 'jruby-9.3.7.0', 'truffleruby-22.2.0']
12
+ ruby: ['2.6', '2.7', '3.0', '3.1', '3.2', 'ruby-head', 'jruby-9.3.7.0', 'truffleruby-22.2.0']
13
13
  # Windows on macOS builds started failing, so they are disabled for now
14
14
  # platform: [windows-2019, macOS-10.14, ubuntu-18.04]
15
15
  # exclude:
data/CHANGELOG.md CHANGED
@@ -6,6 +6,15 @@ section below.
6
6
 
7
7
  ## Unreleased changes
8
8
 
9
+ ## Version 3.5.7
10
+
11
+ - Improve time measurement to avoid seconds to milliseconds conversions.
12
+
13
+ ## Version 3.5.6
14
+
15
+ - Fix issue from 3.5.5 where tests using RSpec matcher for tag assertion would fail, because the matcher as being
16
+ use as an array.
17
+
9
18
  ## Version 3.5.5
10
19
 
11
20
  - Fix issue on 3.5.4, allowing user to specify compound matcher without tags
@@ -49,19 +49,41 @@ module StatsD
49
49
  # @param [Array<String>] metric_names (default: []) The metric names that are not
50
50
  # allowed to happen inside the block. If this is set to `[]`, the assertion
51
51
  # will fail if any metric occurs.
52
+ # @param [Array<StatsD::Instrument::Datagram>] datagrams (default: nil) The datagrams
53
+ # to be inspected for metric emission.
54
+ # @param [StatsD::Instrument::Client] client (default: nil) The client to be used
55
+ # for fetching datagrams (if not provided) and metric prefix. If not provided, the
56
+ # singleton client will attempt to be used.
57
+ # @param [Boolean] no_prefix (default: false) A directive to indicate if the client's
58
+ # prefix should be prepended to the metric names.
52
59
  # @yield A block in which the specified metric should not occur. This block
53
60
  # should not raise any exceptions.
54
61
  # @return [void]
55
62
  # @raise [Minitest::Assertion] If an exception occurs, or if any metric (with the
56
63
  # provided names, or any), occurred during the execution of the provided block.
57
- def assert_no_statsd_calls(*metric_names, datagrams: nil, client: nil, &block)
64
+ def assert_no_statsd_calls(*metric_names, datagrams: nil, client: nil, no_prefix: false, &block)
65
+ client ||= StatsD.singleton_client
66
+
58
67
  if datagrams.nil?
59
68
  raise LocalJumpError, "assert_no_statsd_calls requires a block" unless block_given?
60
69
 
61
70
  datagrams = capture_statsd_datagrams_with_exception_handling(client: client, &block)
62
71
  end
63
72
 
64
- datagrams.select! { |metric| metric_names.include?(metric.name) } unless metric_names.empty?
73
+ formatted_metrics = if no_prefix
74
+ metric_names
75
+ else
76
+ metric_names.map do |metric|
77
+ if StatsD::Instrument::Helpers.prefixed_metric?(metric, client: client)
78
+ warn("`#{__method__}` will prefix metrics by default. `#{metric}` skipped due to existing prefix.")
79
+ metric
80
+ else
81
+ StatsD::Instrument::Helpers.prefix_metric(metric, client: client)
82
+ end
83
+ end
84
+ end
85
+
86
+ datagrams.select! { |metric| formatted_metrics.include?(metric.name) } unless formatted_metrics.empty?
65
87
  assert(datagrams.empty?, "No StatsD calls for metric #{datagrams.map(&:name).join(", ")} expected.")
66
88
  end
67
89
 
@@ -310,16 +310,16 @@ module StatsD
310
310
  # @yield The latency (execution time) of the block
311
311
  # @return The return value of the provided block will be passed through.
312
312
  def latency(name, sample_rate: nil, tags: nil, metric_type: nil, no_prefix: false)
313
- start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
313
+ start = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)
314
314
  begin
315
315
  yield
316
316
  ensure
317
- stop = Process.clock_gettime(Process::CLOCK_MONOTONIC)
317
+ stop = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)
318
318
 
319
319
  sample_rate ||= @default_sample_rate
320
320
  if sample?(sample_rate)
321
321
  metric_type ||= datagram_builder(no_prefix: no_prefix).latency_metric_type
322
- latency_in_ms = 1000.0 * (stop - start)
322
+ latency_in_ms = stop - start
323
323
  emit(datagram_builder(no_prefix: no_prefix).send(metric_type, name, latency_in_ms, sample_rate, tags))
324
324
  end
325
325
  end
@@ -37,9 +37,8 @@ module StatsD
37
37
  def initialize(client: nil, type:, name:, value: nil,
38
38
  sample_rate: nil, tags: nil, no_prefix: false, times: 1)
39
39
 
40
- client ||= StatsD.singleton_client
41
40
  @type = type
42
- @name = no_prefix || !client.prefix ? name : "#{client.prefix}.#{name}"
41
+ @name = no_prefix ? name : StatsD::Instrument::Helpers.prefix_metric(name, client: client)
43
42
  @value = normalized_value_for_type(type, value) if value
44
43
  @sample_rate = sample_rate
45
44
  @tags = normalize_tags(tags)
@@ -26,6 +26,18 @@ module StatsD
26
26
 
27
27
  tags
28
28
  end
29
+
30
+ def self.prefix_metric(metric_name, client: nil)
31
+ client ||= StatsD.singleton_client
32
+ client&.prefix ? "#{client.prefix}.#{metric_name}" : metric_name
33
+ end
34
+
35
+ def self.prefixed_metric?(metric_name, client: nil)
36
+ client ||= StatsD.singleton_client
37
+ return false unless client&.prefix
38
+
39
+ metric_name =~ /\A#{Regexp.escape(client.prefix)}\./
40
+ end
29
41
  end
30
42
  end
31
43
  end
@@ -45,8 +45,8 @@ module StatsD
45
45
  metrics = capture_statsd_calls(&block)
46
46
  metrics = metrics.select do |m|
47
47
  metric_tags = m.tags || []
48
- options_tags = options[:tags] || []
49
- tag_matches = options_tags.empty? || metric_tags.all? { |t| options_tags.include?(t) }
48
+ options_tags = options[:tags]
49
+ tag_matches = options_tags.nil? || RSpec::Matchers::BuiltIn::Match.new(options_tags).matches?(metric_tags)
50
50
  m.type == metric_type && m.name == metric_name && tag_matches
51
51
  end
52
52
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module StatsD
4
4
  module Instrument
5
- VERSION = "3.5.5"
5
+ VERSION = "3.5.7"
6
6
  end
7
7
  end
@@ -74,6 +74,66 @@ class AssertionsTest < Minitest::Test
74
74
  assert_equal(assertion.message, "No StatsD calls for metric other, another expected.")
75
75
  end
76
76
 
77
+ def test_assert_no_statsd_calls_with_prefix
78
+ client = StatsD::Instrument::Client.new(prefix: "prefix")
79
+
80
+ @test_case.assert_no_statsd_calls("counter", client: client) do
81
+ client.increment("other")
82
+ end
83
+
84
+ assertion = assert_raises(Minitest::Assertion) do
85
+ @test_case.assert_no_statsd_calls("counter", client: client) do
86
+ client.increment("counter")
87
+ end
88
+ end
89
+ assert_equal(assertion.message, "No StatsD calls for metric prefix.counter expected.")
90
+
91
+ @test_case.expects(:warn).with(
92
+ "`assert_no_statsd_calls` will prefix metrics by default. `prefix.counter` skipped due to existing prefix."
93
+ )
94
+ assertion = assert_raises(Minitest::Assertion) do
95
+ @test_case.assert_no_statsd_calls("prefix.counter", client: client) do
96
+ client.increment("counter")
97
+ end
98
+ end
99
+ assert_equal(assertion.message, "No StatsD calls for metric prefix.counter expected.")
100
+
101
+ @test_case.expects(:warn).never
102
+ assertion = assert_raises(Minitest::Assertion) do
103
+ @test_case.assert_no_statsd_calls("prefix.counter", client: client, no_prefix: true) do
104
+ client.increment("counter")
105
+ end
106
+ end
107
+ assert_equal(assertion.message, "No StatsD calls for metric prefix.counter expected.")
108
+
109
+ assertion = assert_raises(Minitest::Assertion) do
110
+ @test_case.assert_no_statsd_calls("counter", client: client, no_prefix: true) do
111
+ client.increment("counter", no_prefix: true)
112
+ end
113
+ end
114
+ assert_equal(assertion.message, "No StatsD calls for metric counter expected.")
115
+
116
+ StatsD.singleton_client = client
117
+
118
+ @test_case.assert_no_statsd_calls("counter") do
119
+ StatsD.increment("other")
120
+ end
121
+
122
+ assertion = assert_raises(Minitest::Assertion) do
123
+ @test_case.assert_no_statsd_calls("counter") do
124
+ StatsD.increment("counter")
125
+ end
126
+ end
127
+ assert_equal(assertion.message, "No StatsD calls for metric prefix.counter expected.")
128
+
129
+ assertion = assert_raises(Minitest::Assertion) do
130
+ @test_case.assert_no_statsd_calls("counter", no_prefix: true) do
131
+ StatsD.increment("counter", no_prefix: true)
132
+ end
133
+ end
134
+ assert_equal(assertion.message, "No StatsD calls for metric counter expected.")
135
+ end
136
+
77
137
  def test_assert_statsd
78
138
  @test_case.assert_statsd_increment("counter") do
79
139
  StatsD.increment("counter")
data/test/client_test.rb CHANGED
@@ -95,7 +95,7 @@ class ClientTest < Minitest::Test
95
95
  end
96
96
 
97
97
  def test_measure_with_block
98
- Process.stubs(:clock_gettime).with(Process::CLOCK_MONOTONIC).returns(0.1, 0.2)
98
+ Process.stubs(:clock_gettime).with(Process::CLOCK_MONOTONIC, :float_millisecond).returns(100.0, 200.0)
99
99
  datagrams = @client.capture do
100
100
  @client.measure("foo") {}
101
101
  end
@@ -128,7 +128,7 @@ class ClientTest < Minitest::Test
128
128
  end
129
129
 
130
130
  def test_distribution_with_block
131
- Process.stubs(:clock_gettime).with(Process::CLOCK_MONOTONIC).returns(0.1, 0.2)
131
+ Process.stubs(:clock_gettime).with(Process::CLOCK_MONOTONIC, :float_millisecond).returns(100.0, 200.0)
132
132
  datagrams = @dogstatsd_client.capture do
133
133
  @dogstatsd_client.distribution("foo") {}
134
134
  end
@@ -137,7 +137,7 @@ class ClientTest < Minitest::Test
137
137
  end
138
138
 
139
139
  def test_latency_emits_ms_metric
140
- Process.stubs(:clock_gettime).with(Process::CLOCK_MONOTONIC).returns(0.1, 0.2)
140
+ Process.stubs(:clock_gettime).with(Process::CLOCK_MONOTONIC, :float_millisecond).returns(100.0, 200.0)
141
141
  datagrams = @client.capture do
142
142
  @client.latency("foo") {}
143
143
  end
@@ -146,7 +146,7 @@ class ClientTest < Minitest::Test
146
146
  end
147
147
 
148
148
  def test_latency_on_dogstatsd_prefers_distribution_metric_type
149
- Process.stubs(:clock_gettime).with(Process::CLOCK_MONOTONIC).returns(0.1, 0.2)
149
+ Process.stubs(:clock_gettime).with(Process::CLOCK_MONOTONIC, :float_millisecond).returns(100.0, 200.0)
150
150
  datagrams = @dogstatsd_client.capture do
151
151
  @dogstatsd_client.latency("foo") {}
152
152
  end
data/test/helpers_test.rb CHANGED
@@ -7,6 +7,11 @@ class HelpersTest < Minitest::Test
7
7
  test_class = Class.new(Minitest::Test)
8
8
  test_class.send(:include, StatsD::Instrument::Helpers)
9
9
  @test_case = test_class.new("fake")
10
+ @old_client = StatsD.singleton_client
11
+ end
12
+
13
+ def teardown
14
+ StatsD.singleton_client = @old_client
10
15
  end
11
16
 
12
17
  def test_capture_metrics_inside_block_only
@@ -78,4 +83,58 @@ class HelpersTest < Minitest::Test
78
83
  StatsD::Instrument::Helpers.add_tag(1, :key, 123)
79
84
  end
80
85
  end
86
+
87
+ def test_prefix_metric_returns_metric_if_no_prefix
88
+ metric = "metric"
89
+ client = StatsD::Instrument::Client.new(prefix: nil)
90
+ assert_equal(metric, StatsD::Instrument::Helpers.prefix_metric(metric, client: client))
91
+ end
92
+
93
+ def test_prefix_metric_returns_prefixed_metric
94
+ prefix = "prefix"
95
+ metric = "metric"
96
+ client = StatsD::Instrument::Client.new(prefix: prefix)
97
+ assert_equal("#{prefix}.#{metric}", StatsD::Instrument::Helpers.prefix_metric(metric, client: client))
98
+ end
99
+
100
+ def test_prefix_metric_can_use_singleton_client
101
+ prefix = "prefix"
102
+ metric = "metric"
103
+ StatsD.singleton_client = StatsD::Instrument::Client.new(prefix: prefix)
104
+ assert_equal("#{prefix}.#{metric}", StatsD::Instrument::Helpers.prefix_metric(metric))
105
+ end
106
+
107
+ def test_prefixed_metric_return_true_if_prefix_present
108
+ prefix = "prefix"
109
+ metric = "prefix.metric"
110
+ client = StatsD::Instrument::Client.new(prefix: prefix)
111
+ assert(StatsD::Instrument::Helpers.prefixed_metric?(metric, client: client))
112
+ end
113
+
114
+ def test_prefixed_meric_returns_false_if_prefix_missing
115
+ prefix = "prefix"
116
+ metric = "metric"
117
+ client = StatsD::Instrument::Client.new(prefix: prefix)
118
+ refute(StatsD::Instrument::Helpers.prefixed_metric?(metric, client: client))
119
+ end
120
+
121
+ def test_prefixed_metric_returns_false_if_prefix_not_at_beginning
122
+ prefix = "prefix"
123
+ metric = "metric.prefix"
124
+ client = StatsD::Instrument::Client.new(prefix: prefix)
125
+ refute(StatsD::Instrument::Helpers.prefixed_metric?(metric, client: client))
126
+ end
127
+
128
+ def test_prefixed_metrics_returns_false_if_no_prefix_defined
129
+ metric = "prefix.metric"
130
+ client = StatsD::Instrument::Client.new(prefix: nil)
131
+ refute(StatsD::Instrument::Helpers.prefixed_metric?(metric, client: client))
132
+ end
133
+
134
+ def test_prefixed_metric_can_use_singleton_client
135
+ prefix = "prefix"
136
+ metric = "prefix.metric"
137
+ StatsD.singleton_client = StatsD::Instrument::Client.new(prefix: prefix)
138
+ assert(StatsD::Instrument::Helpers.prefixed_metric?(metric))
139
+ end
81
140
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "test_helper"
4
4
  require "statsd/instrument/matchers"
5
+ require "rspec/mocks/argument_matchers"
5
6
 
6
7
  class MatchersTest < Minitest::Test
7
8
  def test_statsd_increment_matched
@@ -114,6 +115,13 @@ class MatchersTest < Minitest::Test
114
115
  .matches?(lambda { StatsD.increment("counter", tags: ["a", "b"]) }))
115
116
  end
116
117
 
118
+ def test_statsd_increment_with_subset_matcher
119
+ include_matcher = RSpec::Matchers::BuiltIn::Include.new("foo:bar")
120
+ final = RSpec::Matchers::AliasedMatcher.new(include_matcher, :include)
121
+ assert(StatsD::Instrument::Matchers::Increment.new(:c, "counter", tags: final)
122
+ .matches?(lambda { StatsD.increment("counter", tags: ["foo:bar", "bar:baz"]) }))
123
+ end
124
+
117
125
  def test_statsd_increment_with_tags_not_matched
118
126
  refute(StatsD::Instrument::Matchers::Increment.new(:c, "counter", tags: ["a", "b"])
119
127
  .matches?(lambda { StatsD.increment("counter", tags: ["c"]) }))
data/test/statsd_test.rb CHANGED
@@ -18,7 +18,7 @@ class StatsDTest < Minitest::Test
18
18
  end
19
19
 
20
20
  def test_statsd_measure_with_benchmarked_block_duration
21
- Process.stubs(:clock_gettime).returns(5.0, 5.0 + 1.12)
21
+ Process.stubs(:clock_gettime).returns(5000.0, 5000.0 + 1120.0)
22
22
  metric = capture_statsd_call do
23
23
  StatsD.measure("values.foobar") { "foo" }
24
24
  end
@@ -31,7 +31,7 @@ class StatsDTest < Minitest::Test
31
31
  end
32
32
 
33
33
  def test_statsd_measure_with_return_in_block_still_captures
34
- Process.stubs(:clock_gettime).returns(5.0, 6.12)
34
+ Process.stubs(:clock_gettime).returns(5000.0, 6120.0)
35
35
  result = nil
36
36
  metric = capture_statsd_call do
37
37
  lambda = -> do
@@ -46,7 +46,7 @@ class StatsDTest < Minitest::Test
46
46
  end
47
47
 
48
48
  def test_statsd_measure_with_exception_in_block_still_captures
49
- Process.stubs(:clock_gettime).returns(5.0, 6.12)
49
+ Process.stubs(:clock_gettime).returns(5000.0, 6120.0)
50
50
  result = nil
51
51
  metric = capture_statsd_call do
52
52
  lambda = -> do
@@ -111,7 +111,7 @@ class StatsDTest < Minitest::Test
111
111
  end
112
112
 
113
113
  def test_statsd_distribution_with_benchmarked_block_duration
114
- Process.stubs(:clock_gettime).returns(5.0, 5.0 + 1.12)
114
+ Process.stubs(:clock_gettime).returns(5000.0, 5000.0 + 1120.0)
115
115
  metric = capture_statsd_call do
116
116
  result = StatsD.distribution("values.foobar") { "foo" }
117
117
  assert_equal("foo", result)
@@ -121,7 +121,7 @@ class StatsDTest < Minitest::Test
121
121
  end
122
122
 
123
123
  def test_statsd_distribution_with_return_in_block_still_captures
124
- Process.stubs(:clock_gettime).returns(5.0, 5.0 + 1.12)
124
+ Process.stubs(:clock_gettime).returns(5000.0, 5000.0 + 1120.0)
125
125
  result = nil
126
126
  metric = capture_statsd_call do
127
127
  lambda = -> do
@@ -138,7 +138,7 @@ class StatsDTest < Minitest::Test
138
138
  end
139
139
 
140
140
  def test_statsd_distribution_with_exception_in_block_still_captures
141
- Process.stubs(:clock_gettime).returns(5.0, 5.0 + 1.12)
141
+ Process.stubs(:clock_gettime).returns(5000.0, 5000.0 + 1120.0)
142
142
  result = nil
143
143
  metric = capture_statsd_call do
144
144
  lambda = -> do
@@ -158,7 +158,7 @@ class StatsDTest < Minitest::Test
158
158
  end
159
159
 
160
160
  def test_statsd_distribution_with_block_and_options
161
- Process.stubs(:clock_gettime).returns(5.0, 5.0 + 1.12)
161
+ Process.stubs(:clock_gettime).returns(5000.0, 5000.0 + 1120.0)
162
162
  metric = capture_statsd_call do
163
163
  StatsD.distribution("values.foobar", tags: ["test"], sample_rate: 0.9) { "foo" }
164
164
  end
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: 3.5.5
4
+ version: 3.5.7
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: 2023-03-02 00:00:00.000000000 Z
13
+ date: 2023-04-12 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.
@@ -122,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
122
  - !ruby/object:Gem::Version
123
123
  version: '0'
124
124
  requirements: []
125
- rubygems_version: 3.3.3
125
+ rubygems_version: 3.4.10
126
126
  signing_key:
127
127
  specification_version: 4
128
128
  summary: A StatsD client for Ruby apps