statsd-instrument 3.5.12 → 3.6.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/CHANGELOG.md +4 -0
- data/lib/statsd/instrument/client.rb +29 -21
- data/lib/statsd/instrument/datagram_builder.rb +43 -26
- data/lib/statsd/instrument/dogstatsd_datagram_builder.rb +20 -4
- data/lib/statsd/instrument/statsd_datagram_builder.rb +2 -4
- data/lib/statsd/instrument/version.rb +1 -1
- data/test/client_test.rb +1 -1
- data/test/datagram_builder_test.rb +7 -7
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0575c6d7547ea1494ba62807fa7ffd10a0d04b58a762eddf3eac56c47cd2c21e
|
4
|
+
data.tar.gz: 8370611d71ed66a31e67e150646df41f94f393cdb0bc953e23624113e99ffbd5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41fe6f71cd25a79fdfa73f1e53e0976333af4cd2ea7387832564b6991014d432e135c7e9e5a770f4d436ce23770811e21048d4ccf28f2a8d1b77debc3137d59a
|
7
|
+
data.tar.gz: 4db9fb5d52dd7258e8a018de3fcdd90a93ecfa01fea3142f47fb3ef0150de30998a7a422dde012ffc8de9e95eded01c41896f78886df07fc8163dc530e0e2e22
|
data/CHANGELOG.md
CHANGED
@@ -140,13 +140,15 @@ module StatsD
|
|
140
140
|
# on their frequency, rather than changing the default sample rate.
|
141
141
|
#
|
142
142
|
# @return [Float] (default: 1.0) A value between 0.0 and 1.0.
|
143
|
-
|
143
|
+
def default_sample_rate
|
144
|
+
@default_sample_rate || 1.0
|
145
|
+
end
|
144
146
|
|
145
147
|
# Instantiates a new client.
|
146
148
|
# @see .from_env to instantiate a client using environment variables.
|
147
149
|
def initialize(
|
148
150
|
prefix: nil,
|
149
|
-
default_sample_rate:
|
151
|
+
default_sample_rate: nil,
|
150
152
|
default_tags: nil,
|
151
153
|
implementation: "datadog",
|
152
154
|
sink: StatsD::Instrument::NullSink.new,
|
@@ -199,9 +201,10 @@ module StatsD
|
|
199
201
|
# @return [void]
|
200
202
|
def increment(name, value = 1, sample_rate: nil, tags: nil, no_prefix: false)
|
201
203
|
sample_rate ||= @default_sample_rate
|
202
|
-
|
203
|
-
|
204
|
-
|
204
|
+
if sample_rate.nil? || sample?(sample_rate)
|
205
|
+
emit(datagram_builder(no_prefix: no_prefix).c(name, value, sample_rate, tags))
|
206
|
+
end
|
207
|
+
StatsD::Instrument::VOID
|
205
208
|
end
|
206
209
|
|
207
210
|
# Emits a timing metric.
|
@@ -217,9 +220,10 @@ module StatsD
|
|
217
220
|
end
|
218
221
|
|
219
222
|
sample_rate ||= @default_sample_rate
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
+
if sample_rate.nil? || sample?(sample_rate)
|
224
|
+
emit(datagram_builder(no_prefix: no_prefix).ms(name, value, sample_rate, tags))
|
225
|
+
end
|
226
|
+
StatsD::Instrument::VOID
|
223
227
|
end
|
224
228
|
|
225
229
|
# Emits a gauge metric.
|
@@ -237,9 +241,10 @@ module StatsD
|
|
237
241
|
# @return [void]
|
238
242
|
def gauge(name, value, sample_rate: nil, tags: nil, no_prefix: false)
|
239
243
|
sample_rate ||= @default_sample_rate
|
240
|
-
|
241
|
-
|
242
|
-
|
244
|
+
if sample_rate.nil? || sample?(sample_rate)
|
245
|
+
emit(datagram_builder(no_prefix: no_prefix).g(name, value, sample_rate, tags))
|
246
|
+
end
|
247
|
+
StatsD::Instrument::VOID
|
243
248
|
end
|
244
249
|
|
245
250
|
# Emits a set metric, which counts distinct values.
|
@@ -251,9 +256,10 @@ module StatsD
|
|
251
256
|
# @return [void]
|
252
257
|
def set(name, value, sample_rate: nil, tags: nil, no_prefix: false)
|
253
258
|
sample_rate ||= @default_sample_rate
|
254
|
-
|
255
|
-
|
256
|
-
|
259
|
+
if sample_rate.nil? || sample?(sample_rate)
|
260
|
+
emit(datagram_builder(no_prefix: no_prefix).s(name, value, sample_rate, tags))
|
261
|
+
end
|
262
|
+
StatsD::Instrument::VOID
|
257
263
|
end
|
258
264
|
|
259
265
|
# Emits a distribution metric, which builds a histogram of the reported
|
@@ -274,9 +280,10 @@ module StatsD
|
|
274
280
|
end
|
275
281
|
|
276
282
|
sample_rate ||= @default_sample_rate
|
277
|
-
|
278
|
-
|
279
|
-
|
283
|
+
if sample_rate.nil? || sample?(sample_rate)
|
284
|
+
emit(datagram_builder(no_prefix: no_prefix).d(name, value, sample_rate, tags))
|
285
|
+
end
|
286
|
+
StatsD::Instrument::VOID
|
280
287
|
end
|
281
288
|
|
282
289
|
# Emits a histogram metric, which builds a histogram of the reported values.
|
@@ -292,9 +299,10 @@ module StatsD
|
|
292
299
|
# @return [void]
|
293
300
|
def histogram(name, value, sample_rate: nil, tags: nil, no_prefix: false)
|
294
301
|
sample_rate ||= @default_sample_rate
|
295
|
-
|
296
|
-
|
297
|
-
|
302
|
+
if sample_rate.nil? || sample?(sample_rate)
|
303
|
+
emit(datagram_builder(no_prefix: no_prefix).h(name, value, sample_rate, tags))
|
304
|
+
end
|
305
|
+
StatsD::Instrument::VOID
|
298
306
|
end
|
299
307
|
|
300
308
|
# @!endgroup
|
@@ -317,7 +325,7 @@ module StatsD
|
|
317
325
|
stop = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)
|
318
326
|
|
319
327
|
sample_rate ||= @default_sample_rate
|
320
|
-
if sample?(sample_rate)
|
328
|
+
if sample_rate.nil? || sample?(sample_rate)
|
321
329
|
metric_type ||= datagram_builder(no_prefix: no_prefix).latency_metric_type
|
322
330
|
latency_in_ms = stop - start
|
323
331
|
emit(datagram_builder(no_prefix: no_prefix).send(metric_type, name, latency_in_ms, sample_rate, tags))
|
@@ -20,8 +20,8 @@ module StatsD
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def initialize(prefix: nil, default_tags: nil)
|
23
|
-
@prefix = prefix.nil? ? "" : "#{
|
24
|
-
@default_tags =
|
23
|
+
@prefix = prefix.nil? ? "" : "#{prefix}.".tr(":|@", "_")
|
24
|
+
@default_tags = default_tags.nil? || default_tags.empty? ? nil : compile_tags(default_tags, "|#".b)
|
25
25
|
end
|
26
26
|
|
27
27
|
def c(name, value, sample_rate, tags)
|
@@ -58,26 +58,6 @@ module StatsD
|
|
58
58
|
|
59
59
|
protected
|
60
60
|
|
61
|
-
attr_reader :prefix, :default_tags
|
62
|
-
|
63
|
-
# Utility function to convert tags to the canonical form.
|
64
|
-
#
|
65
|
-
# - Tags specified as key value pairs will be converted into an array
|
66
|
-
# - Tags are normalized to remove unsupported characters
|
67
|
-
#
|
68
|
-
# @param tags [Array<String>, Hash<String, String>, nil] Tags specified in any form.
|
69
|
-
# @return [Array<String>, nil] the list of tags in canonical form.
|
70
|
-
def normalize_tags(tags)
|
71
|
-
return [] unless tags
|
72
|
-
|
73
|
-
tags = tags.map { |k, v| "#{k}:#{v}" } if tags.is_a?(Hash)
|
74
|
-
|
75
|
-
# Fast path when no string replacement is needed
|
76
|
-
return tags unless tags.any? { |tag| /[|,]/.match?(tag) }
|
77
|
-
|
78
|
-
tags.map { |tag| tag.tr("|,", "") }
|
79
|
-
end
|
80
|
-
|
81
61
|
# Utility function to remove invalid characters from a StatsD metric name
|
82
62
|
def normalize_name(name)
|
83
63
|
# Fast path when no normalization is needed to avoid copying the string
|
@@ -87,12 +67,49 @@ module StatsD
|
|
87
67
|
end
|
88
68
|
|
89
69
|
def generate_generic_datagram(name, value, type, sample_rate, tags)
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
70
|
+
datagram = "".b <<
|
71
|
+
@prefix <<
|
72
|
+
(/[:|@]/.match?(name) ? name.tr(":|@", "_") : name) <<
|
73
|
+
":" << value.to_s <<
|
74
|
+
"|" << type
|
75
|
+
|
76
|
+
datagram << "|@" << sample_rate.to_s if sample_rate && sample_rate < 1
|
77
|
+
|
78
|
+
unless @default_tags.nil?
|
79
|
+
datagram << @default_tags
|
80
|
+
end
|
81
|
+
|
82
|
+
unless tags.nil?
|
83
|
+
datagram << (@default_tags.nil? ? "|#" : ",")
|
84
|
+
compile_tags(tags, datagram)
|
85
|
+
end
|
86
|
+
|
94
87
|
datagram
|
95
88
|
end
|
89
|
+
|
90
|
+
def compile_tags(tags, buffer = "".b)
|
91
|
+
if tags.is_a?(Hash)
|
92
|
+
first = true
|
93
|
+
tags.each do |key, value|
|
94
|
+
if first
|
95
|
+
first = false
|
96
|
+
else
|
97
|
+
buffer << ","
|
98
|
+
end
|
99
|
+
key = key.to_s
|
100
|
+
key = key.tr("|,", "") if /[|,]/.match?(key)
|
101
|
+
value = value.to_s
|
102
|
+
value = value.tr("|,", "") if /[|,]/.match?(value)
|
103
|
+
buffer << key << ":" << value
|
104
|
+
end
|
105
|
+
else
|
106
|
+
if tags.any? { |tag| /[|,]/.match?(tag) }
|
107
|
+
tags = tags.map { |tag| tag.tr("|,", "") }
|
108
|
+
end
|
109
|
+
buffer << tags.join(",")
|
110
|
+
end
|
111
|
+
buffer
|
112
|
+
end
|
96
113
|
end
|
97
114
|
end
|
98
115
|
end
|
@@ -36,7 +36,6 @@ module StatsD
|
|
36
36
|
|
37
37
|
escaped_title = "#{@prefix}#{title}".gsub("\n", '\n')
|
38
38
|
escaped_text = text.gsub("\n", '\n')
|
39
|
-
tags = normalize_tags(tags) + default_tags
|
40
39
|
|
41
40
|
datagram = +"_e{#{escaped_title.length},#{escaped_text.length}}:#{escaped_title}|#{escaped_text}"
|
42
41
|
datagram << "|h:#{hostname}" if hostname
|
@@ -45,7 +44,16 @@ module StatsD
|
|
45
44
|
datagram << "|p:#{priority}" if priority
|
46
45
|
datagram << "|s:#{source_type_name}" if source_type_name
|
47
46
|
datagram << "|t:#{alert_type}" if alert_type
|
48
|
-
|
47
|
+
|
48
|
+
unless @default_tags.nil?
|
49
|
+
datagram << @default_tags
|
50
|
+
end
|
51
|
+
|
52
|
+
unless tags.nil?
|
53
|
+
datagram << (@default_tags.nil? ? "|#" : ",")
|
54
|
+
compile_tags(tags, datagram)
|
55
|
+
end
|
56
|
+
|
49
57
|
datagram
|
50
58
|
end
|
51
59
|
|
@@ -63,12 +71,20 @@ module StatsD
|
|
63
71
|
# @see https://docs.datadoghq.com/developers/dogstatsd/datagram_shell/#service-checks
|
64
72
|
def _sc(name, status, timestamp: nil, hostname: nil, tags: nil, message: nil)
|
65
73
|
status_number = status.is_a?(Integer) ? status : SERVICE_CHECK_STATUS_VALUES.fetch(status.to_sym)
|
66
|
-
tags = normalize_tags(tags) + default_tags
|
67
74
|
|
68
75
|
datagram = +"_sc|#{@prefix}#{normalize_name(name)}|#{status_number}"
|
69
76
|
datagram << "|h:#{hostname}" if hostname
|
70
77
|
datagram << "|d:#{timestamp.to_i}" if timestamp
|
71
|
-
|
78
|
+
|
79
|
+
unless @default_tags.nil?
|
80
|
+
datagram << @default_tags
|
81
|
+
end
|
82
|
+
|
83
|
+
unless tags.nil?
|
84
|
+
datagram << (@default_tags.nil? ? "|#" : ",")
|
85
|
+
compile_tags(tags, datagram)
|
86
|
+
end
|
87
|
+
|
72
88
|
datagram << "|m:#{normalize_name(message)}" if message
|
73
89
|
datagram
|
74
90
|
end
|
@@ -9,10 +9,8 @@ module StatsD
|
|
9
9
|
|
10
10
|
protected
|
11
11
|
|
12
|
-
def
|
13
|
-
raise NotImplementedError, "#{self.class.name} does not support tags"
|
14
|
-
|
15
|
-
super
|
12
|
+
def compile_tags(*)
|
13
|
+
raise NotImplementedError, "#{self.class.name} does not support tags"
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|
data/test/client_test.rb
CHANGED
@@ -206,7 +206,7 @@ class ClientTest < Minitest::Test
|
|
206
206
|
mock_sink.stubs(:sample?).returns(false, true, false, false, true)
|
207
207
|
mock_sink.expects(:<<).twice
|
208
208
|
|
209
|
-
client = StatsD::Instrument::Client.new(sink: mock_sink)
|
209
|
+
client = StatsD::Instrument::Client.new(sink: mock_sink, default_sample_rate: 0.5)
|
210
210
|
5.times { client.increment("metric") }
|
211
211
|
end
|
212
212
|
|
@@ -14,17 +14,17 @@ class DatagramBuilderTest < Minitest::Test
|
|
14
14
|
assert_equal("fo_o", @datagram_builder.send(:normalize_name, "fo:o"))
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
assert_equal(
|
17
|
+
def test_compile_unsupported_tag_names
|
18
|
+
assert_equal("ign#ored", @datagram_builder.send(:compile_tags, ["ign#o|re,d"]))
|
19
19
|
# NOTE: how this is interpreted by the backend is undefined.
|
20
20
|
# We rely on the user to not do stuff like this if they don't want to be surprised.
|
21
21
|
# We do not want to take the performance hit of normalizing this.
|
22
|
-
assert_equal(
|
22
|
+
assert_equal("lol::class:omg::lol", @datagram_builder.send(:compile_tags, { "lol::class" => "omg::lol" }))
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
26
|
-
assert_equal(
|
27
|
-
assert_equal(
|
25
|
+
def test_compile_tags_converts_hash_to_array
|
26
|
+
assert_equal("tag:value", @datagram_builder.send(:compile_tags, { tag: "value" }))
|
27
|
+
assert_equal("tag1:v1,tag2:v2", @datagram_builder.send(:compile_tags, { tag1: "v1", tag2: "v2" }))
|
28
28
|
end
|
29
29
|
|
30
30
|
def test_c
|
@@ -103,7 +103,7 @@ class DatagramBuilderTest < Minitest::Test
|
|
103
103
|
assert_equal("bar:1|c|#foo", datagram)
|
104
104
|
|
105
105
|
datagram = datagram_builder.c("bar", 1, nil, a: "b")
|
106
|
-
assert_equal("bar:1|c|#a:b
|
106
|
+
assert_equal("bar:1|c|#foo,a:b", datagram)
|
107
107
|
|
108
108
|
# We do not filter out duplicates, because detecting dupes is too time consuming.
|
109
109
|
# We let the server deal with the situation
|
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.
|
4
|
+
version: 3.6.0
|
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-
|
13
|
+
date: 2023-11-03 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.4.
|
125
|
+
rubygems_version: 3.4.21
|
126
126
|
signing_key:
|
127
127
|
specification_version: 4
|
128
128
|
summary: A StatsD client for Ruby apps
|