statsd-instrument 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +3 -3
  3. data/.rubocop.yml +3 -13
  4. data/CHANGELOG.md +6 -0
  5. data/Gemfile +8 -0
  6. data/README.md +2 -2
  7. data/Rakefile +1 -1
  8. data/bin/rake +29 -0
  9. data/bin/rubocop +29 -0
  10. data/lib/statsd/instrument.rb +4 -1
  11. data/lib/statsd/instrument/assertions.rb +200 -196
  12. data/lib/statsd/instrument/capture_sink.rb +23 -19
  13. data/lib/statsd/instrument/client.rb +414 -410
  14. data/lib/statsd/instrument/datagram.rb +69 -65
  15. data/lib/statsd/instrument/datagram_builder.rb +81 -77
  16. data/lib/statsd/instrument/dogstatsd_datagram.rb +76 -72
  17. data/lib/statsd/instrument/dogstatsd_datagram_builder.rb +68 -64
  18. data/lib/statsd/instrument/environment.rb +80 -77
  19. data/lib/statsd/instrument/expectation.rb +96 -92
  20. data/lib/statsd/instrument/helpers.rb +11 -7
  21. data/lib/statsd/instrument/log_sink.rb +20 -16
  22. data/lib/statsd/instrument/matchers.rb +86 -70
  23. data/lib/statsd/instrument/null_sink.rb +12 -8
  24. data/lib/statsd/instrument/railtie.rb +11 -7
  25. data/lib/statsd/instrument/statsd_datagram_builder.rb +12 -8
  26. data/lib/statsd/instrument/udp_sink.rb +50 -46
  27. data/lib/statsd/instrument/version.rb +1 -1
  28. data/statsd-instrument.gemspec +2 -8
  29. data/test/assertions_test.rb +12 -12
  30. data/test/capture_sink_test.rb +8 -8
  31. data/test/client_test.rb +54 -54
  32. data/test/datagram_builder_test.rb +29 -29
  33. data/test/datagram_test.rb +1 -1
  34. data/test/dogstatsd_datagram_builder_test.rb +28 -28
  35. data/test/environment_test.rb +9 -9
  36. data/test/helpers/rubocop_helper.rb +9 -6
  37. data/test/helpers_test.rb +5 -5
  38. data/test/integration_test.rb +1 -1
  39. data/test/log_sink_test.rb +2 -2
  40. data/test/matchers_test.rb +36 -36
  41. data/test/null_sink_test.rb +2 -2
  42. data/test/rubocop/metric_return_value_test.rb +3 -3
  43. data/test/rubocop/positional_arguments_test.rb +10 -10
  44. data/test/statsd_instrumentation_test.rb +66 -66
  45. data/test/statsd_test.rb +44 -44
  46. data/test/test_helper.rb +6 -4
  47. data/test/udp_sink_test.rb +8 -8
  48. metadata +7 -103
  49. 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
- # @note This class is part of the new Client implementation that is intended
4
- # to become the new default in the next major release of this library.
5
- class StatsD::Instrument::CaptureSink
6
- attr_reader :parent, :datagrams, :datagram_class
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
- def initialize(parent:, datagram_class: StatsD::Instrument::Datagram)
9
- @parent = parent
10
- @datagram_class = datagram_class
11
- @datagrams = []
12
- end
10
+ def initialize(parent:, datagram_class: StatsD::Instrument::Datagram)
11
+ @parent = parent
12
+ @datagram_class = datagram_class
13
+ @datagrams = []
14
+ end
13
15
 
14
- def sample?(_sample_rate)
15
- true
16
- end
16
+ def sample?(_sample_rate)
17
+ true
18
+ end
17
19
 
18
- def <<(datagram)
19
- @datagrams << datagram_class.new(datagram)
20
- parent << datagram
21
- self
22
- end
20
+ def <<(datagram)
21
+ @datagrams << datagram_class.new(datagram)
22
+ parent << datagram
23
+ self
24
+ end
23
25
 
