statsd-instrument 2.3.2 → 2.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/.github/CODEOWNERS +1 -0
- data/.github/workflows/benchmark.yml +32 -0
- data/.github/workflows/ci.yml +47 -0
- data/.gitignore +1 -0
- data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +1027 -0
- data/.rubocop.yml +50 -0
- data/.yardopts +5 -0
- data/CHANGELOG.md +288 -2
- data/CONTRIBUTING.md +28 -6
- data/Gemfile +5 -0
- data/README.md +54 -46
- data/Rakefile +4 -2
- data/benchmark/README.md +29 -0
- data/benchmark/datagram-client +41 -0
- data/benchmark/send-metrics-to-dev-null-log +47 -0
- data/benchmark/send-metrics-to-local-udp-receiver +57 -0
- data/lib/statsd/instrument/assertions.rb +179 -30
- data/lib/statsd/instrument/backend.rb +3 -2
- data/lib/statsd/instrument/backends/capture_backend.rb +4 -1
- data/lib/statsd/instrument/backends/logger_backend.rb +3 -3
- data/lib/statsd/instrument/backends/null_backend.rb +2 -0
- data/lib/statsd/instrument/backends/udp_backend.rb +39 -45
- 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 +108 -29
- data/lib/statsd/instrument/helpers.rb +16 -8
- data/lib/statsd/instrument/log_sink.rb +24 -0
- data/lib/statsd/instrument/matchers.rb +14 -11
- data/lib/statsd/instrument/metric.rb +72 -45
- data/lib/statsd/instrument/metric_expectation.rb +32 -18
- data/lib/statsd/instrument/null_sink.rb +13 -0
- data/lib/statsd/instrument/railtie.rb +2 -1
- data/lib/statsd/instrument/rubocop/measure_as_dist_argument.rb +39 -0
- data/lib/statsd/instrument/rubocop/metaprogramming_positional_arguments.rb +42 -0
- data/lib/statsd/instrument/rubocop/metric_prefix_argument.rb +37 -0
- data/lib/statsd/instrument/rubocop/metric_return_value.rb +32 -0
- data/lib/statsd/instrument/rubocop/metric_value_keyword_argument.rb +36 -0
- data/lib/statsd/instrument/rubocop/positional_arguments.rb +99 -0
- data/lib/statsd/instrument/rubocop/splat_arguments.rb +31 -0
- data/lib/statsd/instrument/rubocop.rb +64 -0
- data/lib/statsd/instrument/statsd_datagram_builder.rb +14 -0
- data/lib/statsd/instrument/strict.rb +235 -0
- data/lib/statsd/instrument/udp_sink.rb +62 -0
- data/lib/statsd/instrument/version.rb +3 -1
- data/lib/statsd/instrument.rb +340 -163
- data/lib/statsd-instrument.rb +2 -0
- data/statsd-instrument.gemspec +13 -10
- data/test/assertions_test.rb +167 -156
- data/test/benchmark/clock_gettime.rb +27 -0
- data/test/benchmark/default_tags.rb +47 -0
- data/test/benchmark/metrics.rb +9 -8
- data/test/benchmark/tags.rb +5 -3
- data/test/capture_backend_test.rb +4 -2
- 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 +132 -0
- data/test/dogstatsd_datagram_builder_test.rb +32 -0
- data/test/environment_test.rb +75 -8
- data/test/helpers/rubocop_helper.rb +47 -0
- data/test/helpers_test.rb +2 -1
- data/test/integration_test.rb +31 -7
- data/test/log_sink_test.rb +37 -0
- data/test/logger_backend_test.rb +10 -8
- data/test/matchers_test.rb +42 -28
- data/test/metric_test.rb +18 -22
- 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 +58 -0
- data/test/rubocop/metric_prefix_argument_test.rb +38 -0
- data/test/rubocop/metric_return_value_test.rb +78 -0
- data/test/rubocop/metric_value_keyword_argument_test.rb +39 -0
- data/test/rubocop/positional_arguments_test.rb +110 -0
- data/test/rubocop/splat_arguments_test.rb +27 -0
- data/test/statsd_datagram_builder_test.rb +22 -0
- data/test/statsd_instrumentation_test.rb +109 -100
- data/test/statsd_test.rb +113 -79
- data/test/test_helper.rb +12 -1
- data/test/udp_backend_test.rb +38 -36
- data/test/udp_sink_test.rb +85 -0
- metadata +85 -5
- data/.travis.yml +0 -12
data/lib/statsd/instrument.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'socket'
|
2
4
|
require 'logger'
|
3
5
|
|
@@ -27,10 +29,13 @@ require 'logger'
|
|
27
29
|
# @!attribute logger
|
28
30
|
# The logger to use in case of any errors. The logger is also used as default logger
|
29
31
|
# for the LoggerBackend (although this can be overwritten).
|
30
|
-
#
|
31
32
|
# @see StatsD::Instrument::Backends::LoggerBackend
|
32
33
|
# @return [Logger]
|
33
34
|
#
|
35
|
+
# @!attribute default_tags
|
36
|
+
# The tags to apply to all metrics.
|
37
|
+
# @return [Array<String>, Hash<String, String>, nil] The default tags, or <tt>nil</tt> when no default tags is used
|
38
|
+
#
|
34
39
|
# @see StatsD::Instrument <tt>StatsD::Instrument</tt> contains module to instrument
|
35
40
|
# existing methods with StatsD metrics.
|
36
41
|
module StatsD
|
@@ -56,20 +61,26 @@ module StatsD
|
|
56
61
|
metric_name.respond_to?(:call) ? metric_name.call(callee, args).gsub('::', '.') : metric_name.gsub('::', '.')
|
57
62
|
end
|
58
63
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
64
|
+
# Even though this method is considered private, and is no longer used internally,
|
65
|
+
# applications in the wild rely on it. As a result, we cannot remove this method
|
66
|
+
# until the next major version.
|
67
|
+
#
|
68
|
+
# @deprecated Use Process.clock_gettime(Process::CLOCK_MONOTONIC) instead.
|
69
|
+
def self.current_timestamp
|
70
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Even though this method is considered private, and is no longer used internally,
|
74
|
+
# applications in the wild rely on it. As a result, we cannot remove this method
|
75
|
+
# until the next major version.
|
76
|
+
#
|
77
|
+
# @deprecated You can implement similar functionality yourself using
|
78
|
+
# `Process.clock_gettime(Process::CLOCK_MONOTONIC)`. Think about what will
|
79
|
+
# happen if an exception happens during the block execution though.
|
80
|
+
def self.duration
|
81
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
82
|
+
yield
|
83
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
|
73
84
|
end
|
74
85
|
|
75
86
|
# Adds execution duration instrumentation to a method as a timing.
|
@@ -79,10 +90,18 @@ module StatsD
|
|
79
90
|
# callable to dynamically generate a metric name
|
80
91
|
# @param metric_options (see StatsD#measure)
|
81
92
|
# @return [void]
|
82
|
-
def statsd_measure(method, name,
|
93
|
+
def statsd_measure(method, name, deprecated_sample_rate_arg = nil, deprecated_tags_arg = nil, as_dist: false,
|
94
|
+
sample_rate: deprecated_sample_rate_arg, tags: deprecated_tags_arg, prefix: nil, no_prefix: false)
|
95
|
+
|
83
96
|
add_to_method(method, name, :measure) do
|
84
97
|
define_method(method) do |*args, &block|
|
85
|
-
StatsD
|
98
|
+
key = StatsD::Instrument.generate_metric_name(name, self, *args)
|
99
|
+
prefix ||= StatsD.prefix
|
100
|
+
StatsD.measure( # rubocop:disable StatsD/MeasureAsDistArgument, StatsD/MetricPrefixArgument
|
101
|
+
key, sample_rate: sample_rate, tags: tags, prefix: prefix, no_prefix: no_prefix, as_dist: as_dist
|
102
|
+
) do
|
103
|
+
super(*args, &block)
|
104
|
+
end
|
86
105
|
end
|
87
106
|
end
|
88
107
|
end
|
@@ -95,10 +114,18 @@ module StatsD
|
|
95
114
|
# @param metric_options (see StatsD#measure)
|
96
115
|
# @return [void]
|
97
116
|
# @note Supported by the datadog implementation only (in beta)
|
98
|
-
def statsd_distribution(method, name,
|
117
|
+
def statsd_distribution(method, name, deprecated_sample_rate_arg = nil, deprecated_tags_arg = nil,
|
118
|
+
sample_rate: deprecated_sample_rate_arg, tags: deprecated_tags_arg, prefix: nil, no_prefix: false)
|
119
|
+
|
99
120
|
add_to_method(method, name, :distribution) do
|
100
121
|
define_method(method) do |*args, &block|
|
101
|
-
StatsD
|
122
|
+
key = StatsD::Instrument.generate_metric_name(name, self, *args)
|
123
|
+
prefix ||= StatsD.prefix
|
124
|
+
StatsD.distribution( # rubocop:disable StatsD/MetricPrefixArgument
|
125
|
+
key, sample_rate: sample_rate, tags: tags, prefix: prefix, no_prefix: no_prefix
|
126
|
+
) do
|
127
|
+
super(*args, &block)
|
128
|
+
end
|
102
129
|
end
|
103
130
|
end
|
104
131
|
end
|
@@ -118,7 +145,9 @@ module StatsD
|
|
118
145
|
# @yieldreturn [Boolean] Return true iff the return value is consisered a success, false otherwise.
|
119
146
|
# @return [void]
|
120
147
|
# @see #statsd_count_if
|
121
|
-
def statsd_count_success(method, name,
|
148
|
+
def statsd_count_success(method, name, deprecated_sample_rate_arg = nil, deprecated_tags_arg = nil,
|
149
|
+
sample_rate: deprecated_sample_rate_arg, tags: deprecated_tags_arg, prefix: nil, no_prefix: false)
|
150
|
+
|
122
151
|
add_to_method(method, name, :count_success) do
|
123
152
|
define_method(method) do |*args, &block|
|
124
153
|
begin
|
@@ -127,30 +156,40 @@ module StatsD
|
|
127
156
|
truthiness = false
|
128
157
|
raise
|
129
158
|
else
|
130
|
-
|
159
|
+
if block_given?
|
160
|
+
begin
|
161
|
+
truthiness = yield(result)
|
162
|
+
rescue
|
163
|
+
truthiness = false
|
164
|
+
end
|
165
|
+
end
|
131
166
|
result
|
132
167
|
ensure
|
133
168
|
suffix = truthiness == false ? 'failure' : 'success'
|
134
|
-
|
169
|
+
key = "#{StatsD::Instrument.generate_metric_name(name, self, *args)}.#{suffix}"
|
170
|
+
prefix ||= StatsD.prefix
|
171
|
+
StatsD.increment(key, prefix: prefix, # rubocop:disable StatsD/MetricPrefixArgument
|
172
|
+
sample_rate: sample_rate, tags: tags, no_prefix: no_prefix)
|
135
173
|
end
|
136
174
|
end
|
137
175
|
end
|
138
176
|
end
|
139
177
|
|
140
|
-
# Adds success
|
178
|
+
# Adds success counter instrumentation to a method.
|
141
179
|
#
|
142
180
|
# A method call will be considered successful if it does not raise an exception, and the result is true-y.
|
143
|
-
# Only for successful calls, the metric will be
|
181
|
+
# Only for successful calls, the metric will be incremented.
|
144
182
|
#
|
145
183
|
# @param method (see #statsd_measure)
|
146
184
|
# @param name (see #statsd_measure)
|
147
|
-
# @param metric_options (see #statsd_measure)
|
148
185
|
# @yield (see #statsd_count_success)
|
149
186
|
# @yieldparam result (see #statsd_count_success)
|
150
187
|
# @yieldreturn (see #statsd_count_success)
|
151
188
|
# @return [void]
|
152
189
|
# @see #statsd_count_success
|
153
|
-
def statsd_count_if(method, name,
|
190
|
+
def statsd_count_if(method, name, deprecated_sample_rate_arg = nil, deprecated_tags_arg = nil,
|
191
|
+
sample_rate: deprecated_sample_rate_arg, tags: deprecated_tags_arg, prefix: nil, no_prefix: false)
|
192
|
+
|
154
193
|
add_to_method(method, name, :count_if) do
|
155
194
|
define_method(method) do |*args, &block|
|
156
195
|
begin
|
@@ -159,10 +198,21 @@ module StatsD
|
|
159
198
|
truthiness = false
|
160
199
|
raise
|
161
200
|
else
|
162
|
-
|
201
|
+
if block_given?
|
202
|
+
begin
|
203
|
+
truthiness = yield(result)
|
204
|
+
rescue
|
205
|
+
truthiness = false
|
206
|
+
end
|
207
|
+
end
|
163
208
|
result
|
164
209
|
ensure
|
165
|
-
|
210
|
+
if truthiness
|
211
|
+
key = StatsD::Instrument.generate_metric_name(name, self, *args)
|
212
|
+
prefix ||= StatsD.prefix
|
213
|
+
StatsD.increment(key, prefix: prefix, # rubocop:disable StatsD/MetricPrefixArgument
|
214
|
+
sample_rate: sample_rate, tags: tags, no_prefix: no_prefix)
|
215
|
+
end
|
166
216
|
end
|
167
217
|
end
|
168
218
|
end
|
@@ -177,10 +227,15 @@ module StatsD
|
|
177
227
|
# @param name (see #statsd_measure)
|
178
228
|
# @param metric_options (see #statsd_measure)
|
179
229
|
# @return [void]
|
180
|
-
def statsd_count(method, name,
|
230
|
+
def statsd_count(method, name, deprecated_sample_rate_arg = nil, deprecated_tags_arg = nil,
|
231
|
+
sample_rate: deprecated_sample_rate_arg, tags: deprecated_tags_arg, prefix: nil, no_prefix: false)
|
232
|
+
|
181
233
|
add_to_method(method, name, :count) do
|
182
234
|
define_method(method) do |*args, &block|
|
183
|
-
StatsD
|
235
|
+
key = StatsD::Instrument.generate_metric_name(name, self, *args)
|
236
|
+
prefix ||= StatsD.prefix
|
237
|
+
StatsD.increment(key, prefix: prefix, # rubocop:disable StatsD/MetricPrefixArgument
|
238
|
+
sample_rate: sample_rate, tags: tags, no_prefix: no_prefix)
|
184
239
|
super(*args, &block)
|
185
240
|
end
|
186
241
|
end
|
@@ -248,8 +303,13 @@ module StatsD
|
|
248
303
|
def add_to_method(method, name, action, &block)
|
249
304
|
instrumentation_module = statsd_instrumentation_for(method, name, action)
|
250
305
|
|
251
|
-
|
252
|
-
|
306
|
+
if instrumentation_module.method_defined?(method)
|
307
|
+
raise ArgumentError, "Already instrumented #{method} for #{self.name}"
|
308
|
+
end
|
309
|
+
|
310
|
+
unless method_defined?(method) || private_method_defined?(method)
|
311
|
+
raise ArgumentError, "could not find method #{method} for #{self.name}"
|
312
|
+
end
|
253
313
|
|
254
314
|
method_scope = method_visibility(method)
|
255
315
|
|
@@ -263,10 +323,9 @@ module StatsD
|
|
263
323
|
end
|
264
324
|
|
265
325
|
def method_visibility(method)
|
266
|
-
|
267
|
-
when private_method_defined?(method)
|
326
|
+
if private_method_defined?(method)
|
268
327
|
:private
|
269
|
-
|
328
|
+
elsif protected_method_defined?(method)
|
270
329
|
:protected
|
271
330
|
else
|
272
331
|
:public
|
@@ -275,49 +334,75 @@ module StatsD
|
|
275
334
|
end
|
276
335
|
|
277
336
|
attr_accessor :logger, :default_sample_rate, :prefix
|
278
|
-
attr_writer :backend
|
337
|
+
attr_writer :backend, :client
|
338
|
+
attr_reader :default_tags
|
339
|
+
|
340
|
+
def default_tags=(tags)
|
341
|
+
@default_tags = StatsD::Instrument::Metric.normalize_tags(tags)
|
342
|
+
end
|
279
343
|
|
280
344
|
def backend
|
281
345
|
@backend ||= StatsD::Instrument::Environment.default_backend
|
282
346
|
end
|
283
347
|
|
284
|
-
|
348
|
+
def client
|
349
|
+
@client ||= begin
|
350
|
+
require 'statsd/instrument/client'
|
351
|
+
StatsD::Instrument::Environment.from_env.default_client
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
# @!method measure(name, value = nil, sample_rate: nil, tags: nil, &block)
|
356
|
+
#
|
357
|
+
# Emits a timing metric
|
358
|
+
#
|
359
|
+
# @param [String] key The name of the metric.
|
360
|
+
# @param sample_rate (see #increment)
|
361
|
+
# @param tags (see #increment)
|
285
362
|
#
|
286
|
-
# @
|
287
|
-
#
|
288
|
-
#
|
289
|
-
#
|
290
|
-
#
|
291
|
-
# the key :as_dist will submit the value as a distribution instead of a timing
|
292
|
-
# (only supported by DataDog's implementation)
|
293
|
-
# @return [StatsD::Instrument::Metric] The metric that was sent to the backend.
|
363
|
+
# @example Providing a value directly
|
364
|
+
# start = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
|
365
|
+
# do_something
|
366
|
+
# stop = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
|
367
|
+
# http_response = StatsD.measure('HTTP.call.duration', stop - start)
|
294
368
|
#
|
295
|
-
# @
|
296
|
-
#
|
369
|
+
# @example Providing a block to measure the duration of its execution
|
370
|
+
# http_response = StatsD.measure('HTTP.call.duration') do
|
371
|
+
# Net::HTTP.get(url)
|
372
|
+
# end
|
373
|
+
#
|
374
|
+
# @overload measure(key, value, sample_rate: nil, tags: nil)
|
375
|
+
# Emits a timing metric, by providing a duration in milliseconds.
|
376
|
+
#
|
377
|
+
# @param [Float] value The measured duration in milliseconds
|
378
|
+
# @return [void]
|
379
|
+
#
|
380
|
+
# @overload measure(key, sample_rate: nil, tags: nil, &block)
|
381
|
+
# Emits a timing metric, after measuring the execution duration of the
|
297
382
|
# block passed to this method.
|
298
|
-
#
|
299
|
-
# @
|
300
|
-
#
|
301
|
-
#
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
result = metric unless block_given?
|
317
|
-
result
|
383
|
+
#
|
384
|
+
# @yield `StatsD.measure` will yield the block and measure the duration. After the block
|
385
|
+
# returns, the duration in millisecond will be emitted as metric.
|
386
|
+
# @return The value that was returned by the block passed through.
|
387
|
+
def measure(
|
388
|
+
key, value_arg = nil, deprecated_sample_rate_arg = nil, deprecated_tags_arg = nil,
|
389
|
+
value: value_arg, sample_rate: deprecated_sample_rate_arg, tags: deprecated_tags_arg,
|
390
|
+
prefix: StatsD.prefix, no_prefix: false, as_dist: false,
|
391
|
+
&block
|
392
|
+
)
|
393
|
+
# TODO: in the next version, hardcode this to :ms when the as_dist argument is dropped.
|
394
|
+
type = as_dist ? :d : :ms
|
395
|
+
prefix = nil if no_prefix
|
396
|
+
if block_given?
|
397
|
+
measure_latency(type, key, sample_rate: sample_rate, tags: tags, prefix: prefix, &block)
|
398
|
+
else
|
399
|
+
collect_metric(type, key, value, sample_rate: sample_rate, tags: tags, prefix: prefix)
|
400
|
+
end
|
318
401
|
end
|
319
402
|
|
403
|
+
# @!method increment(name, value = 1, sample_rate: nil, tags: nil)
|
320
404
|
# Emits a counter metric.
|
405
|
+
#
|
321
406
|
# @param key [String] The name of the metric.
|
322
407
|
# @param value [Integer] The value to increment the counter by.
|
323
408
|
#
|
@@ -326,135 +411,226 @@ module StatsD
|
|
326
411
|
# The sample rate is part of the packet that is being sent to the server, and the server
|
327
412
|
# should know how to handle it.
|
328
413
|
#
|
329
|
-
# @param
|
330
|
-
#
|
331
|
-
|
332
|
-
|
414
|
+
# @param sample_rate [Float] (default: `StatsD.default_sample_rate`) The rate at which to sample
|
415
|
+
# this metric call. This value should be between 0 and 1. This value can be used to reduce
|
416
|
+
# the amount of network I/O (and CPU cycles) used for very frequent metrics.
|
417
|
+
#
|
418
|
+
# - A value of `0.1` means that only 1 out of 10 calls will be emitted; the other 9 will
|
419
|
+
# be short-circuited.
|
420
|
+
# - When set to `1`, every metric will be emitted.
|
421
|
+
# - If this parameter is not set, the default sample rate for this client will be used.
|
422
|
+
# @param tags [Array<String>, Hash<Symbol, String>] The tags to associate with this measurement.
|
423
|
+
# They can be provided as an array of strings, or a hash of key/value pairs.
|
424
|
+
# _Note:_ Tags are not supported by all implementations.
|
425
|
+
# @return [void]
|
426
|
+
def increment(
|
427
|
+
key, value_arg = 1, deprecated_sample_rate_arg = nil, deprecated_tags_arg = nil,
|
428
|
+
value: value_arg, sample_rate: deprecated_sample_rate_arg, tags: deprecated_tags_arg,
|
429
|
+
prefix: StatsD.prefix, no_prefix: false
|
430
|
+
)
|
431
|
+
prefix = nil if no_prefix
|
432
|
+
collect_metric(:c, key, value, sample_rate: sample_rate, tags: tags, prefix: prefix)
|
333
433
|
end
|
334
434
|
|
435
|
+
# @!method gauge(name, value, sample_rate: nil, tags: nil)
|
436
|
+
#
|
335
437
|
# Emits a gauge metric.
|
336
|
-
#
|
438
|
+
#
|
439
|
+
# @param key The name of the metric.
|
337
440
|
# @param value [Numeric] The current value to record.
|
338
|
-
# @param
|
339
|
-
# @
|
340
|
-
|
341
|
-
|
441
|
+
# @param sample_rate (see #increment)
|
442
|
+
# @param tags (see #increment)
|
443
|
+
# @return [void]
|
444
|
+
def gauge(
|
445
|
+
key, value_arg = nil, deprecated_sample_rate_arg = nil, deprecated_tags_arg = nil,
|
446
|
+
value: value_arg, sample_rate: deprecated_sample_rate_arg, tags: deprecated_tags_arg,
|
447
|
+
prefix: StatsD.prefix, no_prefix: false
|
448
|
+
)
|
449
|
+
prefix = nil if no_prefix
|
450
|
+
collect_metric(:g, key, value, sample_rate: sample_rate, tags: tags, prefix: prefix)
|
342
451
|
end
|
343
452
|
|
344
|
-
#
|
453
|
+
# @!method set(name, value, sample_rate: nil, tags: nil)
|
454
|
+
#
|
455
|
+
# Emits a set metric, which counts the number of distinct values that have occurred.
|
456
|
+
#
|
457
|
+
# @example Couning the number of unique visitors
|
458
|
+
# StatsD.set('visitors.unique', Current.user.id)
|
459
|
+
#
|
345
460
|
# @param key [String] The name of the metric.
|
346
461
|
# @param value [Numeric] The value to record.
|
347
|
-
# @param
|
462
|
+
# @param sample_rate (see #increment)
|
463
|
+
# @param tags (see #increment)
|
464
|
+
# @return [void]
|
465
|
+
def set(
|
466
|
+
key, value_arg = nil, deprecated_sample_rate_arg = nil, deprecated_tags_arg = nil,
|
467
|
+
value: value_arg, sample_rate: deprecated_sample_rate_arg, tags: deprecated_tags_arg,
|
468
|
+
prefix: StatsD.prefix, no_prefix: false
|
469
|
+
)
|
470
|
+
prefix = nil if no_prefix
|
471
|
+
collect_metric(:s, key, value, sample_rate: sample_rate, tags: tags, prefix: prefix)
|
472
|
+
end
|
473
|
+
|
474
|
+
# @!method histogram(name, value, sample_rate: nil, tags: nil)
|
475
|
+
#
|
476
|
+
# Emits a histogram metric.
|
477
|
+
#
|
478
|
+
# @param key The name of the metric.
|
479
|
+
# @param value [Numeric] The value to record.
|
480
|
+
# @param sample_rate (see #increment)
|
481
|
+
# @param tags (see #increment)
|
348
482
|
# @return (see #collect_metric)
|
349
483
|
# @note Supported by the datadog implementation only.
|
350
|
-
def histogram(
|
351
|
-
|
484
|
+
def histogram(
|
485
|
+
key, value_arg = nil, deprecated_sample_rate_arg = nil, deprecated_tags_arg = nil,
|
486
|
+
value: value_arg, sample_rate: deprecated_sample_rate_arg, tags: deprecated_tags_arg,
|
487
|
+
prefix: StatsD.prefix, no_prefix: false
|
488
|
+
)
|
489
|
+
prefix = nil if no_prefix
|
490
|
+
collect_metric(:h, key, value, sample_rate: sample_rate, tags: tags, prefix: prefix)
|
352
491
|
end
|
353
492
|
|
493
|
+
# @!method distribution(name, value = nil, sample_rate: nil, tags: nil, &block)
|
494
|
+
#
|
354
495
|
# Emits a distribution metric.
|
355
|
-
#
|
356
|
-
# @param
|
357
|
-
# @param
|
358
|
-
# @
|
359
|
-
#
|
496
|
+
#
|
497
|
+
# @param [String] key The name of the metric.
|
498
|
+
# @param sample_rate (see #increment)
|
499
|
+
# @param tags (see #increment)
|
500
|
+
#
|
501
|
+
# @note Supported by the datadog implementation only.
|
502
|
+
# @example
|
503
|
+
# http_response = StatsD.distribution('HTTP.call.duration') do
|
504
|
+
# Net::HTTP.get(url)
|
505
|
+
# end
|
506
|
+
#
|
507
|
+
# @overload distribution(name, value, sample_rate: nil, tags: nil)
|
508
|
+
#
|
509
|
+
# Emits a distribution metric, given a provided value to record.
|
510
|
+
#
|
511
|
+
# @param [Numeric] value The value to record.
|
512
|
+
# @return [void]
|
360
513
|
#
|
361
514
|
# @overload distribution(key, metric_options = {}, &block)
|
362
|
-
#
|
363
|
-
#
|
364
|
-
#
|
365
|
-
# @
|
366
|
-
#
|
367
|
-
# @return The value that was
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
result
|
515
|
+
#
|
516
|
+
# Emits a distribution metric for the duration of the provided block, in milliseconds.
|
517
|
+
#
|
518
|
+
# @yield `StatsD.distribution` will yield the block and measure the duration. After
|
519
|
+
# the block returns, the duration in millisecond will be emitted as metric.
|
520
|
+
# @return The value that was returned by the block passed through.
|
521
|
+
def distribution(
|
522
|
+
key, value_arg = nil, deprecated_sample_rate_arg = nil, deprecated_tags_arg = nil,
|
523
|
+
value: value_arg, sample_rate: deprecated_sample_rate_arg, tags: deprecated_tags_arg,
|
524
|
+
prefix: StatsD.prefix, no_prefix: false,
|
525
|
+
&block
|
526
|
+
)
|
527
|
+
prefix = nil if no_prefix
|
528
|
+
if block_given?
|
529
|
+
measure_latency(:d, key, sample_rate: sample_rate, tags: tags, prefix: prefix, &block)
|
530
|
+
else
|
531
|
+
collect_metric(:d, key, value, sample_rate: sample_rate, tags: tags, prefix: prefix)
|
532
|
+
end
|
381
533
|
end
|
382
534
|
|
535
|
+
# @!method key_value(name, value)
|
536
|
+
#
|
383
537
|
# Emits a key/value metric.
|
538
|
+
#
|
384
539
|
# @param key [String] The name of the metric.
|
385
540
|
# @param value [Numeric] The value to record.
|
386
|
-
# @
|
387
|
-
#
|
541
|
+
# @return [void]
|
542
|
+
#
|
388
543
|
# @note Supported by the statsite implementation only.
|
389
|
-
def key_value(
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
# @param value [Numeric] The value to record.
|
396
|
-
# @param metric_options [Hash] (default: {}) Metric options
|
397
|
-
# @return (see #collect_metric)
|
398
|
-
# @note Supported by the datadog implementation only.
|
399
|
-
def set(key, value, *metric_options)
|
400
|
-
collect_metric(:s, key, value, metric_options)
|
544
|
+
def key_value(
|
545
|
+
key, value_arg = nil, deprecated_sample_rate_arg = nil,
|
546
|
+
value: value_arg, sample_rate: deprecated_sample_rate_arg, no_prefix: false
|
547
|
+
)
|
548
|
+
prefix = nil if no_prefix
|
549
|
+
collect_metric(:kv, key, value, sample_rate: sample_rate, prefix: prefix)
|
401
550
|
end
|
402
551
|
|
403
|
-
#
|
404
|
-
#
|
405
|
-
#
|
406
|
-
#
|
407
|
-
# @
|
408
|
-
# @
|
409
|
-
|
410
|
-
|
552
|
+
# @!method event(title, text, tags: nil, hostname: nil, timestamp: nil, aggregation_key: nil, priority: nil, source_type_name: nil, alert_type: nil) # rubocop:disable Metrics/LineLength
|
553
|
+
#
|
554
|
+
# Emits an event.
|
555
|
+
#
|
556
|
+
# @param title [String] Title of the event. A configured prefix may be applied to this title.
|
557
|
+
# @param text [String] Body of the event. Can contain newlines.
|
558
|
+
# @param [String] hostname The hostname to associate with the event.
|
559
|
+
# @param [Time] timestamp The moment the status of the service was checkes. Defaults to now.
|
560
|
+
# @param [String] aggregation_key A key to aggregate similar events into groups.
|
561
|
+
# @param [String] priority The event's priority, either `"low"` or `"normal"` (default).
|
562
|
+
# @param [String] source_type_name The source type.
|
563
|
+
# @param [String] alert_type The type of alert. Either `"info"` (default), `"warning"`, `"error"`, or `"success"`.
|
564
|
+
# @param tags (see #increment)
|
565
|
+
# @return [void]
|
566
|
+
#
|
567
|
+
# @note Supported by the Datadog implementation only.
|
568
|
+
def event(
|
569
|
+
title, text,
|
570
|
+
deprecated_sample_rate_arg = nil, deprecated_tags_arg = nil,
|
571
|
+
sample_rate: deprecated_sample_rate_arg, tags: deprecated_tags_arg,
|
572
|
+
prefix: StatsD.prefix, no_prefix: false,
|
573
|
+
hostname: nil, date_happened: nil, timestamp: date_happened,
|
574
|
+
aggregation_key: nil, priority: nil, source_type_name: nil, alert_type: nil,
|
575
|
+
**_ignored
|
576
|
+
)
|
577
|
+
prefix = nil if no_prefix
|
578
|
+
collect_metric(:_e, title, text, sample_rate: sample_rate, tags: tags, prefix: prefix, metadata: {
|
579
|
+
hostname: hostname, timestamp: timestamp, aggregation_key: aggregation_key,
|
580
|
+
priority: priority, source_type_name: source_type_name, alert_type: alert_type
|
581
|
+
})
|
411
582
|
end
|
412
583
|
|
413
|
-
#
|
414
|
-
#
|
415
|
-
#
|
416
|
-
#
|
417
|
-
# @
|
418
|
-
# @
|
419
|
-
|
420
|
-
|
584
|
+
# @!method service_check(name, status, tags: nil, hostname: nil, timestamp: nil, message: nil)
|
585
|
+
#
|
586
|
+
# Emits a service check.
|
587
|
+
#
|
588
|
+
# @param [String] name Name of the service. A configured prefix may be applied to this title.
|
589
|
+
# @param [Symbol] status Current status of the service. Either `:ok`, `:warning`, `:critical`, or `:unknown`.
|
590
|
+
# @param [String] hostname The hostname to associate with the event.
|
591
|
+
# @param [Time] timestamp The moment the status of the service was checkes. Defaults to now.
|
592
|
+
# @param [String] message A message that describes the current status.
|
593
|
+
# @param tags (see #increment)
|
594
|
+
# @return [void]
|
595
|
+
#
|
596
|
+
# @note Supported by the Datadog implementation only.
|
597
|
+
def service_check(
|
598
|
+
name, status,
|
599
|
+
deprecated_sample_rate_arg = nil, deprecated_tags_arg = nil,
|
600
|
+
sample_rate: deprecated_sample_rate_arg, tags: deprecated_tags_arg,
|
601
|
+
prefix: StatsD.prefix, no_prefix: false,
|
602
|
+
hostname: nil, timestamp: nil, message: nil, **_ignored
|
603
|
+
)
|
604
|
+
prefix = nil if no_prefix
|
605
|
+
collect_metric(:_sc, name, status, sample_rate: sample_rate, prefix: prefix, tags: tags, metadata: {
|
606
|
+
hostname: hostname, timestamp: timestamp, message: message
|
607
|
+
})
|
421
608
|
end
|
422
609
|
|
423
610
|
private
|
424
611
|
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
hash = {}
|
434
|
-
args.each_with_index do |value, index|
|
435
|
-
hash[order[index]] = value
|
612
|
+
def measure_latency(type, key, sample_rate:, tags:, prefix:)
|
613
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
614
|
+
begin
|
615
|
+
yield
|
616
|
+
ensure
|
617
|
+
# Ensure catches both a raised exception and a return in the invoked block
|
618
|
+
value = 1000.0 * (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start)
|
619
|
+
collect_metric(type, key, value, sample_rate: sample_rate, tags: tags, prefix: prefix)
|
436
620
|
end
|
437
|
-
|
438
|
-
return hash
|
439
|
-
end
|
440
|
-
|
441
|
-
def parse_options(value, metric_options)
|
442
|
-
if value.is_a?(Hash) && metric_options.empty?
|
443
|
-
metric_options = [value]
|
444
|
-
value = value.fetch(:value, nil)
|
445
|
-
end
|
446
|
-
[value, metric_options]
|
447
621
|
end
|
448
622
|
|
449
623
|
# Instantiates a metric, and sends it to the backend for further processing.
|
450
624
|
# @param options (see StatsD::Instrument::Metric#initialize)
|
451
|
-
# @return [
|
452
|
-
def collect_metric(type, name, value,
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
625
|
+
# @return [void]
|
626
|
+
def collect_metric(type, name, value, sample_rate:, tags: nil, prefix:, metadata: nil)
|
627
|
+
sample_rate ||= default_sample_rate
|
628
|
+
name = "#{prefix}.#{name}" if prefix
|
629
|
+
|
630
|
+
metric = StatsD::Instrument::Metric.new(type: type, name: name, value: value,
|
631
|
+
sample_rate: sample_rate, tags: tags, metadata: metadata)
|
632
|
+
backend.collect_metric(metric)
|
633
|
+
metric # TODO: return `nil` in the next major version
|
458
634
|
end
|
459
635
|
end
|
460
636
|
|
@@ -466,4 +642,5 @@ require 'statsd/instrument/helpers'
|
|
466
642
|
require 'statsd/instrument/assertions'
|
467
643
|
require 'statsd/instrument/metric_expectation'
|
468
644
|
require 'statsd/instrument/matchers' if defined?(::RSpec)
|
469
|
-
require 'statsd/instrument/railtie' if defined?(Rails)
|
645
|
+
require 'statsd/instrument/railtie' if defined?(::Rails::Railtie)
|
646
|
+
require 'statsd/instrument/strict' if ENV['STATSD_STRICT_MODE']
|