statsd-instrument 3.0.0.pre1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/lint.yml +22 -0
- data/.github/workflows/tests.yml +31 -0
- data/.rubocop.yml +3 -13
- data/CHANGELOG.md +50 -0
- data/Gemfile +8 -2
- data/README.md +6 -3
- data/Rakefile +7 -7
- data/benchmark/send-metrics-to-dev-null-log +12 -11
- data/benchmark/send-metrics-to-local-udp-receiver +16 -15
- data/bin/rake +29 -0
- data/bin/rubocop +29 -0
- data/lib/statsd-instrument.rb +1 -1
- data/lib/statsd/instrument.rb +112 -145
- data/lib/statsd/instrument/assertions.rb +200 -208
- data/lib/statsd/instrument/batched_udp_sink.rb +154 -0
- data/lib/statsd/instrument/capture_sink.rb +23 -19
- data/lib/statsd/instrument/client.rb +410 -306
- 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 +88 -77
- data/lib/statsd/instrument/expectation.rb +96 -96
- data/lib/statsd/instrument/helpers.rb +11 -7
- data/lib/statsd/instrument/log_sink.rb +20 -16
- data/lib/statsd/instrument/matchers.rb +93 -74
- data/lib/statsd/instrument/null_sink.rb +12 -8
- data/lib/statsd/instrument/railtie.rb +11 -7
- data/lib/statsd/instrument/rubocop.rb +8 -8
- data/lib/statsd/instrument/rubocop/measure_as_dist_argument.rb +1 -1
- data/lib/statsd/instrument/rubocop/metaprogramming_positional_arguments.rb +2 -2
- data/lib/statsd/instrument/rubocop/metric_prefix_argument.rb +1 -1
- data/lib/statsd/instrument/rubocop/metric_return_value.rb +2 -2
- data/lib/statsd/instrument/rubocop/metric_value_keyword_argument.rb +1 -1
- data/lib/statsd/instrument/rubocop/positional_arguments.rb +4 -4
- data/lib/statsd/instrument/rubocop/singleton_configuration.rb +1 -1
- data/lib/statsd/instrument/rubocop/splat_arguments.rb +2 -2
- data/lib/statsd/instrument/statsd_datagram_builder.rb +12 -8
- data/lib/statsd/instrument/strict.rb +1 -6
- data/lib/statsd/instrument/udp_sink.rb +49 -47
- data/lib/statsd/instrument/version.rb +1 -1
- data/statsd-instrument.gemspec +4 -8
- data/test/assertions_test.rb +205 -161
- data/test/benchmark/clock_gettime.rb +1 -1
- data/test/benchmark/default_tags.rb +9 -9
- data/test/benchmark/metrics.rb +8 -8
- data/test/benchmark/tags.rb +4 -4
- data/test/capture_sink_test.rb +14 -14
- data/test/client_test.rb +96 -96
- data/test/datagram_builder_test.rb +55 -55
- data/test/datagram_test.rb +5 -5
- data/test/dogstatsd_datagram_builder_test.rb +37 -37
- data/test/environment_test.rb +30 -21
- data/test/helpers/rubocop_helper.rb +12 -9
- data/test/helpers_test.rb +15 -15
- data/test/integration_test.rb +7 -7
- data/test/log_sink_test.rb +4 -4
- data/test/matchers_test.rb +54 -54
- data/test/null_sink_test.rb +4 -4
- data/test/rubocop/measure_as_dist_argument_test.rb +2 -2
- data/test/rubocop/metaprogramming_positional_arguments_test.rb +2 -2
- data/test/rubocop/metric_prefix_argument_test.rb +2 -2
- data/test/rubocop/metric_return_value_test.rb +6 -6
- data/test/rubocop/metric_value_keyword_argument_test.rb +3 -3
- data/test/rubocop/positional_arguments_test.rb +12 -12
- data/test/rubocop/singleton_configuration_test.rb +8 -8
- data/test/rubocop/splat_arguments_test.rb +2 -2
- data/test/statsd_datagram_builder_test.rb +6 -6
- data/test/statsd_instrumentation_test.rb +122 -122
- data/test/statsd_test.rb +69 -67
- data/test/test_helper.rb +19 -10
- data/test/udp_sink_test.rb +122 -50
- metadata +12 -92
- data/.github/workflows/ci.yml +0 -56
- data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +0 -1027
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a481f6cd0897b93e3e992fc5315b496c033a98a8cccd02948146cb638e0a6b2
|
4
|
+
data.tar.gz: ab454f2fecc89aa662ac2f16632fe2fc3c4e4b2b102d3c4058642e5706bf64c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3fae39281925135491d66805ff8dada34b0ea798d3403fdf0e6d3b9c1e2d3eda4a78295d7eea046ba7a0db55fb5d357d72e853558f12fdf81c71eff3713c816
|
7
|
+
data.tar.gz: 852e0838027594b8451d4fb617ca9aa5f614b570c50180bd513fb2986419adf3e9ea4f59ce86e63fbe799ccc3a07720954c87778c9a9dca63cd62fb339906d43
|
@@ -0,0 +1,22 @@
|
|
1
|
+
name: Lint
|
2
|
+
|
3
|
+
on: push
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
name: Rubocop
|
8
|
+
runs-on: ubuntu-18.04
|
9
|
+
|
10
|
+
steps:
|
11
|
+
- uses: actions/checkout@v1
|
12
|
+
|
13
|
+
- name: Setup Ruby
|
14
|
+
uses: actions/setup-ruby@v1
|
15
|
+
with:
|
16
|
+
ruby-version: 2.6
|
17
|
+
|
18
|
+
- name: Install dependencies
|
19
|
+
run: gem install bundler && bundle install --jobs 4 --retry 3
|
20
|
+
|
21
|
+
- name: Run Rubocop
|
22
|
+
run: bin/rubocop
|
@@ -0,0 +1,31 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on: push
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
name: Ruby ${{ matrix.ruby }} on ubuntu-18.04
|
8
|
+
runs-on: ubuntu-18.04
|
9
|
+
strategy:
|
10
|
+
fail-fast: false
|
11
|
+
matrix:
|
12
|
+
ruby: ['2.6', '2.7', '3.0']
|
13
|
+
|
14
|
+
# Windows on macOS builds started failing, so they are disabled for noew
|
15
|
+
# platform: [windows-2019, macOS-10.14, ubuntu-18.04]
|
16
|
+
# exclude:
|
17
|
+
# ...
|
18
|
+
|
19
|
+
steps:
|
20
|
+
- uses: actions/checkout@v1
|
21
|
+
|
22
|
+
- name: Setup Ruby
|
23
|
+
uses: actions/setup-ruby@v1
|
24
|
+
with:
|
25
|
+
ruby-version: ${{ matrix.ruby }}
|
26
|
+
|
27
|
+
- name: Install dependencies
|
28
|
+
run: gem install bundler && bundle install --jobs 4 --retry 3
|
29
|
+
|
30
|
+
- name: Run test suite
|
31
|
+
run: rake test
|
data/.rubocop.yml
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
|
2
|
-
-
|
1
|
+
inherit_gem:
|
2
|
+
rubocop-shopify: rubocop.yml
|
3
3
|
|
4
4
|
require:
|
5
5
|
- ./lib/statsd/instrument/rubocop.rb
|
6
6
|
|
7
7
|
AllCops:
|
8
|
-
TargetRubyVersion: 2.
|
8
|
+
TargetRubyVersion: 2.6
|
9
9
|
UseCache: true
|
10
10
|
CacheRootDirectory: tmp/rubocop
|
11
11
|
Exclude:
|
@@ -16,16 +16,6 @@ Naming/FileName:
|
|
16
16
|
Exclude:
|
17
17
|
- lib/statsd-instrument.rb
|
18
18
|
|
19
|
-
Style/ClassAndModuleChildren:
|
20
|
-
Enabled: false # TODO: enable later
|
21
|
-
|
22
|
-
|
23
|
-
Style/MethodCallWithArgsParentheses:
|
24
|
-
Enabled: false # TODO: enable later
|
25
|
-
|
26
|
-
Lint/UnusedMethodArgument:
|
27
|
-
AllowUnusedKeywordArguments: true
|
28
|
-
|
29
19
|
# Enable our own cops on our own repo
|
30
20
|
|
31
21
|
StatsD/MetricReturnValue:
|
data/CHANGELOG.md
CHANGED
@@ -8,6 +8,56 @@ section below.
|
|
8
8
|
|
9
9
|
_Nothing yet_
|
10
10
|
|
11
|
+
## Version 3.1.0
|
12
|
+
|
13
|
+
- Introduced UDP batching using a dispatcher thread, and made it the
|
14
|
+
production default.
|
15
|
+
- Dropped support for Ruby 2.4 and 2.5.
|
16
|
+
|
17
|
+
## Version 3.0.2
|
18
|
+
|
19
|
+
- Properly handle no_prefix when using StatsD assertions.
|
20
|
+
|
21
|
+
## Version 3.0.1
|
22
|
+
|
23
|
+
- Fix metaprograming methods to not print keyword argument warnings on
|
24
|
+
Ruby 2.7.
|
25
|
+
- Fix the gemspec to no longer register `rake` and `rubocop` as executables.
|
26
|
+
|
27
|
+
## Version 3.0.0
|
28
|
+
|
29
|
+
This version makes the new client that was added in version 2.6+ the default
|
30
|
+
client, and removes the legacy client.
|
31
|
+
|
32
|
+
- All previously deprecated functionality has been removed (since version 2.5,
|
33
|
+
see below).
|
34
|
+
- Support for the StatSite implementation has been dropped.
|
35
|
+
- Support for Ruby version older than 2.4 has been dropped.
|
36
|
+
- The default implementation has been changed to DataDog. To use the standard
|
37
|
+
StatsD implementation (which was the default in v2), set the
|
38
|
+
`STATSD_IMPLEMENTATION` environment variable to `statsd`.
|
39
|
+
|
40
|
+
To upgrade, follow the following process:
|
41
|
+
|
42
|
+
1. Upgrade to version 2.9.2.
|
43
|
+
2. Switch to the new client by setting the `STATSD_USE_NEW_CLIENT` environment
|
44
|
+
variable to 1.
|
45
|
+
- You may want to use the Rubocop rules that ship with this library, and
|
46
|
+
strict mode to find and fix deprecated usage patterns. See below for more
|
47
|
+
information about strict mode and the available Rubocop rules.
|
48
|
+
3. Upgrade to version 3.0.0, and unset `STATSD_USE_NEW_CLIENT`.
|
49
|
+
|
50
|
+
## Version 2.9.2
|
51
|
+
|
52
|
+
- Allow providing a value as second positional argument to `assert_statsd_*`
|
53
|
+
methods, rather than as keyword argument. This matches the arguments to the
|
54
|
+
StatsD metric call.
|
55
|
+
``` ruby
|
56
|
+
assert_statsd_increment('batch_size', 10) do
|
57
|
+
StatsD.increment('batch_size', 10)
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
11
61
|
## Version 2.9.1
|
12
62
|
|
13
63
|
- The `VOID` object being returned by metric methods (e.g. `StatsD.increment`)
|
data/Gemfile
CHANGED
@@ -3,5 +3,11 @@
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
|
7
|
-
gem
|
6
|
+
gem "rake"
|
7
|
+
gem "minitest"
|
8
|
+
gem "rspec"
|
9
|
+
gem "mocha"
|
10
|
+
gem "yard"
|
11
|
+
gem "rubocop", ">= 1.0"
|
12
|
+
gem "rubocop-shopify", require: false
|
13
|
+
gem "benchmark-ips"
|
data/README.md
CHANGED
@@ -20,7 +20,7 @@ The following environment variables are supported:
|
|
20
20
|
|
21
21
|
- `STATSD_ADDR`: (default `localhost:8125`) The address to send the StatsD UDP
|
22
22
|
datagrams to.
|
23
|
-
- `STATSD_IMPLEMENTATION`: (default: `
|
23
|
+
- `STATSD_IMPLEMENTATION`: (default: `datadog`). The StatsD implementation you
|
24
24
|
are using. `statsd`, `statsite` and `datadog` are supported. Some features
|
25
25
|
are only available on certain implementations,
|
26
26
|
- `STATSD_ENV`: The environment StatsD will run in. If this is not set
|
@@ -42,6 +42,9 @@ The following environment variables are supported:
|
|
42
42
|
overridden in a metric method call.
|
43
43
|
- `STATSD_DEFAULT_TAGS`: A comma-separated list of tags to apply to all metrics.
|
44
44
|
(Note: tags are not supported by all implementations.)
|
45
|
+
- `STATSD_FLUSH_INTERVAL`: (default: `1.0`) The interval in seconds at which
|
46
|
+
events are sent in batch. Only applicable to the UDP configuration. If set
|
47
|
+
to `0.0`, metrics are sent immediately.
|
45
48
|
|
46
49
|
## StatsD keys
|
47
50
|
|
@@ -105,7 +108,7 @@ Because you are counting unique values, the results of using a sampling value le
|
|
105
108
|
Builds a histogram of numeric values.
|
106
109
|
``` ruby
|
107
110
|
|
108
|
-
StatsD.histogram('Order.value', order.value_in_usd.to_f tags: { source: 'POS' })
|
111
|
+
StatsD.histogram('Order.value', order.value_in_usd.to_f, tags: { source: 'POS' })
|
109
112
|
```
|
110
113
|
|
111
114
|
Because you are counting unique values, the results of using a sampling value less than 1.0 can lead to unexpected, hard to interpret results.
|
@@ -128,7 +131,7 @@ An event is a (title, text) tuple that can be used to correlate metrics with som
|
|
128
131
|
This is a good fit for instance to correlate response time variation with a deploy of the new code.
|
129
132
|
|
130
133
|
```ruby
|
131
|
-
StatsD.event('shipit.deploy', 'started'
|
134
|
+
StatsD.event('shipit.deploy', 'started')
|
132
135
|
```
|
133
136
|
|
134
137
|
*Note: This is only supported by the [datadog implementation](https://docs.datadoghq.com/guides/dogstatsd/#events).*
|
data/Rakefile
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/testtask"
|
5
5
|
|
6
|
-
Rake::TestTask.new(
|
7
|
-
t.ruby_opts <<
|
8
|
-
t.libs <<
|
9
|
-
t.test_files = FileList[
|
6
|
+
Rake::TestTask.new("test") do |t|
|
7
|
+
t.ruby_opts << "-r rubygems"
|
8
|
+
t.libs << "lib" << "test"
|
9
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
10
10
|
end
|
11
11
|
|
12
|
-
task
|
12
|
+
task(default: :test)
|
@@ -1,13 +1,14 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
4
|
+
require "bundler/setup"
|
5
|
+
require "tmpdir"
|
6
|
+
require "benchmark/ips"
|
6
7
|
|
7
8
|
revision = %x(git rev-parse HEAD).rstrip
|
8
9
|
master_revision = %x(git rev-parse origin/master).rstrip
|
9
10
|
branch = if revision == master_revision
|
10
|
-
|
11
|
+
"master"
|
11
12
|
else
|
12
13
|
%x(git rev-parse --abbrev-ref HEAD).rstrip
|
13
14
|
end
|
@@ -15,18 +16,18 @@ end
|
|
15
16
|
intermediate_results_filename = "#{Dir.tmpdir}/statsd-instrument-benchmarks/#{File.basename($PROGRAM_NAME)}"
|
16
17
|
FileUtils.mkdir_p(File.dirname(intermediate_results_filename))
|
17
18
|
|
18
|
-
ENV[
|
19
|
-
require
|
19
|
+
ENV["ENV"] = "development"
|
20
|
+
require "statsd-instrument"
|
20
21
|
StatsD.logger = Logger.new(File::NULL)
|
21
22
|
|
22
23
|
report = Benchmark.ips do |bench|
|
23
24
|
bench.report("StatsD metrics to /dev/null log (branch: #{branch}, sha: #{revision[0, 7]})") do
|
24
|
-
StatsD.increment(
|
25
|
-
StatsD.measure(
|
26
|
-
StatsD.gauge(
|
27
|
-
StatsD.set(
|
25
|
+
StatsD.increment("StatsD.increment", 10, sample_rate: 15)
|
26
|
+
StatsD.measure("StatsD.measure") { 1 + 1 }
|
27
|
+
StatsD.gauge("StatsD.gauge", 12.0, tags: ["foo:bar", "quc"])
|
28
|
+
StatsD.set("StatsD.set", "value", tags: { foo: "bar", baz: "quc" })
|
28
29
|
if StatsD.singleton_client.datagram_builder_class == StatsD::Instrument::DogStatsDDatagramBuilder
|
29
|
-
StatsD.event(
|
30
|
+
StatsD.event("StasD.event", "12345")
|
30
31
|
StatsD.service_check("StatsD.service_check", "ok")
|
31
32
|
end
|
32
33
|
end
|
@@ -40,7 +41,7 @@ if report.entries.length == 1
|
|
40
41
|
puts
|
41
42
|
puts "To compare the performance of this revision against another revision (e.g. master),"
|
42
43
|
puts "check out a different branch and run this benchmark script again."
|
43
|
-
elsif ENV[
|
44
|
+
elsif ENV["KEEP_RESULTS"]
|
44
45
|
puts
|
45
46
|
puts "The intermediate results have been stored in #{intermediate_results_filename}"
|
46
47
|
else
|
@@ -1,15 +1,16 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
4
|
+
require "bundler/setup"
|
5
|
+
require "benchmark/ips"
|
6
|
+
require "tmpdir"
|
7
|
+
require "socket"
|
8
|
+
require "statsd-instrument"
|
8
9
|
|
9
10
|
revision = %x(git rev-parse HEAD).rstrip
|
10
11
|
master_revision = %x(git rev-parse origin/master).rstrip
|
11
12
|
branch = if revision == master_revision
|
12
|
-
|
13
|
+
"master"
|
13
14
|
else
|
14
15
|
%x(git rev-parse --abbrev-ref HEAD).rstrip
|
15
16
|
end
|
@@ -19,22 +20,22 @@ FileUtils.mkdir_p(File.dirname(intermediate_results_filename))
|
|
19
20
|
|
20
21
|
# Set up an UDP listener to which we can send StatsD packets
|
21
22
|
receiver = UDPSocket.new
|
22
|
-
receiver.bind(
|
23
|
+
receiver.bind("localhost", 0)
|
23
24
|
|
24
25
|
StatsD.singleton_client = StatsD::Instrument::Environment.new(
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
"STATSD_ADDR" => "#{receiver.addr[2]}:#{receiver.addr[1]}",
|
27
|
+
"STATSD_IMPLEMENTATION" => "dogstatsd",
|
28
|
+
"STATSD_ENV" => "production",
|
28
29
|
).client
|
29
30
|
|
30
31
|
report = Benchmark.ips do |bench|
|
31
32
|
bench.report("StatsD metrics to local UDP receiver (branch: #{branch}, sha: #{revision[0, 7]})") do
|
32
|
-
StatsD.increment(
|
33
|
-
StatsD.measure(
|
34
|
-
StatsD.gauge(
|
35
|
-
StatsD.set(
|
33
|
+
StatsD.increment("StatsD.increment", 10)
|
34
|
+
StatsD.measure("StatsD.measure") { 1 + 1 }
|
35
|
+
StatsD.gauge("StatsD.gauge", 12.0, tags: ["foo:bar", "quc"])
|
36
|
+
StatsD.set("StatsD.set", "value", tags: { foo: "bar", baz: "quc" })
|
36
37
|
if StatsD.singleton_client.datagram_builder_class == StatsD::Instrument::DogStatsDDatagramBuilder
|
37
|
-
StatsD.event(
|
38
|
+
StatsD.event("StasD.event", "12345")
|
38
39
|
StatsD.service_check("StatsD.service_check", "ok")
|
39
40
|
end
|
40
41
|
end
|
@@ -50,7 +51,7 @@ if report.entries.length == 1
|
|
50
51
|
puts
|
51
52
|
puts "To compare the performance of this revision against another revision (e.g. master),"
|
52
53
|
puts "check out a different branch and run this benchmark script again."
|
53
|
-
elsif ENV[
|
54
|
+
elsif ENV["KEEP_RESULTS"]
|
54
55
|
puts
|
55
56
|
puts "The intermediate results have been stored in #{intermediate_results_filename}"
|
56
57
|
else
|
data/bin/rake
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rake' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load(Gem.bin_path("rake", "rake"))
|
data/bin/rubocop
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rubocop' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load(Gem.bin_path("rubocop", "rubocop"))
|
data/lib/statsd-instrument.rb
CHANGED
data/lib/statsd/instrument.rb
CHANGED
@@ -1,89 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "socket"
|
4
|
+
require "logger"
|
5
|
+
require "forwardable"
|
6
6
|
|
7
|
-
# The StatsD module contains low-level metrics for collecting metrics and
|
7
|
+
# The `StatsD` module contains low-level metrics for collecting metrics and
|
8
|
+
# sending them to the backend.
|
8
9
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# @note This new Client implementation is intended to become the new default in
|
13
|
-
# the next major release of this library. While this class may already be functional,
|
14
|
-
# we provide no guarantees about the API and the behavior may change.
|
15
|
-
#
|
16
|
-
# @!attribute backend
|
17
|
-
# The backend that is being used to emit the metrics.
|
18
|
-
# @return [StatsD::Instrument::Backend] the currently active backend. If there is no active backend
|
19
|
-
# yet, it will call {StatsD::Instrument::Environment#default_backend} to obtain a
|
20
|
-
# default backend for the environment.
|
21
|
-
# @see StatsD::Instrument::Environment#default_backend
|
22
|
-
# @deprecated
|
23
|
-
#
|
24
|
-
# @!attribute prefix
|
25
|
-
# The prefix to apply to metric names. This can be useful to group all the metrics
|
26
|
-
# for an application in a shared StatsD server.
|
27
|
-
#
|
28
|
-
# When using a prefix a dot will be included automatically to separate the prefix
|
29
|
-
# from the metric name.
|
30
|
-
#
|
31
|
-
# @return [String, nil] The prefix, or <tt>nil</tt> when no prefix is used
|
32
|
-
# @see StatsD::Instrument::Metric#name
|
33
|
-
# @deprecated
|
34
|
-
#
|
35
|
-
# @!attribute default_sample_rate
|
36
|
-
# The sample rate to use if the sample rate is unspecified for a metric call.
|
37
|
-
# @return [Float] Default is 1.0.
|
38
|
-
# @deprecated
|
39
|
-
#
|
40
|
-
# @!attribute logger
|
41
|
-
# The logger to use in case of any errors. The logger is also used as default logger
|
42
|
-
# for the LoggerBackend (although this can be overwritten).
|
43
|
-
# @see StatsD::Instrument::Backends::LoggerBackend
|
44
|
-
# @return [Logger]
|
45
|
-
#
|
46
|
-
# @!attribute default_tags
|
47
|
-
# The tags to apply to all metrics.
|
48
|
-
# @return [Array<String>, Hash<String, String>, nil] The default tags, or <tt>nil</tt> when no default tags is used
|
49
|
-
# @deprecated
|
50
|
-
#
|
51
|
-
# @!attribute singleton_client
|
52
|
-
# @nodoc
|
53
|
-
# @deprecated
|
54
|
-
#
|
55
|
-
# @!method measure(name, value = nil, sample_rate: nil, tags: nil, &block)
|
56
|
-
# (see StatsD::Instrument::Client#measure)
|
57
|
-
#
|
58
|
-
# @!method increment(name, value = 1, sample_rate: nil, tags: nil)
|
59
|
-
# (see StatsD::Instrument::Client#increment)
|
60
|
-
#
|
61
|
-
# @!method gauge(name, value, sample_rate: nil, tags: nil)
|
62
|
-
# (see StatsD::Instrument::Client#gauge)
|
63
|
-
#
|
64
|
-
# @!method set(name, value, sample_rate: nil, tags: nil)
|
65
|
-
# (see StatsD::Instrument::Client#set)
|
66
|
-
#
|
67
|
-
# @!method histogram(name, value, sample_rate: nil, tags: nil)
|
68
|
-
# (see StatsD::Instrument::Client#histogram)
|
69
|
-
#
|
70
|
-
# @!method distribution(name, value = nil, sample_rate: nil, tags: nil, &block)
|
71
|
-
# (see StatsD::Instrument::Client#distribution)
|
72
|
-
#
|
73
|
-
# @!method key_value(name, value)
|
74
|
-
# (see StatsD::Instrument::Client#key_value)
|
75
|
-
#
|
76
|
-
# @!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
|
77
|
-
# (see StatsD::Instrument::Client#event)
|
78
|
-
#
|
79
|
-
# @!method service_check(name, status, tags: nil, hostname: nil, timestamp: nil, message: nil)
|
80
|
-
# (see StatsD::Instrument::Client#service_check)
|
81
|
-
#
|
82
|
-
# @see StatsD::Instrument <tt>StatsD::Instrument</tt> contains module to instrument
|
10
|
+
# @see .singleton_client Metric method calls on the `StatsD` singleton will
|
11
|
+
# be handled by the client assigned to `StatsD.singleton_client`.
|
12
|
+
# @see StatsD::Instrument `StatsD::Instrument` contains module to instrument
|
83
13
|
# existing methods with StatsD metrics
|
84
14
|
module StatsD
|
85
|
-
extend self
|
86
|
-
|
87
15
|
# The StatsD::Instrument module provides metaprogramming methods to instrument your methods with
|
88
16
|
# StatsD metrics. E.g., you can create counters on how often a method is called, how often it is
|
89
17
|
# successful, the duration of the methods call, etc.
|
@@ -99,9 +27,11 @@ module StatsD
|
|
99
27
|
end
|
100
28
|
end
|
101
29
|
|
30
|
+
# Generates a metric name for an instrumented method.
|
102
31
|
# @private
|
32
|
+
# @return [String]
|
103
33
|
def self.generate_metric_name(name, callee, *args)
|
104
|
-
name.respond_to?(:call) ? name.call(callee, args).gsub(
|
34
|
+
name.respond_to?(:call) ? name.call(callee, args).gsub("::", ".") : name.gsub("::", ".")
|
105
35
|
end
|
106
36
|
|
107
37
|
# Even though this method is considered private, and is no longer used internally,
|
@@ -183,26 +113,24 @@ module StatsD
|
|
183
113
|
def statsd_count_success(method, name, sample_rate: nil, tags: nil, no_prefix: false, client: nil)
|
184
114
|
add_to_method(method, name, :count_success) do
|
185
115
|
define_method(method) do |*args, &block|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
truthiness = false
|
197
|
-
end
|
116
|
+
truthiness = result = super(*args, &block)
|
117
|
+
rescue
|
118
|
+
truthiness = false
|
119
|
+
raise
|
120
|
+
else
|
121
|
+
if block_given?
|
122
|
+
begin
|
123
|
+
truthiness = yield(result)
|
124
|
+
rescue
|
125
|
+
truthiness = false
|
198
126
|
end
|
199
|
-
result
|
200
|
-
ensure
|
201
|
-
client ||= StatsD.singleton_client
|
202
|
-
suffix = truthiness == false ? 'failure' : 'success'
|
203
|
-
key = StatsD::Instrument.generate_metric_name(name, self, *args)
|
204
|
-
client.increment("#{key}.#{suffix}", sample_rate: sample_rate, tags: tags, no_prefix: no_prefix)
|
205
127
|
end
|
128
|
+
result
|
129
|
+
ensure
|
130
|
+
client ||= StatsD.singleton_client
|
131
|
+
suffix = truthiness == false ? "failure" : "success"
|
132
|
+
key = StatsD::Instrument.generate_metric_name(name, self, *args)
|
133
|
+
client.increment("#{key}.#{suffix}", sample_rate: sample_rate, tags: tags, no_prefix: no_prefix)
|
206
134
|
end
|
207
135
|
end
|
208
136
|
end
|
@@ -222,27 +150,25 @@ module StatsD
|
|
222
150
|
def statsd_count_if(method, name, sample_rate: nil, tags: nil, no_prefix: false, client: nil)
|
223
151
|
add_to_method(method, name, :count_if) do
|
224
152
|
define_method(method) do |*args, &block|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
truthiness = false
|
236
|
-
end
|
237
|
-
end
|
238
|
-
result
|
239
|
-
ensure
|
240
|
-
if truthiness
|
241
|
-
client ||= StatsD.singleton_client
|
242
|
-
key = StatsD::Instrument.generate_metric_name(name, self, *args)
|
243
|
-
client.increment(key, sample_rate: sample_rate, tags: tags, no_prefix: no_prefix)
|
153
|
+
truthiness = result = super(*args, &block)
|
154
|
+
rescue
|
155
|
+
truthiness = false
|
156
|
+
raise
|
157
|
+
else
|
158
|
+
if block_given?
|
159
|
+
begin
|
160
|
+
truthiness = yield(result)
|
161
|
+
rescue
|
162
|
+
truthiness = false
|
244
163
|
end
|
245
164
|
end
|
165
|
+
result
|
166
|
+
ensure
|
167
|
+
if truthiness
|
168
|
+
client ||= StatsD.singleton_client
|
169
|
+
key = StatsD::Instrument.generate_metric_name(name, self, *args)
|
170
|
+
client.increment(key, sample_rate: sample_rate, tags: tags, no_prefix: no_prefix)
|
171
|
+
end
|
246
172
|
end
|
247
173
|
end
|
248
174
|
end
|
@@ -345,6 +271,9 @@ module StatsD
|
|
345
271
|
|
346
272
|
instrumentation_module.module_eval(&block)
|
347
273
|
instrumentation_module.send(method_scope, method)
|
274
|
+
if instrumentation_module.respond_to?(:ruby2_keywords, true)
|
275
|
+
instrumentation_module.send(:ruby2_keywords, method)
|
276
|
+
end
|
348
277
|
prepend(instrumentation_module) unless self < instrumentation_module
|
349
278
|
end
|
350
279
|
|
@@ -363,35 +292,73 @@ module StatsD
|
|
363
292
|
end
|
364
293
|
end
|
365
294
|
|
366
|
-
|
367
|
-
|
295
|
+
class << self
|
296
|
+
extend Forwardable
|
368
297
|
|
369
|
-
|
298
|
+
# The logger to use in case of any errors.
|
299
|
+
#
|
300
|
+
# @return [Logger]
|
301
|
+
# @see StatsD::Instrument::LogSink
|
302
|
+
attr_accessor :logger
|
370
303
|
|
371
|
-
|
372
|
-
|
373
|
-
|
304
|
+
# The StatsD client that handles method calls on the StatsD singleton.
|
305
|
+
#
|
306
|
+
# E.g. a call to `StatsD.increment` will be handled by this client.
|
307
|
+
#
|
308
|
+
# @return [StatsD::Instrument::Client]
|
309
|
+
attr_writer :singleton_client
|
374
310
|
|
375
|
-
|
376
|
-
|
377
|
-
|
311
|
+
# The StatsD client that handles method calls on the StatsD singleton
|
312
|
+
# @return [StatsD::Instrument::Client]
|
313
|
+
def singleton_client
|
314
|
+
@singleton_client ||= StatsD::Instrument::Environment.current.client
|
315
|
+
end
|
316
|
+
|
317
|
+
# @!method measure(name, value = nil, sample_rate: nil, tags: nil, &block)
|
318
|
+
# (see StatsD::Instrument::Client#measure)
|
319
|
+
#
|
320
|
+
# @!method increment(name, value = 1, sample_rate: nil, tags: nil)
|
321
|
+
# (see StatsD::Instrument::Client#increment)
|
322
|
+
#
|
323
|
+
# @!method gauge(name, value, sample_rate: nil, tags: nil)
|
324
|
+
# (see StatsD::Instrument::Client#gauge)
|
325
|
+
#
|
326
|
+
# @!method set(name, value, sample_rate: nil, tags: nil)
|
327
|
+
# (see StatsD::Instrument::Client#set)
|
328
|
+
#
|
329
|
+
# @!method histogram(name, value, sample_rate: nil, tags: nil)
|
330
|
+
# (see StatsD::Instrument::Client#histogram)
|
331
|
+
#
|
332
|
+
# @!method distribution(name, value = nil, sample_rate: nil, tags: nil, &block)
|
333
|
+
# (see StatsD::Instrument::Client#distribution)
|
334
|
+
#
|
335
|
+
# @!method event(title, text, tags: nil, hostname: nil, timestamp: nil, aggregation_key: nil, priority: nil, source_type_name: nil, alert_type: nil) # rubocop:disable Layout/LineLength
|
336
|
+
# (see StatsD::Instrument::Client#event)
|
337
|
+
#
|
338
|
+
# @!method service_check(name, status, tags: nil, hostname: nil, timestamp: nil, message: nil)
|
339
|
+
# (see StatsD::Instrument::Client#service_check)
|
340
|
+
|
341
|
+
def_delegators :singleton_client, :increment, :gauge, :set, :measure,
|
342
|
+
:histogram, :distribution, :event, :service_check
|
343
|
+
end
|
378
344
|
end
|
379
345
|
|
380
|
-
require
|
381
|
-
require
|
382
|
-
require
|
383
|
-
require
|
384
|
-
require
|
385
|
-
require
|
386
|
-
require
|
387
|
-
require
|
388
|
-
require
|
389
|
-
require
|
390
|
-
require
|
391
|
-
require
|
392
|
-
require
|
393
|
-
require
|
394
|
-
require
|
395
|
-
require
|
396
|
-
require
|
397
|
-
require
|
346
|
+
require "statsd/instrument/version"
|
347
|
+
require "statsd/instrument/client"
|
348
|
+
require "statsd/instrument/datagram"
|
349
|
+
require "statsd/instrument/dogstatsd_datagram"
|
350
|
+
require "statsd/instrument/datagram_builder"
|
351
|
+
require "statsd/instrument/statsd_datagram_builder"
|
352
|
+
require "statsd/instrument/dogstatsd_datagram_builder"
|
353
|
+
require "statsd/instrument/null_sink"
|
354
|
+
require "statsd/instrument/udp_sink"
|
355
|
+
require "statsd/instrument/batched_udp_sink"
|
356
|
+
require "statsd/instrument/capture_sink"
|
357
|
+
require "statsd/instrument/log_sink"
|
358
|
+
require "statsd/instrument/environment"
|
359
|
+
require "statsd/instrument/helpers"
|
360
|
+
require "statsd/instrument/assertions"
|
361
|
+
require "statsd/instrument/expectation"
|
362
|
+
require "statsd/instrument/matchers" if defined?(::RSpec)
|
363
|
+
require "statsd/instrument/railtie" if defined?(::Rails::Railtie)
|
364
|
+
require "statsd/instrument/strict" if ENV["STATSD_STRICT_MODE"]
|