24
- def clear
25
- @datagrams.clear
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
- # The Client is the main interface for using StatsD. It defines the metric
4
- # methods that you would normally call from your application.
5
- #
6
- # The client set to {StatsD.singleton_client} will handle all metric calls made
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
- # @see StatsD::Instrument::Environment
25
- def from_env(
26
- env = StatsD::Instrument::Environment.current,
27
- prefix: env.statsd_prefix,
28
- default_sample_rate: env.statsd_sample_rate,
29
- default_tags: env.statsd_default_tags,
30
- implementation: env.statsd_implementation,
31
- sink: env.default_sink_for_environment,
32
- datagram_builder_class: datagram_builder_class_for_implementation(implementation)
33
- )
34
- new(
35
- prefix: prefix,
36
- default_sample_rate: default_sample_rate,
37
- default_tags: default_tags,
38
- implementation: implementation,
39
- sink: sink,
40
- datagram_builder_class: datagram_builder_class,
41
- )
42
- end
43
-
44
- # Finds the right DatagramBuilder class for a given implementation.
45
- # @private
46
- # @param [Symbol, String] implementation The name of the implementation, e.g.
47
- # `"statsd"` or `:datadog`.
48
- # @return [Class] The subclass of {StatsD::Instrument::DatagramBuilder}
49
- # builder to use to generate UDP datagrams for the given implementation.
50
- # @raise `NotImplementedError` if the implementation is not recognized or
51
- # supported.
52
- def datagram_builder_class_for_implementation(implementation)
53
- case implementation.to_s
54
- when 'statsd'
55
- StatsD::Instrument::StatsDDatagramBuilder
56
- when 'datadog', 'dogstatsd'
57
- StatsD::Instrument::DogStatsDDatagramBuilder
58
- else
59
- raise NotImplementedError, "No implementation for #{statsd_implementation}"
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
- # The class to use to build StatsD datagrams. To build the actual datagrams,
65
- # the class will be instantiated, potentially multiple times, by the client.
66
- #
67
- # @return [Class] A subclass of {StatsD::Instrument::DatagramBuilder}
68
- # @see .datagram_builder_class_for_implementation
69
- attr_reader :datagram_builder_class
70
-
71
- # The sink to send UDP datagrams to.
72
- #
73
- # This can be set to any object that responds to the following methods:
74
- #
75
- # - `sample?` which should return true if the metric should be sampled, i.e.
76
- # actually sent to the sink.
77
- # - `#<<` which takes a UDP datagram as string to emit the datagram. This
78
- # method will only be called if `sample?` returned `true`.
79
- #
80
- # Generally, you should use an instance of one of the following classes that
81
- # ship with this library:
82
- #
83
- # - {StatsD::Instrument::UDPSink} A sink that will actually emit the provided
84
- # datagrams over UDP.
85
- # - {StatsD::Instrument::NullSink} A sink that will simply swallow every
86
- # datagram. This sink is for use when testing your application.
87
- # - {StatsD::Instrument::LogSink} A sink that log all provided datagrams to
88
- # a Logger, normally {StatsD.logger}.
89
- #
90
- # @return [#sample?, #<<]
91
- attr_reader :sink
92
-
93
- # The prefix to prepend to the metric names that are emitted through this
94
- # client, using a dot (`.`) as namespace separator. E.g. when the prefix is
95
- # set to `foo`, and you emit a metric named `bar`, the metric name will be
96
- # `foo.bar`.
97
- #
98
- # Generally all the metrics you emit to the same StatsD server will share a
99
- # single, global namespace. If you are emitting metrics from multiple
100
- # applications, using a prefix is recommended to prevent metric name
101
- # collisions.
102
- #
103
- # You can also leave this value to be `nil` if you don't want to prefix your
104
- # metric names.
105
- #
106
- # @return [String, nil]
107
- #
108
- # @note The `prefix` can be overriden by any metric call by setting the
109
- # `no_prefix` keyword argument to `true`. We recommend against doing this,
110
- # but this behavior is retained for backwards compatibility.
111
- # Rather, when you feel the need to do this, we recommend instantiating
112
- # a new client without prefix (using {#clone_with_options}), and using it
113
- # to emit the metric.
114
- attr_reader :prefix
115
-
116
- # The tags to apply to all the metrics emitted through this client.
117
- #
118
- # The tags can be supplied in normal form: an array of strings. You can also
119
- # provide a hash, which will be turned into normal form by concatanting the
120
- # key and the value using a colon. To not use any default tags, set to `nil`.
121
- # Note that other components of your StatsD metric pipeline may also add tags
122
- # to metrics. E.g. the DataDog agent may add add tags like `hostname`.
123
- #
124
- # We generally recommend to not use default tags, or use them sparingly.
125
- # Adding tags to every metric easily introduces carninality explosions, which
126
- # will make metrics less precise due to the lossy nature of aggregation. It
127
- # also makes your infrastructure more expsnive to run, and the user interface
128
- # of your metric explorer less responsive.
129
- #
130
- # @return [Array<String>, Hash, nil]
131
- attr_reader :default_tags
132
-
133
- # The default sample rate to use for metrics that are emitted without a
134
- # sample rate set. This should be a value between 0 (never emit a metric) and
135
- # 1.0 (always emit). If it is not set, the default value 1.0 is used.
136
- #
137
- # We generally recommend setting sample rates on individual metrics based
138
- # on their frequency, rather than changing the default sample rate.
139
- #
140
- # @return [Float] (default: 1.0) A value between 0.0 and 1.0.
141
- attr_reader :default_sample_rate
142
-
143
- # Instantiates a new client.
144
- # @see .from_env to instantiate a client using environment variables.
145
- def initialize(
146
- prefix: nil,
147
- default_sample_rate: 1.0,
148
- default_tags: nil,
149
- implementation: 'datadog',
150
- sink: StatsD::Instrument::NullSink.new,
151
- datagram_builder_class: self.class.datagram_builder_class_for_implementation(implementation)
152
- )
153
- @sink = sink
154
- @datagram_builder_class = datagram_builder_class
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
- # @!group Metric Methods
164
-
165
- # Emits a counter metric.
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
- # Emits a timing metric.
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
- sample_rate ||= @default_sample_rate
217
- return StatsD::Instrument::VOID unless sample?(sample_rate)
218
- emit(datagram_builder(no_prefix: no_prefix).ms(name, value, sample_rate, tags))
219
- end
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
- # Emits a gauge metric.
222
- #
223
- # You should use a gauge if you are reporting the current value of
224
- # something that can only have one value at the time. E.g., the
225
- # speed of your car. A newly reported value will replace the previously
226
- # reported value.
227
- #
228
- #
229
- # @param name (see #increment)
230
- # @param [Numeric] value The gauged value.
231
- # @param sample_rate (see #increment)
232
- # @param tags (see #increment)
233
- # @return [void]
234
- def gauge(name, value, sample_rate: nil, tags: nil, no_prefix: false)
235
- sample_rate ||= @default_sample_rate
236
- return StatsD::Instrument::VOID unless sample?(sample_rate)
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
- # Emits a set metric, which counts distinct values.
241
- #
242
- # @param name (see #increment)
243
- # @param [Numeric, String] value The value to count for distinct occurrences.
244
- # @param sample_rate (see #increment)
245
- # @param tags (see #increment)
246
- # @return [void]
247
- def set(name, value, sample_rate: nil, tags: nil, no_prefix: false)
248
- sample_rate ||= @default_sample_rate
249
- return StatsD::Instrument::VOID unless sample?(sample_rate)
250
- emit(datagram_builder(no_prefix: no_prefix).s(name, value, sample_rate, tags))
251
- end
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
- # Emits a distribution metric, which builds a histogram of the reported
254
- # values.
255
- #
256
- # @note The distribution metric type is not available on all implementations.
257
- # A `NotImplementedError` will be raised if you call this method, but
258
- # the active implementation does not support it.
259
- #
260
- # @param name (see #increment)
261
- # @param [Numeric] value The value to include in the distribution histogram.
262
- # @param sample_rate (see #increment)
263
- # @param tags (see #increment)
264
- # @return [void]
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
- sample_rate ||= @default_sample_rate
271
- return StatsD::Instrument::VOID unless sample?(sample_rate)
272
- emit(datagram_builder(no_prefix: no_prefix).d(name, value, sample_rate, tags))
273
- end
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
- # Emits a histogram metric, which builds a histogram of the reported values.
276
- #
277
- # @note The histogram metric type is not available on all implementations.
278
- # A `NotImplementedError` will be raised if you call this method, but
279
- # the active implementation does not support it.
280
- #
281
- # @param name (see #increment)
282
- # @param [Numeric] value The value to include in the histogram.
283
- # @param sample_rate (see #increment)
284
- # @param tags (see #increment)
285
- # @return [void]
286
- def histogram(name, value, sample_rate: nil, tags: nil, no_prefix: false)
287
- sample_rate ||= @default_sample_rate
288
- return StatsD::Instrument::VOID unless sample?(sample_rate)
289
- emit(datagram_builder(no_prefix: no_prefix).h(name, value, sample_rate, tags))
290
- end
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
- # @!endgroup
293
-
294
- # Measures the latency of the given block in milliseconds, and emits it as a metric.
295
- #
296
- # @param name (see #increment)
297
- # @param sample_rate (see #increment)
298
- # @param tags (see #increment)
299
- # @param [Symbol] metric_type The metric type to use. If not specified, we will
300
- # use the preferred metric type of the implementation. The default is `:ms`.
301
- # Generally, you should not have to set this.
302
- # @yield The latency (execution time) of the block
303
- # @return The return value of the provided block will be passed through.
304
- def latency(name, sample_rate: nil, tags: nil, metric_type: nil, no_prefix: false)
305
- start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
306
- begin
307
- yield
308
- ensure
309
- stop = Process.clock_gettime(Process::CLOCK_MONOTONIC)
310
-
311
- sample_rate ||= @default_sample_rate
312
- if sample?(sample_rate)
313
- metric_type ||= datagram_builder(no_prefix: no_prefix).latency_metric_type
314
- latency_in_ms = 1000.0 * (stop - start)
315
- emit(datagram_builder(no_prefix: no_prefix).send(metric_type, name, latency_in_ms, sample_rate, tags))
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
- # Emits a service check. Services Checks allow you to characterize the status
321
- # of a service in order to monitor it within Datadog.
322
- #
323
- # @param name (see StatsD::Instrument::DogStatsDDatagramBuilder#_sc)
324
- # @param status (see StatsD::Instrument::DogStatsDDatagramBuilder#_sc)
325
- # @param timestamp (see StatsD::Instrument::DogStatsDDatagramBuilder#_sc)
326
- # @param hostname (see StatsD::Instrument::DogStatsDDatagramBuilder#_sc)
327
- # @param tags (see StatsD::Instrument::DogStatsDDatagramBuilder#_sc)
328
- # @param message (see StatsD::Instrument::DogStatsDDatagramBuilder#_sc)
329
- # @return [void]
330
- #
331
- # @note Supported by the Datadog implementation only.
332
- def service_check(name, status, timestamp: nil, hostname: nil, tags: nil, message: nil, no_prefix: false)
333
- emit(datagram_builder(no_prefix: no_prefix)._sc(name, status,
334
- timestamp: timestamp, hostname: hostname, tags: tags, message: message))
335
- end
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
- # Emits an event. An event represents any record of activity noteworthy for engineers.
338
- #
339
- # @param title (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
340
- # @param text (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
341
- # @param timestamp (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
342
- # @param hostname (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
343
- # @param aggregation_key (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
344
- # @param priority (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
345
- # @param source_type_name (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
346
- # @param alert_type (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
347
- # @param tags (see StatsD::Instrument::DogStatsDDatagramBuilder#_e)
348
- # @return [void]
349
- #
350
- # @note Supported by the Datadog implementation only.
351
- def event(title, text, timestamp: nil, hostname: nil, aggregation_key: nil, priority: nil,
352
- source_type_name: nil, alert_type: nil, tags: nil, no_prefix: false)
353
-
354
- emit(datagram_builder(no_prefix: no_prefix)._e(title, text, timestamp: timestamp,
355
- hostname: hostname, tags: tags, aggregation_key: aggregation_key, priority: priority,
356
- source_type_name: source_type_name, alert_type: alert_type))
357
- end
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
- # Instantiates a new StatsD client that uses the settings of the current client,
360
- # except for the provided overrides.
361
- #
362
- # @yield [client] A new client will be constructed with the altered settings, and
363
- # yielded to the block. The original client will not be affected. The new client
364
- # will be disposed after the block returns
365
- # @return The return value of the block will be passed on as return value.
366
- def with_options(
367
- sink: nil,
368
- prefix: nil,
369
- default_sample_rate: nil,
370
- default_tags: nil,
371
- datagram_builder_class: nil
372
- )
373
- client = clone_with_options(sink: sink, prefix: prefix,
374
- default_sample_rate: default_sample_rate, default_tags: default_tags,
375
- datagram_builder_class: datagram_builder_class)
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
- def clone_with_options(
381
- sink: nil,
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
- def capture_sink
397
- StatsD::Instrument::CaptureSink.new(
398
- parent: @sink,
399
- datagram_class: datagram_builder_class.datagram_class,
400
- )
401
- end
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
- def with_capture_sink(capture_sink)
404
- @sink = capture_sink
405
- yield
406
- ensure
407
- @sink = @sink.parent
408
- end
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
- # Captures metrics that were emitted during the provided block.
411
- #
412
- # @yield During the execution of the provided block, metrics will be captured.
413
- # @return [Array<StatsD::Instagram::Datagram>] The list of metrics that were
414
- # emitted during the block, in the same order in which they were emitted.
415
- def capture(&block)
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
- protected
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
- def datagram_builder(no_prefix:)
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
- def sample?(sample_rate)
431
- @sink.sample?(sample_rate)
432
- end
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
- def emit(datagram)
435
- @sink << datagram
436
- StatsD::Instrument::VOID
436
+ def emit(datagram)
437
+ @sink << datagram
438
+ StatsD::Instrument::VOID
439
+ end
440
+ end
437
441
  end
438
442
  end