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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/lint.yml +22 -0
  3. data/.github/workflows/tests.yml +31 -0
  4. data/.rubocop.yml +3 -13
  5. data/CHANGELOG.md +50 -0
  6. data/Gemfile +8 -2
  7. data/README.md +6 -3
  8. data/Rakefile +7 -7
  9. data/benchmark/send-metrics-to-dev-null-log +12 -11
  10. data/benchmark/send-metrics-to-local-udp-receiver +16 -15
  11. data/bin/rake +29 -0
  12. data/bin/rubocop +29 -0
  13. data/lib/statsd-instrument.rb +1 -1
  14. data/lib/statsd/instrument.rb +112 -145
  15. data/lib/statsd/instrument/assertions.rb +200 -208
  16. data/lib/statsd/instrument/batched_udp_sink.rb +154 -0
  17. data/lib/statsd/instrument/capture_sink.rb +23 -19
  18. data/lib/statsd/instrument/client.rb +410 -306
  19. data/lib/statsd/instrument/datagram.rb +69 -65
  20. data/lib/statsd/instrument/datagram_builder.rb +81 -77
  21. data/lib/statsd/instrument/dogstatsd_datagram.rb +76 -72
  22. data/lib/statsd/instrument/dogstatsd_datagram_builder.rb +68 -64
  23. data/lib/statsd/instrument/environment.rb +88 -77
  24. data/lib/statsd/instrument/expectation.rb +96 -96
  25. data/lib/statsd/instrument/helpers.rb +11 -7
  26. data/lib/statsd/instrument/log_sink.rb +20 -16
  27. data/lib/statsd/instrument/matchers.rb +93 -74
  28. data/lib/statsd/instrument/null_sink.rb +12 -8
  29. data/lib/statsd/instrument/railtie.rb +11 -7
  30. data/lib/statsd/instrument/rubocop.rb +8 -8
  31. data/lib/statsd/instrument/rubocop/measure_as_dist_argument.rb +1 -1
  32. data/lib/statsd/instrument/rubocop/metaprogramming_positional_arguments.rb +2 -2
  33. data/lib/statsd/instrument/rubocop/metric_prefix_argument.rb +1 -1
  34. data/lib/statsd/instrument/rubocop/metric_return_value.rb +2 -2
  35. data/lib/statsd/instrument/rubocop/metric_value_keyword_argument.rb +1 -1
  36. data/lib/statsd/instrument/rubocop/positional_arguments.rb +4 -4
  37. data/lib/statsd/instrument/rubocop/singleton_configuration.rb +1 -1
  38. data/lib/statsd/instrument/rubocop/splat_arguments.rb +2 -2
  39. data/lib/statsd/instrument/statsd_datagram_builder.rb +12 -8
  40. data/lib/statsd/instrument/strict.rb +1 -6
  41. data/lib/statsd/instrument/udp_sink.rb +49 -47
  42. data/lib/statsd/instrument/version.rb +1 -1
  43. data/statsd-instrument.gemspec +4 -8
  44. data/test/assertions_test.rb +205 -161
  45. data/test/benchmark/clock_gettime.rb +1 -1
  46. data/test/benchmark/default_tags.rb +9 -9
  47. data/test/benchmark/metrics.rb +8 -8
  48. data/test/benchmark/tags.rb +4 -4
  49. data/test/capture_sink_test.rb +14 -14
  50. data/test/client_test.rb +96 -96
  51. data/test/datagram_builder_test.rb +55 -55
  52. data/test/datagram_test.rb +5 -5
  53. data/test/dogstatsd_datagram_builder_test.rb +37 -37
  54. data/test/environment_test.rb +30 -21
  55. data/test/helpers/rubocop_helper.rb +12 -9
  56. data/test/helpers_test.rb +15 -15
  57. data/test/integration_test.rb +7 -7
  58. data/test/log_sink_test.rb +4 -4
  59. data/test/matchers_test.rb +54 -54
  60. data/test/null_sink_test.rb +4 -4
  61. data/test/rubocop/measure_as_dist_argument_test.rb +2 -2
  62. data/test/rubocop/metaprogramming_positional_arguments_test.rb +2 -2
  63. data/test/rubocop/metric_prefix_argument_test.rb +2 -2
  64. data/test/rubocop/metric_return_value_test.rb +6 -6
  65. data/test/rubocop/metric_value_keyword_argument_test.rb +3 -3
  66. data/test/rubocop/positional_arguments_test.rb +12 -12
  67. data/test/rubocop/singleton_configuration_test.rb +8 -8
  68. data/test/rubocop/splat_arguments_test.rb +2 -2
  69. data/test/statsd_datagram_builder_test.rb +6 -6
  70. data/test/statsd_instrumentation_test.rb +122 -122
  71. data/test/statsd_test.rb +69 -67
  72. data/test/test_helper.rb +19 -10
  73. data/test/udp_sink_test.rb +122 -50
  74. metadata +12 -92
  75. data/.github/workflows/ci.yml +0 -56
  76. 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: ec03c4f1452d2b5bca53c83faf68955d8095ad75ed0484103091789764e02233
4
- data.tar.gz: 6037bd8e41bfc3b7d726c9f1120d10ce202a206dbfdd1e3368d550ed90f0bcc9
3
+ metadata.gz: 3a481f6cd0897b93e3e992fc5315b496c033a98a8cccd02948146cb638e0a6b2
4
+ data.tar.gz: ab454f2fecc89aa662ac2f16632fe2fc3c4e4b2b102d3c4058642e5706bf64c1
5
5
  SHA512:
