statsd-instrument 3.9.9 → 3.10.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/workflows/tests.yml +1 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +21 -0
- data/lib/statsd/instrument/aggregator.rb +166 -45
- data/lib/statsd/instrument/client.rb +85 -4
- data/lib/statsd/instrument/compiled_metric.rb +465 -0
- data/lib/statsd/instrument/version.rb +1 -1
- data/lib/statsd/instrument.rb +2 -1
- data/test/aggregator_test.rb +158 -6
- data/test/client_test.rb +75 -4
- data/test/compiled_metric/counter_test.rb +396 -0
- data/test/compiled_metric/distribution_test.rb +503 -0
- data/test/compiled_metric/gauge_test.rb +395 -0
- data/test/compiled_metric_test.rb +447 -0
- data/test/dispatcher_stats_test.rb +6 -6
- data/test/integration_test.rb +52 -0
- metadata +12 -3
data/test/client_test.rb
CHANGED
|
@@ -8,6 +8,10 @@ class ClientTest < Minitest::Test
|
|
|
8
8
|
@dogstatsd_client = StatsD::Instrument::Client.new(implementation: "datadog")
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
def teardown
|
|
12
|
+
@client.instance_variable_get(:@aggregator).instance_variable_get(:@flush_thread)&.kill
|
|
13
|
+
end
|
|
14
|
+
|
|
11
15
|
def test_client_from_env
|
|
12
16
|
env = StatsD::Instrument::Environment.new(
|
|
13
17
|
"STATSD_ENV" => "production",
|
|
@@ -255,11 +259,78 @@ class ClientTest < Minitest::Test
|
|
|
255
259
|
client = StatsD::Instrument::Client.new(sink: mock_sink, default_sample_rate: 0.5, enable_aggregation: true)
|
|
256
260
|
5.times { client.distribution("metric", 60) }
|
|
257
261
|
client.force_flush
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def test_increment_with_aggregation_respects_sample_rate
|
|
265
|
+
# Test that increment with aggregation properly samples before aggregation
|
|
266
|
+
# and preserves sample_rate in the datagram
|
|
267
|
+
sink = StatsD::Instrument::CaptureSink.new(parent: StatsD::Instrument::NullSink.new)
|
|
268
|
+
client = StatsD::Instrument::Client.new(sink: sink, enable_aggregation: true)
|
|
269
|
+
|
|
270
|
+
# With sample_rate=1.0, all increments should be counted
|
|
271
|
+
client.increment("counter", 1, sample_rate: 1.0)
|
|
272
|
+
client.increment("counter", 2, sample_rate: 1.0)
|
|
273
|
+
client.force_flush
|
|
274
|
+
|
|
275
|
+
assert_equal(1, sink.datagrams.size)
|
|
276
|
+
datagram = sink.datagrams.first
|
|
277
|
+
assert_equal("counter", datagram.name)
|
|
278
|
+
assert_equal(3, datagram.value)
|
|
279
|
+
assert_equal(1.0, datagram.sample_rate)
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def test_increment_with_aggregation_applies_sampling_before_aggregation
|
|
283
|
+
# Test that sampling happens BEFORE aggregation, not after
|
|
284
|
+
# This is the key fix - previously sampling was bypassed when aggregation was enabled
|
|
285
|
+
mock_sink = mock("sink")
|
|
286
|
+
# First call samples out (false), second call samples in (true)
|
|
287
|
+
mock_sink.stubs(:sample?).returns(false, true)
|
|
288
|
+
mock_sink.expects(:<<).with("counter:3|c|@0.5")
|
|
289
|
+
mock_sink.stubs(:flush)
|
|
290
|
+
|
|
291
|
+
client = StatsD::Instrument::Client.new(sink: mock_sink, enable_aggregation: true)
|
|
292
|
+
|
|
293
|
+
# First increment should be sampled out
|
|
294
|
+
client.increment("counter", 5, sample_rate: 0.5)
|
|
295
|
+
# Second increment should be sampled in
|
|
296
|
+
client.increment("counter", 3, sample_rate: 0.5)
|
|
297
|
+
client.force_flush
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def test_measure_with_aggregation_respects_sample_rate
|
|
301
|
+
# Test that measure (timing) with aggregation properly handles sample_rate
|
|
302
|
+
sink = StatsD::Instrument::CaptureSink.new(parent: StatsD::Instrument::NullSink.new)
|
|
303
|
+
client = StatsD::Instrument::Client.new(
|
|
304
|
+
sink: sink,
|
|
305
|
+
enable_aggregation: true,
|
|
306
|
+
datagram_builder_class: StatsD::Instrument::StatsDDatagramBuilder,
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
client.measure("timing", 100, sample_rate: 0.5)
|
|
310
|
+
client.measure("timing", 200, sample_rate: 0.5)
|
|
311
|
+
client.force_flush
|
|
312
|
+
|
|
313
|
+
assert_equal(1, sink.datagrams.size)
|
|
314
|
+
datagram = sink.datagrams.first
|
|
315
|
+
assert_equal("timing", datagram.name)
|
|
316
|
+
assert_equal(0.5, datagram.sample_rate)
|
|
317
|
+
assert_includes(datagram.source, "|@0.5")
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
def test_histogram_with_aggregation_respects_sample_rate
|
|
321
|
+
# Test that histogram with aggregation properly handles sample_rate
|
|
322
|
+
sink = StatsD::Instrument::CaptureSink.new(parent: StatsD::Instrument::NullSink.new)
|
|
323
|
+
client = StatsD::Instrument::Client.new(sink: sink, enable_aggregation: true)
|
|
324
|
+
|
|
325
|
+
client.histogram("hist", 100, sample_rate: 0.25)
|
|
326
|
+
client.histogram("hist", 200, sample_rate: 0.25)
|
|
327
|
+
client.force_flush
|
|
258
328
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
329
|
+
assert_equal(1, sink.datagrams.size)
|
|
330
|
+
datagram = sink.datagrams.first
|
|
331
|
+
assert_equal("hist", datagram.name)
|
|
332
|
+
assert_equal(0.25, datagram.sample_rate)
|
|
333
|
+
assert_includes(datagram.source, "|@0.25")
|
|
263
334
|
end
|
|
264
335
|
|
|
265
336
|
def test_clone_with_prefix_option
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
class CompiledMetricCounterTest < Minitest::Test
|
|
6
|
+
def setup
|
|
7
|
+
super
|
|
8
|
+
@old_client = StatsD.singleton_client
|
|
9
|
+
@sink = StatsD::Instrument::CaptureSink.new(parent: StatsD::Instrument::NullSink.new)
|
|
10
|
+
StatsD.singleton_client = StatsD::Instrument::Client.new(
|
|
11
|
+
sink: @sink,
|
|
12
|
+
prefix: "test",
|
|
13
|
+
default_tags: [],
|
|
14
|
+
enable_aggregation: false,
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def teardown
|
|
19
|
+
super
|
|
20
|
+
@sink.clear
|
|
21
|
+
StatsD.singleton_client = @old_client
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_counter_without_define
|
|
25
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter)
|
|
26
|
+
|
|
27
|
+
error = assert_raises(ArgumentError) do
|
|
28
|
+
metric.increment(5)
|
|
29
|
+
end
|
|
30
|
+
assert_equal("Every CompiledMetric subclass needs to call `define` before first invocation of increment.", error.message)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def test_define_counter_without_tags
|
|
34
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
35
|
+
define(name: "foo.bar")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
metric.increment(5)
|
|
39
|
+
|
|
40
|
+
datagram = @sink.datagrams.first
|
|
41
|
+
assert_equal("test.foo.bar", datagram.name)
|
|
42
|
+
assert_equal(5, datagram.value)
|
|
43
|
+
assert_equal(:c, datagram.type)
|
|
44
|
+
assert_nil(datagram.tags)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_define_counter_with_static_tags
|
|
48
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
49
|
+
define(
|
|
50
|
+
name: "foo.bar",
|
|
51
|
+
static_tags: { service: "web", env: "prod" },
|
|
52
|
+
)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
metric.increment(5)
|
|
56
|
+
|
|
57
|
+
datagram = @sink.datagrams.first
|
|
58
|
+
assert_equal("test.foo.bar", datagram.name)
|
|
59
|
+
assert_equal(5, datagram.value)
|
|
60
|
+
assert_equal(:c, datagram.type)
|
|
61
|
+
assert_equal(["env:prod", "service:web"], datagram.tags.sort)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_define_counter_with_dynamic_tags
|
|
65
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
66
|
+
define(
|
|
67
|
+
name: "foo.bar",
|
|
68
|
+
tags: { shop_id: Integer, user_id: Integer },
|
|
69
|
+
)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
metric.increment(1, shop_id: 123, user_id: 456)
|
|
73
|
+
|
|
74
|
+
datagram = @sink.datagrams.first
|
|
75
|
+
assert_equal("test.foo.bar", datagram.name)
|
|
76
|
+
assert_equal(1, datagram.value)
|
|
77
|
+
assert_equal(:c, datagram.type)
|
|
78
|
+
assert_equal(["shop_id:123", "user_id:456"], datagram.tags.sort)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_define_counter_with_mixed_tags
|
|
82
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
83
|
+
define(
|
|
84
|
+
name: "foo.bar",
|
|
85
|
+
static_tags: { service: "web" },
|
|
86
|
+
tags: { shop_id: Integer },
|
|
87
|
+
)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
metric.increment(3, shop_id: 999)
|
|
91
|
+
|
|
92
|
+
datagram = @sink.datagrams.first
|
|
93
|
+
assert_equal("test.foo.bar", datagram.name)
|
|
94
|
+
assert_equal(3, datagram.value)
|
|
95
|
+
assert_equal(["service:web", "shop_id:999"], datagram.tags.sort)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def test_define_counter_with_string_tags
|
|
99
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
100
|
+
define(
|
|
101
|
+
name: "foo.bar",
|
|
102
|
+
tags: { country: String, region: String },
|
|
103
|
+
)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
metric.increment(2, country: "US", region: "West")
|
|
107
|
+
|
|
108
|
+
datagram = @sink.datagrams.first
|
|
109
|
+
assert_equal("test.foo.bar", datagram.name)
|
|
110
|
+
assert_equal(2, datagram.value)
|
|
111
|
+
assert_equal(["country:US", "region:West"], datagram.tags.sort)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def test_define_counter_with_float_tags
|
|
115
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
116
|
+
define(
|
|
117
|
+
name: "foo.bar",
|
|
118
|
+
tags: { rate: Float },
|
|
119
|
+
)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
metric.increment(1, rate: 1.5)
|
|
123
|
+
|
|
124
|
+
datagram = @sink.datagrams.first
|
|
125
|
+
assert_equal("test.foo.bar", datagram.name)
|
|
126
|
+
assert_equal(1, datagram.value)
|
|
127
|
+
# Float formatting uses %f which outputs full precision
|
|
128
|
+
assert_equal(1, datagram.tags.size)
|
|
129
|
+
assert_match(/^rate:1\.5/, datagram.tags.first)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def test_define_counter_no_prefix
|
|
133
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
134
|
+
define(
|
|
135
|
+
name: "foo.bar",
|
|
136
|
+
no_prefix: true,
|
|
137
|
+
)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
metric.increment(1)
|
|
141
|
+
|
|
142
|
+
datagram = @sink.datagrams.first
|
|
143
|
+
assert_equal("foo.bar", datagram.name) # No "test." prefix
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def test_multiple_increments_same_tags
|
|
147
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
148
|
+
define(
|
|
149
|
+
name: "foo.bar",
|
|
150
|
+
tags: { shop_id: Integer },
|
|
151
|
+
)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
metric.increment(1, shop_id: 123)
|
|
155
|
+
metric.increment(2, shop_id: 123)
|
|
156
|
+
metric.increment(3, shop_id: 123)
|
|
157
|
+
|
|
158
|
+
assert_equal(3, @sink.datagrams.size)
|
|
159
|
+
@sink.datagrams.each do |datagram|
|
|
160
|
+
assert_equal(["shop_id:123"], datagram.tags)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def test_multiple_increments_different_tags
|
|
165
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
166
|
+
define(
|
|
167
|
+
name: "foo.bar",
|
|
168
|
+
tags: { shop_id: Integer },
|
|
169
|
+
)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
metric.increment(1, shop_id: 123)
|
|
173
|
+
metric.increment(1, shop_id: 456)
|
|
174
|
+
metric.increment(1, shop_id: 789)
|
|
175
|
+
|
|
176
|
+
assert_equal(3, @sink.datagrams.size)
|
|
177
|
+
assert_equal(["shop_id:123"], @sink.datagrams[0].tags)
|
|
178
|
+
assert_equal(["shop_id:456"], @sink.datagrams[1].tags)
|
|
179
|
+
assert_equal(["shop_id:789"], @sink.datagrams[2].tags)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def test_counter_includes_default_tags_from_client
|
|
183
|
+
# Create a client with default tags
|
|
184
|
+
client = StatsD::Instrument::Client.new(
|
|
185
|
+
sink: @sink,
|
|
186
|
+
prefix: "test",
|
|
187
|
+
default_tags: ["env:production", "region:us-east"],
|
|
188
|
+
enable_aggregation: false,
|
|
189
|
+
)
|
|
190
|
+
StatsD.singleton_client = client
|
|
191
|
+
|
|
192
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
193
|
+
define(
|
|
194
|
+
name: "foo.bar",
|
|
195
|
+
static_tags: { service: "web" },
|
|
196
|
+
)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
metric.increment(1)
|
|
200
|
+
|
|
201
|
+
datagram = @sink.datagrams.first
|
|
202
|
+
assert_equal("test.foo.bar", datagram.name)
|
|
203
|
+
# Should include default tags from client + static tags
|
|
204
|
+
assert_equal(["env:production", "region:us-east", "service:web"], datagram.tags.sort)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def test_counter_includes_default_tags_with_no_prefix
|
|
208
|
+
# Create a client with default tags
|
|
209
|
+
client = StatsD::Instrument::Client.new(
|
|
210
|
+
sink: @sink,
|
|
211
|
+
prefix: "test",
|
|
212
|
+
default_tags: ["env:production", "region:us-east"],
|
|
213
|
+
enable_aggregation: false,
|
|
214
|
+
)
|
|
215
|
+
StatsD.singleton_client = client
|
|
216
|
+
|
|
217
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
218
|
+
define(
|
|
219
|
+
name: "foo.bar",
|
|
220
|
+
static_tags: { service: "web" },
|
|
221
|
+
no_prefix: true,
|
|
222
|
+
)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
metric.increment(1)
|
|
226
|
+
|
|
227
|
+
datagram = @sink.datagrams.first
|
|
228
|
+
assert_equal("foo.bar", datagram.name) # No prefix
|
|
229
|
+
# Should include default tags even when no_prefix is true
|
|
230
|
+
assert_equal(["env:production", "region:us-east", "service:web"], datagram.tags.sort)
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def test_counter_does_not_support_blocks
|
|
234
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
235
|
+
define(
|
|
236
|
+
name: "foo.bar",
|
|
237
|
+
static_tags: { service: "web" },
|
|
238
|
+
tags: { shop_id: Integer },
|
|
239
|
+
)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
block_called = false
|
|
243
|
+
metric.increment(shop_id: 999) do
|
|
244
|
+
block_called = true
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
datagram = @sink.datagrams.first
|
|
248
|
+
assert_equal("test.foo.bar", datagram.name)
|
|
249
|
+
# Default value
|
|
250
|
+
assert_equal(1, datagram.value)
|
|
251
|
+
refute(block_called)
|
|
252
|
+
assert_equal(["service:web", "shop_id:999"], datagram.tags.sort)
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
class CompiledMetricCounterWithAggregationTest < Minitest::Test
|
|
257
|
+
def setup
|
|
258
|
+
super
|
|
259
|
+
@old_client = StatsD.singleton_client
|
|
260
|
+
@sink = StatsD::Instrument::CaptureSink.new(parent: StatsD::Instrument::NullSink.new)
|
|
261
|
+
@aggregator = StatsD::Instrument::Aggregator.new(
|
|
262
|
+
@sink,
|
|
263
|
+
StatsD::Instrument::DatagramBuilder,
|
|
264
|
+
"test",
|
|
265
|
+
[],
|
|
266
|
+
flush_interval: 0.1,
|
|
267
|
+
)
|
|
268
|
+
client = StatsD::Instrument::Client.new(
|
|
269
|
+
sink: @sink,
|
|
270
|
+
prefix: "test",
|
|
271
|
+
default_tags: [],
|
|
272
|
+
enable_aggregation: true,
|
|
273
|
+
)
|
|
274
|
+
client.instance_variable_set(:@aggregator, @aggregator)
|
|
275
|
+
StatsD.singleton_client = client
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def teardown
|
|
279
|
+
super
|
|
280
|
+
@sink.clear
|
|
281
|
+
StatsD.singleton_client = @old_client
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def test_aggregates_precompiled_metrics
|
|
285
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
286
|
+
define(
|
|
287
|
+
name: "foo.bar",
|
|
288
|
+
tags: { shop_id: Integer },
|
|
289
|
+
)
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
metric.increment(1, shop_id: 123)
|
|
293
|
+
metric.increment(2, shop_id: 123)
|
|
294
|
+
metric.increment(3, shop_id: 123)
|
|
295
|
+
|
|
296
|
+
@aggregator.flush
|
|
297
|
+
|
|
298
|
+
assert_equal(1, @sink.datagrams.size)
|
|
299
|
+
datagram = @sink.datagrams.first
|
|
300
|
+
assert_equal(6, datagram.value) # 1 + 2 + 3
|
|
301
|
+
assert_equal(["shop_id:123"], datagram.tags)
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def test_aggregates_different_tag_combinations_separately
|
|
305
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
306
|
+
define(
|
|
307
|
+
name: "foo.bar",
|
|
308
|
+
tags: { shop_id: Integer },
|
|
309
|
+
)
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
metric.increment(1, shop_id: 123)
|
|
313
|
+
metric.increment(2, shop_id: 456)
|
|
314
|
+
metric.increment(3, shop_id: 123)
|
|
315
|
+
|
|
316
|
+
@aggregator.flush
|
|
317
|
+
|
|
318
|
+
assert_equal(2, @sink.datagrams.size)
|
|
319
|
+
|
|
320
|
+
shop_123_datagram = @sink.datagrams.find { |d| d.tags.include?("shop_id:123") }
|
|
321
|
+
shop_456_datagram = @sink.datagrams.find { |d| d.tags.include?("shop_id:456") }
|
|
322
|
+
|
|
323
|
+
assert_equal(4, shop_123_datagram.value) # 1 + 3
|
|
324
|
+
assert_equal(2, shop_456_datagram.value)
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
def test_aggregates_static_tag_metrics
|
|
328
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
329
|
+
define(
|
|
330
|
+
name: "foo.bar",
|
|
331
|
+
static_tags: { service: "web" },
|
|
332
|
+
)
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
metric.increment(1)
|
|
336
|
+
metric.increment(2)
|
|
337
|
+
metric.increment(5)
|
|
338
|
+
|
|
339
|
+
@aggregator.flush
|
|
340
|
+
|
|
341
|
+
assert_equal(1, @sink.datagrams.size)
|
|
342
|
+
datagram = @sink.datagrams.first
|
|
343
|
+
assert_equal(8, datagram.value) # 1 + 2 + 5
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
def test_sample_rate_equal_to_1_with_aggregation
|
|
347
|
+
# When aggregating with sample_rate, sampling happens before aggregation
|
|
348
|
+
# This test verifies that with sample_rate=1.0, all increments are aggregated
|
|
349
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
350
|
+
define(
|
|
351
|
+
name: "foo.bar",
|
|
352
|
+
static_tags: { service: "web" },
|
|
353
|
+
sample_rate: 1.0,
|
|
354
|
+
)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
# With sample_rate=1.0, all increments should be aggregated
|
|
358
|
+
metric.increment(5)
|
|
359
|
+
metric.increment(3)
|
|
360
|
+
|
|
361
|
+
@aggregator.flush
|
|
362
|
+
|
|
363
|
+
assert_equal(1, @sink.datagrams.size)
|
|
364
|
+
datagram = @sink.datagrams.first
|
|
365
|
+
assert_equal("test.foo.bar", datagram.name)
|
|
366
|
+
assert_equal(8, datagram.value) # 5 + 3
|
|
367
|
+
# Sample rate should be 1.0 when aggregating
|
|
368
|
+
assert_equal(1.0, datagram.sample_rate)
|
|
369
|
+
refute_includes(datagram.source, "|@")
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def test_sample_rate_applied_with_aggregation
|
|
373
|
+
# When aggregating with sample_rate, sampling happens before aggregation
|
|
374
|
+
# This test verifies that with sample_rate=0.5, all increments are aggregated
|
|
375
|
+
metric = Class.new(StatsD::Instrument::CompiledMetric::Counter) do
|
|
376
|
+
define(
|
|
377
|
+
name: "foo.bar",
|
|
378
|
+
static_tags: { service: "web" },
|
|
379
|
+
sample_rate: 0.5,
|
|
380
|
+
)
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
metric.increment(5)
|
|
384
|
+
metric.increment(3)
|
|
385
|
+
|
|
386
|
+
@aggregator.flush
|
|
387
|
+
|
|
388
|
+
assert_equal(1, @sink.datagrams.size)
|
|
389
|
+
datagram = @sink.datagrams.first
|
|
390
|
+
assert_equal("test.foo.bar", datagram.name)
|
|
391
|
+
assert_equal(8, datagram.value) # 5 + 3
|
|
392
|
+
# Sample rate should be 1.0 when aggregating
|
|
393
|
+
assert_equal(0.5, datagram.sample_rate)
|
|
394
|
+
assert_includes(datagram.source, "|@")
|
|
395
|
+
end
|
|
396
|
+
end
|