statsd-instrument 2.5.1 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +1 -1
- data/.rubocop.yml +11 -6
- data/.yardopts +5 -0
- data/CHANGELOG.md +75 -6
- data/README.md +54 -46
- data/benchmark/datagram-client +41 -0
- data/lib/statsd/instrument/assertions.rb +168 -57
- data/lib/statsd/instrument/backends/udp_backend.rb +20 -29
- data/lib/statsd/instrument/capture_sink.rb +27 -0
- data/lib/statsd/instrument/client.rb +313 -0
- data/lib/statsd/instrument/datagram.rb +75 -0
- data/lib/statsd/instrument/datagram_builder.rb +101 -0
- data/lib/statsd/instrument/dogstatsd_datagram_builder.rb +71 -0
- data/lib/statsd/instrument/environment.rb +106 -29
- data/lib/statsd/instrument/log_sink.rb +24 -0
- data/lib/statsd/instrument/null_sink.rb +13 -0
- data/lib/statsd/instrument/rubocop/measure_as_dist_argument.rb +39 -0
- data/lib/statsd/instrument/rubocop/metaprogramming_positional_arguments.rb +6 -10
- data/lib/statsd/instrument/rubocop/metric_prefix_argument.rb +37 -0
- data/lib/statsd/instrument/rubocop/metric_return_value.rb +7 -6
- data/lib/statsd/instrument/rubocop/metric_value_keyword_argument.rb +11 -20
- data/lib/statsd/instrument/rubocop/positional_arguments.rb +13 -13
- data/lib/statsd/instrument/rubocop/splat_arguments.rb +8 -14
- data/lib/statsd/instrument/rubocop.rb +64 -0
- data/lib/statsd/instrument/statsd_datagram_builder.rb +14 -0
- data/lib/statsd/instrument/strict.rb +112 -22
- data/lib/statsd/instrument/udp_sink.rb +62 -0
- data/lib/statsd/instrument/version.rb +1 -1
- data/lib/statsd/instrument.rb +191 -100
- data/test/assertions_test.rb +139 -176
- data/test/capture_sink_test.rb +44 -0
- data/test/client_test.rb +164 -0
- data/test/compatibility/dogstatsd_datagram_compatibility_test.rb +162 -0
- data/test/datagram_builder_test.rb +120 -0
- data/test/deprecations_test.rb +56 -10
- data/test/dogstatsd_datagram_builder_test.rb +32 -0
- data/test/environment_test.rb +73 -7
- data/test/log_sink_test.rb +37 -0
- data/test/null_sink_test.rb +13 -0
- data/test/rubocop/measure_as_dist_argument_test.rb +44 -0
- data/test/rubocop/metaprogramming_positional_arguments_test.rb +1 -1
- data/test/rubocop/metric_prefix_argument_test.rb +38 -0
- data/test/rubocop/metric_return_value_test.rb +1 -1
- data/test/rubocop/metric_value_keyword_argument_test.rb +1 -1
- data/test/rubocop/positional_arguments_test.rb +1 -1
- data/test/rubocop/splat_arguments_test.rb +1 -1
- data/test/statsd_datagram_builder_test.rb +22 -0
- data/test/statsd_instrumentation_test.rb +0 -24
- data/test/statsd_test.rb +0 -23
- data/test/test_helper.rb +0 -2
- data/test/udp_backend_test.rb +25 -8
- data/test/udp_sink_test.rb +85 -0
- metadata +38 -2
data/test/client_test.rb
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
require 'statsd/instrument/client'
|
6
|
+
|
7
|
+
class ClientTest < Minitest::Test
|
8
|
+
def setup
|
9
|
+
@client = StatsD::Instrument::Client.new(datagram_builder_class: StatsD::Instrument::StatsDDatagramBuilder)
|
10
|
+
@dogstatsd_client = StatsD::Instrument::Client.new(
|
11
|
+
datagram_builder_class: StatsD::Instrument::DogStatsDDatagramBuilder,
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_capture
|
16
|
+
inner_datagrams = nil
|
17
|
+
|
18
|
+
@client.increment('foo')
|
19
|
+
outer_datagrams = @client.capture do
|
20
|
+
@client.increment('bar')
|
21
|
+
inner_datagrams = @client.capture do
|
22
|
+
@client.increment('baz')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
@client.increment('quc')
|
26
|
+
|
27
|
+
assert_equal ['bar', 'baz'], outer_datagrams.map(&:name)
|
28
|
+
assert_equal ['baz'], inner_datagrams.map(&:name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_metric_methods_return_nil
|
32
|
+
assert_nil @client.increment('foo')
|
33
|
+
assert_nil @client.measure('bar', 122.54)
|
34
|
+
assert_nil @client.set('baz', 123)
|
35
|
+
assert_nil @client.gauge('baz', 12.3)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_increment_with_default_value
|
39
|
+
datagrams = @client.capture { @client.increment('foo') }
|
40
|
+
assert_equal 1, datagrams.size
|
41
|
+
assert_equal 'foo:1|c', datagrams.first.source
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_measure_with_value
|
45
|
+
datagrams = @client.capture { @client.measure('foo', 122.54) }
|
46
|
+
assert_equal 1, datagrams.size
|
47
|
+
assert_equal 'foo:122.54|ms', datagrams.first.source
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_measure_with_block
|
51
|
+
Process.stubs(:clock_gettime).with(Process::CLOCK_MONOTONIC).returns(0.1, 0.2)
|
52
|
+
datagrams = @client.capture do
|
53
|
+
@client.measure('foo') {}
|
54
|
+
end
|
55
|
+
assert_equal 1, datagrams.size
|
56
|
+
assert_equal 'foo:100.0|ms', datagrams.first.source
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_gauge
|
60
|
+
datagrams = @client.capture { @client.gauge('foo', 123) }
|
61
|
+
assert_equal 1, datagrams.size
|
62
|
+
assert_equal 'foo:123|g', datagrams.first.source
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_set
|
66
|
+
datagrams = @client.capture { @client.set('foo', 12345) }
|
67
|
+
assert_equal 1, datagrams.size
|
68
|
+
assert_equal 'foo:12345|s', datagrams.first.source
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_histogram
|
72
|
+
datagrams = @dogstatsd_client.capture { @dogstatsd_client.histogram('foo', 12.44) }
|
73
|
+
assert_equal 1, datagrams.size
|
74
|
+
assert_equal 'foo:12.44|h', datagrams.first.source
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_distribution_with_value
|
78
|
+
datagrams = @dogstatsd_client.capture { @dogstatsd_client.distribution('foo', 12.44) }
|
79
|
+
assert_equal 1, datagrams.size
|
80
|
+
assert_equal 'foo:12.44|d', datagrams.first.source
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_distribution_with_block
|
84
|
+
Process.stubs(:clock_gettime).with(Process::CLOCK_MONOTONIC).returns(0.1, 0.2)
|
85
|
+
datagrams = @dogstatsd_client.capture do
|
86
|
+
@dogstatsd_client.distribution('foo') {}
|
87
|
+
end
|
88
|
+
assert_equal 1, datagrams.size
|
89
|
+
assert_equal "foo:100.0|d", datagrams.first.source
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_latency_emits_ms_metric
|
93
|
+
Process.stubs(:clock_gettime).with(Process::CLOCK_MONOTONIC).returns(0.1, 0.2)
|
94
|
+
datagrams = @client.capture do
|
95
|
+
@client.latency('foo') {}
|
96
|
+
end
|
97
|
+
assert_equal 1, datagrams.size
|
98
|
+
assert_equal "foo:100.0|ms", datagrams.first.source
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_latency_on_dogstatsd_prefers_distribution_metric_type
|
102
|
+
Process.stubs(:clock_gettime).with(Process::CLOCK_MONOTONIC).returns(0.1, 0.2)
|
103
|
+
datagrams = @dogstatsd_client.capture do
|
104
|
+
@dogstatsd_client.latency('foo') {}
|
105
|
+
end
|
106
|
+
assert_equal 1, datagrams.size
|
107
|
+
assert_equal "foo:100.0|d", datagrams.first.source
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_latency_calls_block_even_when_not_sending_a_sample
|
111
|
+
called = false
|
112
|
+
@client.capture do
|
113
|
+
@client.latency('foo', sample_rate: 0) { called = true }
|
114
|
+
end
|
115
|
+
assert called, "The block should have been called"
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_service_check
|
119
|
+
datagrams = @dogstatsd_client.capture { @dogstatsd_client.service_check('service', :ok) }
|
120
|
+
assert_equal 1, datagrams.size
|
121
|
+
assert_equal "_sc|service|0", datagrams.first.source
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_event
|
125
|
+
datagrams = @dogstatsd_client.capture { @dogstatsd_client.event('service', "event\ndescription") }
|
126
|
+
assert_equal 1, datagrams.size
|
127
|
+
assert_equal "_e{7,18}:service|event\\ndescription", datagrams.first.source
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_no_prefix
|
131
|
+
client = StatsD::Instrument::Client.new(prefix: 'foo')
|
132
|
+
datagrams = client.capture do
|
133
|
+
client.increment('bar')
|
134
|
+
client.increment('bar', no_prefix: true)
|
135
|
+
end
|
136
|
+
|
137
|
+
assert_equal 2, datagrams.size
|
138
|
+
assert_equal "foo.bar", datagrams[0].name
|
139
|
+
assert_equal "bar", datagrams[1].name
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_sampling
|
143
|
+
mock_sink = mock('sink')
|
144
|
+
mock_sink.stubs(:sample?).returns(false, true, false, false, true)
|
145
|
+
mock_sink.expects(:<<).twice
|
146
|
+
|
147
|
+
client = StatsD::Instrument::Client.new(sink: mock_sink)
|
148
|
+
5.times { client.increment('metric') }
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_clone_with_prefix_option
|
152
|
+
# Both clients will use the same sink.
|
153
|
+
mock_sink = mock('sink')
|
154
|
+
mock_sink.stubs(:sample?).returns(true)
|
155
|
+
mock_sink.expects(:<<).with("metric:1|c").returns(mock_sink)
|
156
|
+
mock_sink.expects(:<<).with("foo.metric:1|c").returns(mock_sink)
|
157
|
+
|
158
|
+
original_client = StatsD::Instrument::Client.new(sink: mock_sink)
|
159
|
+
client_with_other_options = original_client.clone_with_options(prefix: 'foo')
|
160
|
+
|
161
|
+
original_client.increment('metric')
|
162
|
+
client_with_other_options.increment('metric')
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'statsd/instrument/client'
|
5
|
+
|
6
|
+
module Compatibility
|
7
|
+
class DogStatsDDatagramCompatibilityTest < Minitest::Test
|
8
|
+
def setup
|
9
|
+
StatsD::Instrument::UDPSink.any_instance.stubs(:sample?).returns(true)
|
10
|
+
StatsD::Instrument::Backends::UDPBackend.any_instance.stubs(:rand).returns(0)
|
11
|
+
|
12
|
+
@server = UDPSocket.new
|
13
|
+
@server.bind('localhost', 0)
|
14
|
+
@host = @server.addr[2]
|
15
|
+
@port = @server.addr[1]
|
16
|
+
end
|
17
|
+
|
18
|
+
def teardown
|
19
|
+
@server.close
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_increment_compatibility
|
23
|
+
assert_equal_datagrams { |client| client.increment('counter') }
|
24
|
+
assert_equal_datagrams { |client| client.increment('counter', no_prefix: true) }
|
25
|
+
assert_equal_datagrams { |client| client.increment('counter', 12) }
|
26
|
+
assert_equal_datagrams { |client| client.increment('counter', sample_rate: 0.1) }
|
27
|
+
assert_equal_datagrams { |client| client.increment('counter', tags: ['foo', 'bar']) }
|
28
|
+
assert_equal_datagrams { |client| client.increment('counter', tags: { foo: 'bar' }) }
|
29
|
+
assert_equal_datagrams { |client| client.increment('counter', sample_rate: 0.1, tags: ['quc']) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_measure_compatibility
|
33
|
+
assert_equal_datagrams { |client| client.measure('timing', 12.34) }
|
34
|
+
assert_equal_datagrams { |client| client.measure('timing', 0.01, no_prefix: true) }
|
35
|
+
assert_equal_datagrams { |client| client.measure('timing', 0.12, sample_rate: 0.1) }
|
36
|
+
assert_equal_datagrams { |client| client.measure('timing', 0.12, tags: ['foo', 'bar']) }
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_measure_with_block_compatibility
|
40
|
+
Process.stubs(:clock_gettime).with(Process::CLOCK_MONOTONIC).returns(12.1)
|
41
|
+
assert_equal_datagrams do |client|
|
42
|
+
return_value = client.measure('timing', tags: ['foo'], sample_rate: 0.1) { 'foo' }
|
43
|
+
assert_equal 'foo', return_value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_gauge_compatibility
|
48
|
+
assert_equal_datagrams { |client| client.gauge('current', 1234) }
|
49
|
+
assert_equal_datagrams { |client| client.gauge('current', 1234, no_prefix: true) }
|
50
|
+
assert_equal_datagrams { |client| client.gauge('current', 1234, sample_rate: 0.1) }
|
51
|
+
assert_equal_datagrams { |client| client.gauge('current', 1234, tags: ['foo', 'bar']) }
|
52
|
+
assert_equal_datagrams { |client| client.gauge('current', 1234, tags: { foo: 'bar' }) }
|
53
|
+
assert_equal_datagrams { |client| client.gauge('current', 1234, sample_rate: 0.1, tags: ['quc']) }
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_set_compatibility
|
57
|
+
assert_equal_datagrams { |client| client.set('unique', 'foo') }
|
58
|
+
assert_equal_datagrams { |client| client.set('unique', 'foo', no_prefix: true) }
|
59
|
+
assert_equal_datagrams { |client| client.set('unique', 'foo', sample_rate: 0.1) }
|
60
|
+
assert_equal_datagrams { |client| client.set('unique', '1234', tags: ['foo', 'bar']) }
|
61
|
+
assert_equal_datagrams { |client| client.set('unique', '1234', tags: { foo: 'bar' }) }
|
62
|
+
assert_equal_datagrams { |client| client.set('unique', '1234', sample_rate: 0.1, tags: ['quc']) }
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_histogram_compatibility
|
66
|
+
assert_equal_datagrams { |client| client.histogram('sample', 12.44) }
|
67
|
+
assert_equal_datagrams { |client| client.histogram('sample', 12.44, no_prefix: true) }
|
68
|
+
assert_equal_datagrams { |client| client.histogram('sample', 12.44, sample_rate: 0.1) }
|
69
|
+
assert_equal_datagrams { |client| client.histogram('sample', 12.44, tags: ['foo', 'bar']) }
|
70
|
+
assert_equal_datagrams { |client| client.histogram('sample', 12.44, tags: { foo: 'bar' }) }
|
71
|
+
assert_equal_datagrams { |client| client.histogram('sample', 12.44, sample_rate: 0.1, tags: ['quc']) }
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_distribution_compatibility
|
75
|
+
assert_equal_datagrams { |client| client.distribution('sample', 12.44) }
|
76
|
+
assert_equal_datagrams { |client| client.distribution('sample', 12.44, no_prefix: true) }
|
77
|
+
assert_equal_datagrams { |client| client.distribution('sample', 12.44, sample_rate: 0.1) }
|
78
|
+
assert_equal_datagrams { |client| client.distribution('sample', 12.44, tags: ['foo', 'bar']) }
|
79
|
+
assert_equal_datagrams { |client| client.distribution('sample', 12.44, tags: { foo: 'bar' }) }
|
80
|
+
assert_equal_datagrams { |client| client.distribution('sample', 12.44, sample_rate: 0.1, tags: ['quc']) }
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_distribution_with_block_compatibility
|
84
|
+
Process.stubs(:clock_gettime).with(Process::CLOCK_MONOTONIC).returns(12.1)
|
85
|
+
assert_equal_datagrams do |client|
|
86
|
+
return_value = client.distribution('timing', tags: ['foo'], sample_rate: 0.1) { 'foo' }
|
87
|
+
assert_equal 'foo', return_value
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_service_check_compatibility
|
92
|
+
assert_equal_datagrams { |client| client.service_check('service', 0) }
|
93
|
+
assert_equal_datagrams { |client| client.service_check('service', :critical, no_prefix: true) }
|
94
|
+
assert_equal_datagrams { |client| client.event('foo', "bar\nbaz") }
|
95
|
+
assert_equal_datagrams do |client|
|
96
|
+
client.service_check('service', "ok", timestamp: Time.parse('2019-09-09T04:22:17Z'),
|
97
|
+
hostname: 'localhost', tags: ['foo'], message: 'bar')
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_event_compatibility
|
102
|
+
assert_equal_datagrams { |client| client.event('foo', "bar\nbaz") }
|
103
|
+
assert_equal_datagrams { |client| client.event('foo', "bar\nbaz", no_prefix: true) }
|
104
|
+
assert_equal_datagrams do |client|
|
105
|
+
client.event('Something happend', "And it's not good", timestamp: Time.parse('2019-09-09T04:22:17Z'),
|
106
|
+
hostname: 'localhost', tags: ['foo'], alert_type: 'warning', priority: 'low',
|
107
|
+
aggregation_key: 'foo', source_type_name: 'logs')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
MODES = [:normal, :with_prefix, :with_default_tags]
|
114
|
+
|
115
|
+
def assert_equal_datagrams(&block)
|
116
|
+
MODES.each do |mode|
|
117
|
+
legacy_datagram = with_legacy_client(mode) { |client| read_datagram(client, &block) }
|
118
|
+
new_datagram = with_new_client(mode) { |client| read_datagram(client, &block) }
|
119
|
+
|
120
|
+
assert_equal legacy_datagram, new_datagram, "The datagrams emitted were not the same in #{mode} mode"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def with_legacy_client(mode)
|
125
|
+
old_prefix = StatsD.prefix
|
126
|
+
StatsD.prefix = 'prefix' if mode == :with_prefix
|
127
|
+
|
128
|
+
old_default_tags = StatsD.default_tags
|
129
|
+
StatsD.default_tags = { key: 'value' } if mode == :with_default_tags
|
130
|
+
|
131
|
+
old_backend = StatsD.backend
|
132
|
+
new_backend = StatsD::Instrument::Backends::UDPBackend.new("#{@host}:#{@port}", :datadog)
|
133
|
+
StatsD.backend = new_backend
|
134
|
+
|
135
|
+
yield(StatsD)
|
136
|
+
ensure
|
137
|
+
new_backend.socket.close if new_backend&.socket
|
138
|
+
StatsD.backend = old_backend
|
139
|
+
StatsD.prefix = old_prefix
|
140
|
+
StatsD.default_tags = old_default_tags
|
141
|
+
end
|
142
|
+
|
143
|
+
def with_new_client(mode)
|
144
|
+
prefix = mode == :with_prefix ? 'prefix' : nil
|
145
|
+
default_tags = mode == :with_default_tags ? { key: 'value' } : nil
|
146
|
+
client = StatsD::Instrument::Client.new(
|
147
|
+
sink: StatsD::Instrument::UDPSink.new(@host, @port),
|
148
|
+
datagram_builder_class: StatsD::Instrument::DogStatsDDatagramBuilder,
|
149
|
+
prefix: prefix,
|
150
|
+
default_tags: default_tags
|
151
|
+
)
|
152
|
+
|
153
|
+
yield(client)
|
154
|
+
end
|
155
|
+
|
156
|
+
def read_datagram(client)
|
157
|
+
yield(client)
|
158
|
+
data, _origin = @server.recvfrom(100)
|
159
|
+
data
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
require 'statsd/instrument/client'
|
6
|
+
|
7
|
+
class DatagramBuilderTest < Minitest::Test
|
8
|
+
def setup
|
9
|
+
@datagram_builder = StatsD::Instrument::DatagramBuilder.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_normalize_name
|
13
|
+
assert_equal 'foo', @datagram_builder.send(:normalize_name, 'foo')
|
14
|
+
assert_equal 'fo_o', @datagram_builder.send(:normalize_name, 'fo|o')
|
15
|
+
assert_equal 'fo_o', @datagram_builder.send(:normalize_name, 'fo@o')
|
16
|
+
assert_equal 'fo_o', @datagram_builder.send(:normalize_name, 'fo:o')
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_normalize_unsupported_tag_names
|
20
|
+
assert_equal ['ignored'], @datagram_builder.send(:normalize_tags, ['igno|re,d'])
|
21
|
+
# Note: how this is interpreted by the backend is undefined.
|
22
|
+
# We rely on the user to not do stuff like this if they don't want to be surprised.
|
23
|
+
# We do not want to take the performance hit of normaling this.
|
24
|
+
assert_equal ['lol::class:omg::lol'], @datagram_builder.send(:normalize_tags, "lol::class" => "omg::lol")
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_normalize_tags_converts_hash_to_array
|
28
|
+
assert_equal ['tag:value'], @datagram_builder.send(:normalize_tags, tag: 'value')
|
29
|
+
assert_equal ['tag1:v1', 'tag2:v2'], @datagram_builder.send(:normalize_tags, tag1: 'v1', tag2: 'v2')
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_c
|
33
|
+
datagram = @datagram_builder.c('foo', 1, nil, nil)
|
34
|
+
assert_equal "foo:1|c", datagram
|
35
|
+
|
36
|
+
datagram = @datagram_builder.c('fo:o', 10, 0.1, nil)
|
37
|
+
assert_equal "fo_o:10|c|@0.1", datagram
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_ms
|
41
|
+
datagram = @datagram_builder.ms('foo', 1, nil, nil)
|
42
|
+
assert_equal "foo:1|ms", datagram
|
43
|
+
|
44
|
+
datagram = @datagram_builder.ms('fo:o', 10, 0.1, nil)
|
45
|
+
assert_equal "fo_o:10|ms|@0.1", datagram
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_g
|
49
|
+
datagram = @datagram_builder.g('foo', 1, nil, nil)
|
50
|
+
assert_equal "foo:1|g", datagram
|
51
|
+
|
52
|
+
datagram = @datagram_builder.g('fo|o', 10, 0.01, nil)
|
53
|
+
assert_equal "fo_o:10|g|@0.01", datagram
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_s
|
57
|
+
datagram = @datagram_builder.s('foo', 1, nil, nil)
|
58
|
+
assert_equal "foo:1|s", datagram
|
59
|
+
|
60
|
+
datagram = @datagram_builder.s('fo@o', 10, 0.01, nil)
|
61
|
+
assert_equal "fo_o:10|s|@0.01", datagram
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_h
|
65
|
+
datagram = @datagram_builder.h('foo', 1, nil, nil)
|
66
|
+
assert_equal "foo:1|h", datagram
|
67
|
+
|
68
|
+
datagram = @datagram_builder.h('fo@o', 10, 0.01, nil)
|
69
|
+
assert_equal "fo_o:10|h|@0.01", datagram
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_d
|
73
|
+
datagram = @datagram_builder.d('foo', 1, nil, nil)
|
74
|
+
assert_equal "foo:1|d", datagram
|
75
|
+
|
76
|
+
datagram = @datagram_builder.d('fo@o', 10, 0.01, nil)
|
77
|
+
assert_equal "fo_o:10|d|@0.01", datagram
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_tags
|
81
|
+
datagram = @datagram_builder.d('foo', 10, nil, ['foo', 'bar'])
|
82
|
+
assert_equal "foo:10|d|#foo,bar", datagram
|
83
|
+
|
84
|
+
datagram = @datagram_builder.d('foo', 10, 0.1, ['foo:bar'])
|
85
|
+
assert_equal "foo:10|d|@0.1|#foo:bar", datagram
|
86
|
+
|
87
|
+
datagram = @datagram_builder.d('foo', 10, 1, foo: 'bar', baz: 'quc')
|
88
|
+
assert_equal "foo:10|d|#foo:bar,baz:quc", datagram
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_prefix
|
92
|
+
datagram_builder = StatsD::Instrument::DatagramBuilder.new(prefix: 'foo')
|
93
|
+
datagram = datagram_builder.c('bar', 1, nil, nil)
|
94
|
+
assert_equal 'foo.bar:1|c', datagram
|
95
|
+
|
96
|
+
# The prefix should also be normalized
|
97
|
+
datagram_builder = StatsD::Instrument::DatagramBuilder.new(prefix: 'foo|bar')
|
98
|
+
datagram = datagram_builder.c('baz', 1, nil, nil)
|
99
|
+
assert_equal 'foo_bar.baz:1|c', datagram
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_default_tags
|
103
|
+
datagram_builder = StatsD::Instrument::DatagramBuilder.new(default_tags: ['foo'])
|
104
|
+
datagram = datagram_builder.c('bar', 1, nil, nil)
|
105
|
+
assert_equal 'bar:1|c|#foo', datagram
|
106
|
+
|
107
|
+
datagram = datagram_builder.c('bar', 1, nil, a: 'b')
|
108
|
+
assert_equal 'bar:1|c|#a:b,foo', datagram
|
109
|
+
|
110
|
+
# We do not filter out duplicates, because detecting dupes is too time consuming.
|
111
|
+
# We let the server deal with the situation
|
112
|
+
datagram = datagram_builder.c('bar', 1, nil, ['foo'])
|
113
|
+
assert_equal 'bar:1|c|#foo,foo', datagram
|
114
|
+
|
115
|
+
# Default tags are also normalized
|
116
|
+
datagram_builder = StatsD::Instrument::DatagramBuilder.new(default_tags: ['f,o|o'])
|
117
|
+
datagram = datagram_builder.c('bar', 1, nil, nil)
|
118
|
+
assert_equal 'bar:1|c|#foo', datagram
|
119
|
+
end
|
120
|
+
end
|
data/test/deprecations_test.rb
CHANGED
@@ -4,13 +4,13 @@ require 'test_helper'
|
|
4
4
|
|
5
5
|
class DeprecationsTest < Minitest::Test
|
6
6
|
unless StatsD::Instrument.strict_mode_enabled?
|
7
|
-
# rubocop:disable StatsD/MetaprogrammingPositionalArguments
|
8
7
|
class InstrumentedClass
|
9
8
|
extend StatsD::Instrument
|
10
9
|
def foo; end
|
11
|
-
statsd_count :foo, '
|
10
|
+
statsd_count :foo, 'frequency', 0.5, ['tag'] # rubocop:disable StatsD/MetaprogrammingPositionalArguments
|
11
|
+
statsd_measure :foo, 'latency', as_dist: true # rubocop:disable StatsD/MeasureAsDistArgument
|
12
|
+
statsd_count_success :foo, 'frequency', prefix: 'foo' # rubocop:disable StatsD/MetricPrefixArgument
|
12
13
|
end
|
13
|
-
# rubocop:enable StatsD/MetaprogrammingPositionalArguments
|
14
14
|
end
|
15
15
|
|
16
16
|
include StatsD::Instrument::Assertions
|
@@ -19,6 +19,30 @@ class DeprecationsTest < Minitest::Test
|
|
19
19
|
skip("Deprecation are not supported in strict mode") if StatsD::Instrument.strict_mode_enabled?
|
20
20
|
end
|
21
21
|
|
22
|
+
def test__deprecated__metaprogramming_method_with_positional_arguments
|
23
|
+
metrics = capture_statsd_calls { InstrumentedClass.new.foo }
|
24
|
+
metric = metrics[0]
|
25
|
+
assert_equal :c, metric.type
|
26
|
+
assert_equal 'frequency', metric.name
|
27
|
+
assert_equal 1, metric.value
|
28
|
+
assert_equal 0.5, metric.sample_rate
|
29
|
+
assert_equal ["tag"], metric.tags
|
30
|
+
end
|
31
|
+
|
32
|
+
def test__deprecated__metaprogramming_statsd_measure_with_as_dist
|
33
|
+
metrics = capture_statsd_calls { InstrumentedClass.new.foo }
|
34
|
+
metric = metrics[1]
|
35
|
+
assert_equal :d, metric.type
|
36
|
+
assert_equal 'latency', metric.name
|
37
|
+
end
|
38
|
+
|
39
|
+
def test__deprecated__metaprogramming_statsd_count_with_prefix
|
40
|
+
metrics = capture_statsd_calls { InstrumentedClass.new.foo }
|
41
|
+
metric = metrics[2]
|
42
|
+
assert_equal :c, metric.type
|
43
|
+
assert_equal 'foo.frequency.success', metric.name
|
44
|
+
end
|
45
|
+
|
22
46
|
# rubocop:disable StatsD/MetricValueKeywordArgument
|
23
47
|
def test__deprecated__statsd_measure_with_explicit_value_as_keyword_argument
|
24
48
|
metric = capture_statsd_call { StatsD.measure('values.foobar', value: 42) }
|
@@ -27,11 +51,13 @@ class DeprecationsTest < Minitest::Test
|
|
27
51
|
assert_equal :ms, metric.type
|
28
52
|
end
|
29
53
|
|
54
|
+
# rubocop:disable StatsD/MeasureAsDistArgument
|
30
55
|
def test__deprecated__statsd_measure_with_explicit_value_keyword_and_distribution_override
|
31
56
|
metric = capture_statsd_call { StatsD.measure('values.foobar', value: 42, as_dist: true) }
|
32
57
|
assert_equal 42, metric.value
|
33
58
|
assert_equal :d, metric.type
|
34
59
|
end
|
60
|
+
# rubocop:enable StatsD/MeasureAsDistArgument
|
35
61
|
|
36
62
|
def test__deprecated__statsd_increment_with_value_as_keyword_argument
|
37
63
|
metric = capture_statsd_call { StatsD.increment('values.foobar', value: 2) }
|
@@ -67,14 +93,34 @@ class DeprecationsTest < Minitest::Test
|
|
67
93
|
end
|
68
94
|
# rubocop:enable StatsD/PositionalArguments
|
69
95
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
assert_equal
|
74
|
-
|
75
|
-
|
76
|
-
|
96
|
+
# rubocop:disable StatsD/MeasureAsDistArgument
|
97
|
+
def test__deprecated__statsd_measure_with_explicit_value_and_distribution_override
|
98
|
+
metric = capture_statsd_call { StatsD.measure('values.foobar', 42, as_dist: true) }
|
99
|
+
assert_equal :d, metric.type
|
100
|
+
end
|
101
|
+
|
102
|
+
def test__deprecated__statsd_measure_use_distribution_override_for_a_block
|
103
|
+
metric = capture_statsd_call do
|
104
|
+
StatsD.measure('values.foobar', as_dist: true) { 'foo' }
|
105
|
+
end
|
106
|
+
assert_equal :d, metric.type
|
107
|
+
end
|
108
|
+
|
109
|
+
def test__deprecated__statsd_measure_as_distribution_returns_return_value_of_block_even_if_nil
|
110
|
+
return_value = StatsD.measure('values.foobar', as_dist: true) { nil }
|
111
|
+
assert_nil return_value
|
112
|
+
end
|
113
|
+
# rubocop:enable StatsD/MeasureAsDistArgument
|
114
|
+
|
115
|
+
# rubocop:disable StatsD/MetricPrefixArgument
|
116
|
+
def test__deprecated__override_name_prefix
|
117
|
+
m = capture_statsd_call { StatsD.increment('counter', prefix: "foobar") }
|
118
|
+
assert_equal 'foobar.counter', m.name
|
119
|
+
|
120
|
+
m = capture_statsd_call { StatsD.increment('counter', prefix: "foobar", no_prefix: true) }
|
121
|
+
assert_equal 'counter', m.name
|
77
122
|
end
|
123
|
+
# rubocop:enable StatsD/MetricPrefixArgument
|
78
124
|
|
79
125
|
protected
|
80
126
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
require 'statsd/instrument/client'
|
6
|
+
|
7
|
+
class DogStatsDDatagramBuilderTest < Minitest::Test
|
8
|
+
def setup
|
9
|
+
@datagram_builder = StatsD::Instrument::DogStatsDDatagramBuilder.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_raises_on_unsupported_metrics
|
13
|
+
assert_raises(NotImplementedError) { @datagram_builder.kv('foo', 10, nil, nil) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_service_check
|
17
|
+
assert_equal '_sc|service|0', @datagram_builder._sc('service', :ok)
|
18
|
+
datagram = @datagram_builder._sc('service', :warning, timestamp: Time.parse('2019-09-30T04:22:12Z'),
|
19
|
+
hostname: 'localhost', tags: { foo: 'bar|baz' }, message: 'blah')
|
20
|
+
assert_equal "_sc|service|1|h:localhost|d:1569817332|#foo:barbaz|m:blah", datagram
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_event
|
24
|
+
assert_equal '_e{5,5}:hello|world', @datagram_builder._e('hello', "world")
|
25
|
+
|
26
|
+
datagram = @datagram_builder._e("testing", "with\nnewline", timestamp: Time.parse('2019-09-30T04:22:12Z'),
|
27
|
+
hostname: 'localhost', aggregation_key: 'my-key', priority: 'low', source_type_name: 'source',
|
28
|
+
alert_type: 'success', tags: { foo: 'bar|baz' })
|
29
|
+
assert_equal '_e{7,13}:testing|with\\nnewline|h:localhost|d:1569817332|k:my-key|' \
|
30
|
+
'p:low|s:source|t:success|#foo:barbaz', datagram
|
31
|
+
end
|
32
|
+
end
|