statsd-instrument 3.0.0 → 3.0.1
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/ci.yml +3 -3
- data/.rubocop.yml +3 -13
- data/CHANGELOG.md +6 -0
- data/Gemfile +8 -0
- data/README.md +2 -2
- data/Rakefile +1 -1
- data/bin/rake +29 -0
- data/bin/rubocop +29 -0
- data/lib/statsd/instrument.rb +4 -1
- data/lib/statsd/instrument/assertions.rb +200 -196
- data/lib/statsd/instrument/capture_sink.rb +23 -19
- data/lib/statsd/instrument/client.rb +414 -410
- data/lib/statsd/instrument/datagram.rb +69 -65
- data/lib/statsd/instrument/datagram_builder.rb +81 -77
- data/lib/statsd/instrument/dogstatsd_datagram.rb +76 -72
- data/lib/statsd/instrument/dogstatsd_datagram_builder.rb +68 -64
- data/lib/statsd/instrument/environment.rb +80 -77
- data/lib/statsd/instrument/expectation.rb +96 -92
- data/lib/statsd/instrument/helpers.rb +11 -7
- data/lib/statsd/instrument/log_sink.rb +20 -16
- data/lib/statsd/instrument/matchers.rb +86 -70
- data/lib/statsd/instrument/null_sink.rb +12 -8
- data/lib/statsd/instrument/railtie.rb +11 -7
- data/lib/statsd/instrument/statsd_datagram_builder.rb +12 -8
- data/lib/statsd/instrument/udp_sink.rb +50 -46
- data/lib/statsd/instrument/version.rb +1 -1
- data/statsd-instrument.gemspec +2 -8
- data/test/assertions_test.rb +12 -12
- data/test/capture_sink_test.rb +8 -8
- data/test/client_test.rb +54 -54
- data/test/datagram_builder_test.rb +29 -29
- data/test/datagram_test.rb +1 -1
- data/test/dogstatsd_datagram_builder_test.rb +28 -28
- data/test/environment_test.rb +9 -9
- data/test/helpers/rubocop_helper.rb +9 -6
- data/test/helpers_test.rb +5 -5
- data/test/integration_test.rb +1 -1
- data/test/log_sink_test.rb +2 -2
- data/test/matchers_test.rb +36 -36
- data/test/null_sink_test.rb +2 -2
- data/test/rubocop/metric_return_value_test.rb +3 -3
- data/test/rubocop/positional_arguments_test.rb +10 -10
- data/test/statsd_instrumentation_test.rb +66 -66
- data/test/statsd_test.rb +44 -44
- data/test/test_helper.rb +6 -4
- data/test/udp_sink_test.rb +8 -8
- metadata +7 -103
- data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +0 -1027
@@ -1,27 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
class
|
6
|
-
|
3
|
+
module StatsD
|
4
|
+
module Instrument
|
5
|
+
# @note This class is part of the new Client implementation that is intended
|
6
|
+
# to become the new default in the next major release of this library.
|
7
|
+
class CaptureSink
|
8
|
+
attr_reader :parent, :datagrams, :datagram_class
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
def initialize(parent:, datagram_class: StatsD::Instrument::Datagram)
|
11
|
+
@parent = parent
|
12
|
+
@datagram_class = datagram_class
|
13
|
+
@datagrams = []
|
14
|
+
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
def sample?(_sample_rate)
|
17
|
+
true
|
18
|
+
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
def <<(datagram)
|
21
|
+
@datagrams << datagram_class.new(datagram)
|
22
|
+
parent << datagram
|
23
|
+
self
|
24
|
+
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
+
def clear
|
27
|
+
@datagrams.clear
|
28
|
+
end
|
29
|
+
end
|
26
30
|
end
|
27
31
|
end
|
@@ -1,438 +1,442 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
#
|
6
|
-
#
|
7
|
-
# against the StatsD singleton, e.g. `StatsD.increment`.
|
8
|
-
#
|
9
|
-
# We recommend that the configuration of the StatsD setup is provided through
|
10
|
-
# environment variables
|
11
|
-
#
|
12
|
-
# You are encouraged to instantiate multiple clients, and instantiate variants
|
13
|
-
# of an existing clients using {#clone_with_options}. We recommend instantiating
|
14
|
-
# a separate client for every logical component of your application using
|
15
|
-
# `clone_with_options`, and setting a different metric `prefix`.
|
16
|
-
#
|
17
|
-
# @see StatsD.singleton_client
|
18
|
-
# @see #clone_with_options
|
19
|
-
class StatsD::Instrument::Client
|
20
|
-
class << self
|
21
|
-
# Instantiates a StatsD::Instrument::Client using configuration values provided in
|
22
|
-
# environment variables.
|
3
|
+
module StatsD
|
4
|
+
module Instrument
|
5
|
+
# The Client is the main interface for using StatsD. It defines the metric
|
6
|
+
# methods that you would normally call from your application.
|
23
7
|
#
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
8
|
+
# The client set to {StatsD.singleton_client} will handle all metric calls made
|
9
|
+
# against the StatsD singleton, e.g. `StatsD.increment`.
|
10
|
+
#
|
11
|
+
# We recommend that the configuration of the StatsD setup is provided through
|
12
|
+
# environment variables
|
13
|
+
#
|
14
|
+
# You are encouraged to instantiate multiple clients, and instantiate variants
|
15
|
+
# of an existing clients using {#clone_with_options}. We recommend instantiating
|
16
|
+
# a separate client for every logical component of your application using
|
17
|
+
# `clone_with_options`, and setting a different metric `prefix`.
|
18
|
+
#
|
19
|
+
# @see StatsD.singleton_client
|
20
|
+
# @see #clone_with_options
|
21
|
+
class Client
|
22
|
+
class << self
|
23
|
+
# Instantiates a StatsD::Instrument::Client using configuration values provided in
|
24
|
+
# environment variables.
|
25
|
+
#
|
26
|
+
# @see StatsD::Instrument::Environment
|
27
|
+
def from_env(
|
28
|
+
env = StatsD::Instrument::Environment.current,
|
29
|
+
prefix: env.statsd_prefix,
|
30
|
+
default_sample_rate: env.statsd_sample_rate,
|
31
|
+
default_tags: env.statsd_default_tags,
|
32
|
+
implementation: env.statsd_implementation,
|
33
|
+
sink: env.default_sink_for_environment,
|
34
|
+
datagram_builder_class: datagram_builder_class_for_implementation(implementation)
|
35
|
+
)
|
36
|
+
new(
|
37
|
+
prefix: prefix,
|
38
|
+
default_sample_rate: default_sample_rate,
|
39
|
+
default_tags: default_tags,
|
40
|
+
implementation: implementation,
|
41
|
+
sink: sink,
|
42
|
+
datagram_builder_class: datagram_builder_class,
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Finds the right DatagramBuilder class for a given implementation.
|
47
|
+
# @private
|
48
|
+
# @param [Symbol, String] implementation The name of the implementation, e.g.
|
49
|
+
# `"statsd"` or `:datadog`.
|
50
|
+
# @return [Class] The subclass of {StatsD::Instrument::DatagramBuilder}
|
51
|
+
# builder to use to generate UDP datagrams for the given implementation.
|
52
|
+
# @raise `NotImplementedError` if the implementation is not recognized or
|
53
|
+
# supported.
|
54
|
+
def datagram_builder_class_for_implementation(implementation)
|
55
|
+
case implementation.to_s
|
56
|
+
when 'statsd'
|
57
|
+
StatsD::Instrument::StatsDDatagramBuilder
|
58
|
+
when 'datadog', 'dogstatsd'
|
59
|
+
StatsD::Instrument::DogStatsDDatagramBuilder
|
60
|
+
else
|
61
|
+
raise NotImplementedError, "Implementation named #{implementation} could not be found"
|
62
|
+
end
|
63
|
+
end
|
60
64
|
end
|
61
|
-
end
|
62
|
-
end
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
@prefix = prefix
|
157
|
-
@default_tags = default_tags
|
158
|
-
@default_sample_rate = default_sample_rate
|
159
|
-
|
160
|
-
@datagram_builder = { false => nil, true => nil }
|
161
|
-
end
|
66
|
+
# The class to use to build StatsD datagrams. To build the actual datagrams,
|
67
|
+
# the class will be instantiated, potentially multiple times, by the client.
|
68
|
+
#
|
69
|
+
# @return [Class] A subclass of {StatsD::Instrument::DatagramBuilder}
|
70
|
+
# @see .datagram_builder_class_for_implementation
|
71
|
+
attr_reader :datagram_builder_class
|
72
|
+
|
73
|
+
# The sink to send UDP datagrams to.
|
74
|
+
#
|
75
|
+
# This can be set to any object that responds to the following methods:
|
76
|
+
#
|
77
|
+
# - `sample?` which should return true if the metric should be sampled, i.e.
|
78
|
+
# actually sent to the sink.
|
79
|
+
# - `#<<` which takes a UDP datagram as string to emit the datagram. This
|
80
|
+
# method will only be called if `sample?` returned `true`.
|
81
|
+
#
|
82
|
+
# Generally, you should use an instance of one of the following classes that
|
83
|
+
# ship with this library:
|
84
|
+
#
|
85
|
+
# - {StatsD::Instrument::UDPSink} A sink that will actually emit the provided
|
86
|
+
# datagrams over UDP.
|
87
|
+
# - {StatsD::Instrument::NullSink} A sink that will simply swallow every
|
88
|
+
# datagram. This sink is for use when testing your application.
|
89
|
+
# - {StatsD::Instrument::LogSink} A sink that log all provided datagrams to
|
90
|
+
# a Logger, normally {StatsD.logger}.
|
91
|
+
#
|
92
|
+
# @return [#sample?, #<<]
|
93
|
+
attr_reader :sink
|
94
|
+
|
95
|
+
# The prefix to prepend to the metric names that are emitted through this
|
96
|
+
# client, using a dot (`.`) as namespace separator. E.g. when the prefix is
|
97
|
+
# set to `foo`, and you emit a metric named `bar`, the metric name will be
|
98
|
+
# `foo.bar`.
|
99
|
+
#
|
100
|
+
# Generally all the metrics you emit to the same StatsD server will share a
|
101
|
+
# single, global namespace. If you are emitting metrics from multiple
|
102
|
+
# applications, using a prefix is recommended to prevent metric name
|
103
|
+
# collisions.
|
104
|
+
#
|
105
|
+
# You can also leave this value to be `nil` if you don't want to prefix your
|
106
|
+
# metric names.
|
107
|
+
#
|
108
|
+
# @return [String, nil]
|
109
|
+
#
|
110
|
+
# @note The `prefix` can be overridden by any metric call by setting the
|
111
|
+
# `no_prefix` keyword argument to `true`. We recommend against doing this,
|
112
|
+
# but this behavior is retained for backwards compatibility.
|
113
|
+
# Rather, when you feel the need to do this, we recommend instantiating
|
114
|
+
# a new client without prefix (using {#clone_with_options}), and using it
|
115
|
+
# to emit the metric.
|
116
|
+
attr_reader :prefix
|
117
|
+
|
118
|
+
# The tags to apply to all the metrics emitted through this client.
|
119
|
+
#
|
120
|
+
# The tags can be supplied in normal form: an array of strings. You can also
|
121
|
+
# provide a hash, which will be turned into normal form by concatanting the
|
122
|
+
# key and the value using a colon. To not use any default tags, set to `nil`.
|
123
|
+
# Note that other components of your StatsD metric pipeline may also add tags
|
124
|
+
# to metrics. E.g. the DataDog agent may add add tags like `hostname`.
|
125
|
+
#
|
126
|
+
# We generally recommend to not use default tags, or use them sparingly.
|
127
|
+
# Adding tags to every metric easily introduces carninality explosions, which
|
128
|
+
# will make metrics less precise due to the lossy nature of aggregation. It
|
129
|
+
# also makes your infrastructure more expsnive to run, and the user interface
|
130
|
+
# of your metric explorer less responsive.
|
131
|
+
#
|
132
|
+
# @return [Array<String>, Hash, nil]
|
133
|
+
attr_reader :default_tags
|
134
|
+
|
135
|
+
# The default sample rate to use for metrics that are emitted without a
|
136
|
+
# sample rate set. This should be a value between 0 (never emit a metric) and
|
137
|
+
# 1.0 (always emit). If it is not set, the default value 1.0 is used.
|
138
|
+
#
|
139
|
+
# We generally recommend setting sample rates on individual metrics based
|
140
|
+
# on their frequency, rather than changing the default sample rate.
|
141
|
+
#
|
142
|
+
# @return [Float] (default: 1.0) A value between 0.0 and 1.0.
|
143
|
+
attr_reader :default_sample_rate
|
144
|
+
|
145
|
+
# Instantiates a new client.
|
146
|
+
# @see .from_env to instantiate a client using environment variables.
|
147
|
+
def initialize(
|
148
|
+
prefix: nil,
|
149
|
+
default_sample_rate: 1.0,
|
150
|
+
default_tags: nil,
|
151
|
+
implementation: 'datadog',
|
152
|
+
sink: StatsD::Instrument::NullSink.new,
|
153
|
+
datagram_builder_class: self.class.datagram_builder_class_for_implementation(implementation)
|
154
|
+
)
|
155
|
+
@sink = sink
|
156
|
+
@datagram_builder_class = datagram_builder_class
|
162
157
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
#
|
167
|
-
# You should use a counter metric to count the frequency of something happening. As a
|
168
|
-
# result, the value should generally be set to 1 (the default), unless you reporting
|
169
|
-
# about a batch of activity. E.g. `increment('messages.processed', messages.size)`
|
170
|
-
# For values that are not frequencies, you should use another metric type, e.g.
|
171
|
-
# {#histogram} or {#distribution}.
|
172
|
-
#
|
173
|
-
# @param name [String] The name of the metric.
|
174
|
-
#
|
175
|
-
# - We recommend using `snake_case.metric_names` as naming scheme.
|
176
|
-
# - A `.` should be used for namespacing, e.g. `foo.bar.baz`
|
177
|
-
# - A metric name should not include the following characters: `|`, `@`, and `:`.
|
178
|
-
# The library will convert these characters to `_`.
|
179
|
-
#
|
180
|
-
# @param value [Integer] (default: 1) The value to increment the counter by.
|
181
|
-
#
|
182
|
-
# You should not compensate for the sample rate using the counter increment. E.g., if
|
183
|
-
# your sample rate is set to `0.01`, you should not use 100 as increment to compensate
|
184
|
-
# for it. The sample rate is part of the packet that is being sent to the server, and
|
185
|
-
# the server should know how to compensate for it.
|
186
|
-
#
|
187
|
-
# @param [Float] sample_rate (default: `#default_sample_rate`) The rate at which to sample
|
188
|
-
# this metric call. This value should be between 0 and 1. This value can be used to reduce
|
189
|
-
# the amount of network I/O (and CPU cycles) is being used for very frequent metrics.
|
190
|
-
#
|
191
|
-
# - A value of `0.1` means that only 1 out of 10 calls will be emitted; the other 9 will
|
192
|
-
# be short-circuited.
|
193
|
-
# - When set to `1`, every metric will be emitted.
|
194
|
-
# - If this parameter is not set, the default sample rate for this client will be used.
|
195
|
-
#
|
196
|
-
# @param [Hash<Symbol, String>, Array<String>] tags (default: nil)
|
197
|
-
# @return [void]
|
198
|
-
def increment(name, value = 1, sample_rate: nil, tags: nil, no_prefix: false)
|
199
|
-
sample_rate ||= @default_sample_rate
|
200
|
-
return StatsD::Instrument::VOID unless sample?(sample_rate)
|
201
|
-
emit(datagram_builder(no_prefix: no_prefix).c(name, value, sample_rate, tags))
|
202
|
-
end
|
158
|
+
@prefix = prefix
|
159
|
+
@default_tags = default_tags
|
160
|
+
@default_sample_rate = default_sample_rate
|
203
161
|
|
204
|
-
|
205
|
-
|
206
|
-
# @param name (see #increment)
|
207
|
-
# @param [Numeric] value The duration to record, in milliseconds.
|
208
|
-
# @param sample_rate (see #increment)
|
209
|
-
# @param tags (see #increment)
|
210
|
-
# @return [void]
|
211
|
-
def measure(name, value = nil, sample_rate: nil, tags: nil, no_prefix: false, &block)
|
212
|
-
if block_given?
|
213
|
-
return latency(name, sample_rate: sample_rate, tags: tags, metric_type: :ms, no_prefix: no_prefix, &block)
|
214
|
-
end
|
162
|
+
@datagram_builder = { false => nil, true => nil }
|
163
|
+
end
|
215
164
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
165
|
+
# @!group Metric Methods
|
166
|
+
|
167
|
+
# Emits a counter metric.
|
168
|
+
#
|
169
|
+
# You should use a counter metric to count the frequency of something happening. As a
|
170
|
+
# result, the value should generally be set to 1 (the default), unless you reporting
|
171
|
+
# about a batch of activity. E.g. `increment('messages.processed', messages.size)`
|
172
|
+
# For values that are not frequencies, you should use another metric type, e.g.
|
173
|
+
# {#histogram} or {#distribution}.
|
174
|
+
#
|
175
|
+
# @param name [String] The name of the metric.
|
176
|
+
#
|
177
|
+
# - We recommend using `snake_case.metric_names` as naming scheme.
|
178
|
+
# - A `.` should be used for namespacing, e.g. `foo.bar.baz`
|
179
|
+
# - A metric name should not include the following characters: `|`, `@`, and `:`.
|
180
|
+
# The library will convert these characters to `_`.
|
181
|
+
#
|
182
|
+
# @param value [Integer] (default: 1) The value to increment the counter by.
|
183
|
+
#
|
184
|
+
# You should not compensate for the sample rate using the counter increment. E.g., if
|
185
|
+
# your sample rate is set to `0.01`, you should not use 100 as increment to compensate
|
186
|
+
# for it. The sample rate is part of the packet that is being sent to the server, and
|
187
|
+
# the server should know how to compensate for it.
|
188
|
+
#
|
189
|
+
# @param [Float] sample_rate (default: `#default_sample_rate`) The rate at which to sample
|
190
|
+
# this metric call. This value should be between 0 and 1. This value can be used to reduce
|
191
|
+
# the amount of network I/O (and CPU cycles) is being used for very frequent metrics.
|
192
|
+
#
|
193
|
+
# - A value of `0.1` means that only 1 out of 10 calls will be emitted; the other 9 will
|
194
|
+
# be short-circuited.
|
195
|
+
# - When set to `1`, every metric will be emitted.
|
196
|
+
# - If this parameter is not set, the default sample rate for this client will be used.
|
197
|
+
#
|
198
|
+
# @param [Hash<Symbol, String>, Array<String>] tags (default: nil)
|
199
|
+
# @return [void]
|
200
|
+
def increment(name, value = 1, sample_rate: nil, tags: nil, no_prefix: false)
|
201
|
+
sample_rate ||= @default_sample_rate
|
202
|
+
return StatsD::Instrument::VOID unless sample?(sample_rate)
|
203
|
+
emit(datagram_builder(no_prefix: no_prefix).c(name, value, sample_rate, tags))
|
204
|
+
end
|
220
205
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
emit(datagram_builder(no_prefix: no_prefix).g(name, value, sample_rate, tags))
|
238
|
-
end
|
206
|
+
# Emits a timing metric.
|
207
|
+
#
|
208
|
+
# @param name (see #increment)
|
209
|
+
# @param [Numeric] value The duration to record, in milliseconds.
|
210
|
+
# @param sample_rate (see #increment)
|
211
|
+
# @param tags (see #increment)
|
212
|
+
# @return [void]
|
213
|
+
def measure(name, value = nil, sample_rate: nil, tags: nil, no_prefix: false, &block)
|
214
|
+
if block_given?
|
215
|
+
return latency(name, sample_rate: sample_rate, tags: tags, metric_type: :ms, no_prefix: no_prefix, &block)
|
216
|
+
end
|
217
|
+
|
218
|
+
sample_rate ||= @default_sample_rate
|
219
|
+
return StatsD::Instrument::VOID unless sample?(sample_rate)
|
220
|
+
emit(datagram_builder(no_prefix: no_prefix).ms(name, value, sample_rate, tags))
|
221
|
+
end
|
239
222
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
223
|
+
# Emits a gauge metric.
|
224
|
+
#
|
225
|
+
# You should use a gauge if you are reporting the current value of
|
226
|
+
# something that can only have one value at the time. E.g., the
|
227
|
+
# speed of your car. A newly reported value will replace the previously
|
228
|
+
# reported value.
|
229
|
+
#
|
230
|
+
#
|
231
|
+
# @param name (see #increment)
|
232
|
+
# @param [Numeric] value The gauged value.
|
233
|
+
# @param sample_rate (see #increment)
|
234
|
+
# @param tags (see #increment)
|
235
|
+
# @return [void]
|
236
|
+
def gauge(name, value, sample_rate: nil, tags: nil, no_prefix: false)
|
237
|
+
sample_rate ||= @default_sample_rate
|
238
|
+
return StatsD::Instrument::VOID unless sample?(sample_rate)
|
239
|
+
emit(datagram_builder(no_prefix: no_prefix).g(name, value, sample_rate, tags))
|
240
|
+
end
|
252
241
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
def distribution(name, value = nil, sample_rate: nil, tags: nil, no_prefix: false, &block)
|
266
|
-
if block_given?
|
267
|
-
return latency(name, sample_rate: sample_rate, tags: tags, metric_type: :d, no_prefix: no_prefix, &block)
|
268
|
-
end
|
242
|
+
# Emits a set metric, which counts distinct values.
|
243
|
+
#
|
244
|
+
# @param name (see #increment)
|
245
|
+
# @param [Numeric, String] value The value to count for distinct occurrences.
|
246
|
+
# @param sample_rate (see #increment)
|
247
|
+
# @param tags (see #increment)
|
248
|
+
# @return [void]
|
249
|
+
def set(name, value, sample_rate: nil, tags: nil, no_prefix: false)
|
250
|
+
sample_rate ||= @default_sample_rate
|
251
|
+
return StatsD::Instrument::VOID unless sample?(sample_rate)
|
252
|
+
emit(datagram_builder(no_prefix: no_prefix).s(name, value, sample_rate, tags))
|
253
|
+
end
|
269
254
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
255
|
+
# Emits a distribution metric, which builds a histogram of the reported
|
256
|
+
# values.
|
257
|
+
#
|
258
|
+
# @note The distribution metric type is not available on all implementations.
|
259
|
+
# A `NotImplementedError` will be raised if you call this method, but
|
260
|
+
# the active implementation does not support it.
|
261
|
+
#
|
262
|
+
# @param name (see #increment)
|
263
|
+
# @param [Numeric] value The value to include in the distribution histogram.
|
264
|
+
# @param sample_rate (see #increment)
|
265
|
+
# @param tags (see #increment)
|
266
|
+
# @return [void]
|
267
|
+
def distribution(name, value = nil, sample_rate: nil, tags: nil, no_prefix: false, &block)
|
268
|
+
if block_given?
|
269
|
+
return latency(name, sample_rate: sample_rate, tags: tags, metric_type: :d, no_prefix: no_prefix, &block)
|
270
|
+
end
|
271
|
+
|
272
|
+
sample_rate ||= @default_sample_rate
|
273
|
+
return StatsD::Instrument::VOID unless sample?(sample_rate)
|
274
|
+
emit(datagram_builder(no_prefix: no_prefix).d(name, value, sample_rate, tags))
|
275
|
+
end
|
274
276
|
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
277
|
+
# Emits a histogram metric, which builds a histogram of the reported values.
|
278
|
+
#
|
279
|
+
# @note The histogram metric type is not available on all implementations.
|
280
|
+
# A `NotImplementedError` will be raised if you call this method, but
|
281
|
+
# the active implementation does not support it.
|
282
|
+
#
|
283
|
+
# @param name (see #increment)
|
284
|
+
# @param [Numeric] value The value to include in the histogram.
|
285
|
+
# @param sample_rate (see #increment)
|
286
|
+
# @param tags (see #increment)
|
287
|
+
# @return [void]
|
288
|
+
def histogram(name, value, sample_rate: nil, tags: nil, no_prefix: false)
|
289
|
+
sample_rate ||= @default_sample_rate
|
290
|
+
return StatsD::Instrument::VOID unless sample?(sample_rate)
|
291
|
+
emit(datagram_builder(no_prefix: no_prefix).h(name, value, sample_rate, tags))
|
292
|
+
end
|
291
293
|
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
294
|
+
# @!endgroup
|
295
|
+
|
296
|
+
# Measures the latency of the given block in milliseconds, and emits it as a metric.
|
297
|
+
#
|
298
|
+
# @param name (see #increment)
|
299
|
+
# @param sample_rate (see #increment)
|
300
|
+
# @param tags (see #increment)
|
301
|
+
# @param [Symbol] metric_type The metric type to use. If not specified, we will
|
302
|
+
# use the preferred metric type of the implementation. The default is `:ms`.
|
303
|
+
# Generally, you should not have to set this.
|
304
|
+
# @yield The latency (execution time) of the block
|
305
|
+
# @return The return value of the provided block will be passed through.
|
306
|
+
def latency(name, sample_rate: nil, tags: nil, metric_type: nil, no_prefix: false)
|
307
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
308
|
+
begin
|
309
|
+
yield
|
310
|
+
ensure
|
311
|
+
stop = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
312
|
+
|
313
|
+
sample_rate ||= @default_sample_rate
|
314
|
+
if sample?(sample_rate)
|
315
|
+
metric_type ||= datagram_builder(no_prefix: no_prefix).latency_metric_type
|
316
|
+
latency_in_ms = 1000.0 * (stop - start)
|
317
|
+
emit(datagram_builder(no_prefix: no_prefix).send(metric_type, name, latency_in_ms, sample_rate, tags))
|
318
|
+
end
|
319
|
+
end
|
316
320
|
end
|
317
|
-
end
|
318
|
-
end
|
319
321
|
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
322
|
+
# Emits a service check. Services Checks allow you to characterize the status
|
323
|
+
# of a service in order to monitor it within Datadog.
|
324
|
+
#
|
325
|
+
# @param name (see StatsD::Instrument::DogStatsDDatagramBuilder#_sc)
|
326
|
+
# @param status (see StatsD::Instrument::DogStatsDDatagramBuilder#_sc)
|
327
|
+
# @param timestamp (see StatsD::Instrument::DogStatsDDatagramBuilder#_sc)
|
328
|
+
# @param hostname (see StatsD::Instrument::DogStatsDDatagramBuilder#_sc)
|
329
|
+
# @param tags (see StatsD::Instrument::DogStatsDDatagramBuilder#_sc)
|
330
|
+
# @param message (see StatsD::Instrument::DogStatsDDatagramBuilder#_sc)
|
331
|
+
# @return [void]
|
332
|
+
#
|
333
|
+
# @note Supported by the Datadog implementation only.
|
334
|
+
def service_check(name, status, timestamp: nil, hostname: nil, tags: nil, message: nil, no_prefix: false)
|
335
|
+
emit(datagram_builder(no_prefix: no_prefix)._sc(name, status,
|
336
|
+
timestamp: timestamp, hostname: hostname, tags: tags, message: message))
|
337
|
+
end
|
336
338
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
339
|
+
# Emits an event. An event represents any record of activity noteworthy for engineers.
|
340
|
+
#
|
341
|
+
# @param title (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
|
342
|
+
# @param text (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
|
343
|
+
# @param timestamp (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
|
344
|
+
# @param hostname (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
|
345
|
+
# @param aggregation_key (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
|
346
|
+
# @param priority (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
|
347
|
+
# @param source_type_name (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
|
348
|
+
# @param alert_type (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
|
349
|
+
# @param tags (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
|
350
|
+
# @return [void]
|
351
|
+
#
|
352
|
+
# @note Supported by the Datadog implementation only.
|
353
|
+
def event(title, text, timestamp: nil, hostname: nil, aggregation_key: nil, priority: nil,
|
354
|
+
source_type_name: nil, alert_type: nil, tags: nil, no_prefix: false)
|
355
|
+
|
356
|
+
emit(datagram_builder(no_prefix: no_prefix)._e(title, text, timestamp: timestamp,
|
357
|
+
hostname: hostname, tags: tags, aggregation_key: aggregation_key, priority: priority,
|
358
|
+
source_type_name: source_type_name, alert_type: alert_type))
|
359
|
+
end
|
358
360
|
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
yield(client)
|
378
|
-
end
|
361
|
+
# Instantiates a new StatsD client that uses the settings of the current client,
|
362
|
+
# except for the provided overrides.
|
363
|
+
#
|
364
|
+
# @yield [client] A new client will be constructed with the altered settings, and
|
365
|
+
# yielded to the block. The original client will not be affected. The new client
|
366
|
+
# will be disposed after the block returns
|
367
|
+
# @return The return value of the block will be passed on as return value.
|
368
|
+
def with_options(
|
369
|
+
sink: nil,
|
370
|
+
prefix: nil,
|
371
|
+
default_sample_rate: nil,
|
372
|
+
default_tags: nil,
|
373
|
+
datagram_builder_class: nil
|
374
|
+
)
|
375
|
+
client = clone_with_options(sink: sink, prefix: prefix,
|
376
|
+
default_sample_rate: default_sample_rate, default_tags: default_tags,
|
377
|
+
datagram_builder_class: datagram_builder_class)
|
379
378
|
|
380
|
-
|
381
|
-
|
382
|
-
prefix: nil,
|
383
|
-
default_sample_rate: nil,
|
384
|
-
default_tags: nil,
|
385
|
-
datagram_builder_class: nil
|
386
|
-
)
|
387
|
-
self.class.new(
|
388
|
-
sink: sink || @sink,
|
389
|
-
prefix: prefix || @prefix,
|
390
|
-
default_sample_rate: default_sample_rate || @default_sample_rate,
|
391
|
-
default_tags: default_tags || @default_tags,
|
392
|
-
datagram_builder_class: datagram_builder_class || @datagram_builder_class,
|
393
|
-
)
|
394
|
-
end
|
379
|
+
yield(client)
|
380
|
+
end
|
395
381
|
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
382
|
+
def clone_with_options(
|
383
|
+
sink: nil,
|
384
|
+
prefix: nil,
|
385
|
+
default_sample_rate: nil,
|
386
|
+
default_tags: nil,
|
387
|
+
datagram_builder_class: nil
|
388
|
+
)
|
389
|
+
self.class.new(
|
390
|
+
sink: sink || @sink,
|
391
|
+
prefix: prefix || @prefix,
|
392
|
+
default_sample_rate: default_sample_rate || @default_sample_rate,
|
393
|
+
default_tags: default_tags || @default_tags,
|
394
|
+
datagram_builder_class: datagram_builder_class || @datagram_builder_class,
|
395
|
+
)
|
396
|
+
end
|
402
397
|
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
398
|
+
def capture_sink
|
399
|
+
StatsD::Instrument::CaptureSink.new(
|
400
|
+
parent: @sink,
|
401
|
+
datagram_class: datagram_builder_class.datagram_class,
|
402
|
+
)
|
403
|
+
end
|
409
404
|
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
sink = capture_sink
|
417
|
-
with_capture_sink(sink, &block)
|
418
|
-
sink.datagrams
|
419
|
-
end
|
405
|
+
def with_capture_sink(capture_sink)
|
406
|
+
@sink = capture_sink
|
407
|
+
yield
|
408
|
+
ensure
|
409
|
+
@sink = @sink.parent
|
410
|
+
end
|
420
411
|
|
421
|
-
|
412
|
+
# Captures metrics that were emitted during the provided block.
|
413
|
+
#
|
414
|
+
# @yield During the execution of the provided block, metrics will be captured.
|
415
|
+
# @return [Array<StatsD::Instagram::Datagram>] The list of metrics that were
|
416
|
+
# emitted during the block, in the same order in which they were emitted.
|
417
|
+
def capture(&block)
|
418
|
+
sink = capture_sink
|
419
|
+
with_capture_sink(sink, &block)
|
420
|
+
sink.datagrams
|
421
|
+
end
|
422
422
|
|
423
|
-
|
424
|
-
@datagram_builder[no_prefix] ||= @datagram_builder_class.new(
|
425
|
-
prefix: no_prefix ? nil : prefix,
|
426
|
-
default_tags: default_tags,
|
427
|
-
)
|
428
|
-
end
|
423
|
+
protected
|
429
424
|
|
430
|
-
|
431
|
-
|
432
|
-
|
425
|
+
def datagram_builder(no_prefix:)
|
426
|
+
@datagram_builder[no_prefix] ||= @datagram_builder_class.new(
|
427
|
+
prefix: no_prefix ? nil : prefix,
|
428
|
+
default_tags: default_tags,
|
429
|
+
)
|
430
|
+
end
|
431
|
+
|
432
|
+
def sample?(sample_rate)
|
433
|
+
@sink.sample?(sample_rate)
|
434
|
+
end
|
433
435
|
|
434
|
-
|
435
|
-
|
436
|
-
|
436
|
+
def emit(datagram)
|
437
|
+
@sink << datagram
|
438
|
+
StatsD::Instrument::VOID
|
439
|
+
end
|
440
|
+
end
|
437
441
|
end
|
438
442
|
end
|