6
- metadata.gz: f282acf3e05dac8b66eddc5b2fb8e11501543bc2125c92d7154835bd832304d706e35dc831c7c4ea879f05f4f1b0568b67bd19e4a657ef45c8272c81aa29b0af
7
- data.tar.gz: 65546513cc2e0fb9ea06ab220d63102ba354963397c96ae8d81983d3b9178ca8ca03ed1536c29a8d2938b125e7644a37cdc40c0707d9eab1ccca2298bd3b6ad1
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
- inherit_from:
2
- - https://shopify.github.io/ruby-style-guide/rubocop.yml
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.3
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
- # benchmark-ips save! method is not part of a released version yet.
7
- gem 'benchmark-ips', git: 'https://github.com/evanphx/benchmark-ips', branch: 'master'
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: `statsd`). The StatsD implementation you
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', sample_rate: 1.0)
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 'bundler/gem_tasks'
4
- require 'rake/testtask'
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
5
 
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']
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 default: :test
12
+ task(default: :test)
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'bundler/setup'
5
- require 'benchmark/ips'
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
- 'master'
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['ENV'] = "development"
19
- require 'statsd-instrument'
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('StatsD.increment', 10, sample_rate: 15)
25
- StatsD.measure('StatsD.measure') { 1 + 1 }
26
- StatsD.gauge('StatsD.gauge', 12.0, tags: ["foo:bar", "quc"])
27
- StatsD.set('StatsD.set', 'value', tags: { foo: 'bar', baz: 'quc' })
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('StasD.event', "12345")
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['KEEP_RESULTS']
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 'bundler/setup'
5
- require 'benchmark/ips'
6
- require 'socket'
7
- require 'statsd-instrument'
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
- 'master'
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('localhost', 0)
23
+ receiver.bind("localhost", 0)
23
24
 
24
25
  StatsD.singleton_client = StatsD::Instrument::Environment.new(
25
- 'STATSD_ADDR' => "#{receiver.addr[2]}:#{receiver.addr[1]}",
26
- 'STATSD_IMPLEMENTATION' => 'dogstatsd',
27
- 'STATSD_ENV' => 'production',
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('StatsD.increment', 10)
33
- StatsD.measure('StatsD.measure') { 1 + 1 }
34
- StatsD.gauge('StatsD.gauge', 12.0, tags: ["foo:bar", "quc"])
35
- StatsD.set('StatsD.set', 'value', tags: { foo: 'bar', baz: 'quc' })
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('StasD.event', "12345")
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['KEEP_RESULTS']
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"))
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'statsd/instrument'
3
+ require "statsd/instrument"
@@ -1,89 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'socket'
4
- require 'logger'
5
- require 'forwardable'
3
+ require "socket"
4
+ require "logger"
5
+ require "forwardable"
6
6
 
7
- # The StatsD module contains low-level metrics for collecting metrics and sending them to the backend.
7
+ # The `StatsD` module contains low-level metrics for collecting metrics and
8
+ # sending them to the backend.
8
9
  #
9
- # @!attribute client
10
- # @return [StatsD::Instrument::Backend] The client that will handle singleton method calls in the next
11
- # major version of this library.
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('::', '.') : name.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
- begin
187
- truthiness = result = super(*args, &block)
188
- rescue
189
- truthiness = false
190
- raise
191
- else
192
- if block_given?
193
- begin
194
- truthiness = yield(result)
195
- rescue
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
- begin
226
- truthiness = result = super(*args, &block)
227
- rescue
228
- truthiness = false
229
- raise
230
- else
231
- if block_given?
232
- begin
233
- truthiness = yield(result)
234
- rescue
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
- attr_accessor :logger
367
- attr_writer :singleton_client
295
+ class << self
296
+ extend Forwardable
368
297
 
369
- extend Forwardable
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
- def singleton_client
372
- @singleton_client ||= StatsD::Instrument::Environment.current.client
373
- end
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
- # Singleton methods will be delegated to the singleton client.
376
- def_delegators :singleton_client, :increment, :gauge, :set, :measure,
377
- :histogram, :distribution, :key_value, :event, :service_check
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 'statsd/instrument/version'
381
- require 'statsd/instrument/client'
382
- require 'statsd/instrument/datagram'
383
- require 'statsd/instrument/dogstatsd_datagram'
384
- require 'statsd/instrument/datagram_builder'
385
- require 'statsd/instrument/statsd_datagram_builder'
386
- require 'statsd/instrument/dogstatsd_datagram_builder'
387
- require 'statsd/instrument/null_sink'
388
- require 'statsd/instrument/udp_sink'
389
- require 'statsd/instrument/capture_sink'
390
- require 'statsd/instrument/log_sink'
391
- require 'statsd/instrument/environment'
392
- require 'statsd/instrument/helpers'
393
- require 'statsd/instrument/assertions'
394
- require 'statsd/instrument/expectation'
395
- require 'statsd/instrument/matchers' if defined?(::RSpec)
396
- require 'statsd/instrument/railtie' if defined?(::Rails::Railtie)
397
- require 'statsd/instrument/strict' if ENV['STATSD_STRICT_MODE']
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"]