statsd-instrument 3.0.0.pre1 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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"]