statsd-instrument 2.9.2 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +16 -23
  3. data/.rubocop.yml +3 -13
  4. data/CHANGELOG.md +33 -0
  5. data/Gemfile +8 -0
  6. data/README.md +3 -3
  7. data/Rakefile +1 -1
  8. data/benchmark/send-metrics-to-dev-null-log +5 -2
  9. data/benchmark/send-metrics-to-local-udp-receiver +8 -6
  10. data/bin/rake +29 -0
  11. data/bin/rubocop +29 -0
  12. data/lib/statsd/instrument.rb +80 -144
  13. data/lib/statsd/instrument/assertions.rb +200 -208
  14. data/lib/statsd/instrument/capture_sink.rb +23 -19
  15. data/lib/statsd/instrument/client.rb +414 -320
  16. data/lib/statsd/instrument/datagram.rb +69 -65
  17. data/lib/statsd/instrument/datagram_builder.rb +81 -77
  18. data/lib/statsd/instrument/dogstatsd_datagram.rb +76 -72
  19. data/lib/statsd/instrument/dogstatsd_datagram_builder.rb +68 -64
  20. data/lib/statsd/instrument/environment.rb +79 -98
  21. data/lib/statsd/instrument/expectation.rb +96 -96
  22. data/lib/statsd/instrument/helpers.rb +10 -35
  23. data/lib/statsd/instrument/log_sink.rb +20 -16
  24. data/lib/statsd/instrument/matchers.rb +86 -71
  25. data/lib/statsd/instrument/null_sink.rb +12 -8
  26. data/lib/statsd/instrument/railtie.rb +11 -11
  27. data/lib/statsd/instrument/statsd_datagram_builder.rb +12 -8
  28. data/lib/statsd/instrument/strict.rb +12 -123
  29. data/lib/statsd/instrument/udp_sink.rb +50 -46
  30. data/lib/statsd/instrument/version.rb +1 -1
  31. data/statsd-instrument.gemspec +2 -8
  32. data/test/assertions_test.rb +46 -12
  33. data/test/capture_sink_test.rb +8 -8
  34. data/test/client_test.rb +62 -51
  35. data/test/datagram_builder_test.rb +29 -29
  36. data/test/datagram_test.rb +1 -1
  37. data/test/dogstatsd_datagram_builder_test.rb +28 -28
  38. data/test/environment_test.rb +10 -46
  39. data/test/helpers/rubocop_helper.rb +11 -8
  40. data/test/helpers_test.rb +5 -5
  41. data/test/integration_test.rb +10 -25
  42. data/test/log_sink_test.rb +2 -2
  43. data/test/matchers_test.rb +36 -36
  44. data/test/null_sink_test.rb +2 -2
  45. data/test/rubocop/metric_return_value_test.rb +3 -3
  46. data/test/rubocop/metric_value_keyword_argument_test.rb +1 -1
  47. data/test/rubocop/positional_arguments_test.rb +10 -10
  48. data/test/statsd_instrumentation_test.rb +97 -122
  49. data/test/statsd_test.rb +50 -75
  50. data/test/test_helper.rb +7 -5
  51. data/test/udp_sink_test.rb +8 -8
  52. metadata +7 -125
  53. data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +0 -1027
  54. data/benchmark/datagram-client +0 -40
  55. data/lib/statsd/instrument/backend.rb +0 -18
  56. data/lib/statsd/instrument/backends/capture_backend.rb +0 -32
  57. data/lib/statsd/instrument/backends/logger_backend.rb +0 -20
  58. data/lib/statsd/instrument/backends/null_backend.rb +0 -9
  59. data/lib/statsd/instrument/backends/udp_backend.rb +0 -152
  60. data/lib/statsd/instrument/legacy_client.rb +0 -301
  61. data/lib/statsd/instrument/metric.rb +0 -155
  62. data/test/assertions_on_legacy_client_test.rb +0 -344
  63. data/test/capture_backend_test.rb +0 -26
  64. data/test/compatibility/dogstatsd_datagram_compatibility_test.rb +0 -161
  65. data/test/deprecations_test.rb +0 -139
  66. data/test/logger_backend_test.rb +0 -22
  67. data/test/metric_test.rb +0 -47
  68. data/test/udp_backend_test.rb +0 -228
@@ -1,75 +1,79 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # @note This class is part of the new Client implementation that is intended
4
- # to become the new default in the next major release of this library.
5
- class StatsD::Instrument::DogStatsDDatagramBuilder < StatsD::Instrument::DatagramBuilder
6
- unsupported_datagram_types :kv
3
+ module StatsD
4
+ module Instrument
5
+ # @note This class is part of the new Client implementation that is intended
6
+ # to become the new default in the next major release of this library.
7
+ class DogStatsDDatagramBuilder < StatsD::Instrument::DatagramBuilder
8
+ unsupported_datagram_types :kv
7
9
 
8
- def self.datagram_class
9
- StatsD::Instrument::DogStatsDDatagram
10
- end
10
+ def self.datagram_class
11
+ StatsD::Instrument::DogStatsDDatagram
12
+ end
11
13
 
12
- def latency_metric_type
13
- :d
14
- end
14
+ def latency_metric_type
15
+ :d
16
+ end
15
17
 
16
- # Constricts an event datagram.
17
- #
18
- # @param [String] title Event title.
19
- # @param [String] text Event description. Newlines are allowed.
20
- # @param [Time] timestamp The of the event. If not provided,
21
- # Datadog will interpret it as the current timestamp.
22
- # @param [String] hostname A hostname to associate with the event.
23
- # @param [String] aggregation_key An aggregation key to group events with the same key.
24
- # @param [String] priority Priority of the event. Either "normal" (default) or "low".
25
- # @param [String] source_type_name The source type of the event.
26
- # @param [String] alert_type Either "error", "warning", "info" (default) or "success".
27
- # @param [Array, Hash] tags Tags to associate with the event.
28
- # @return [String] The correctly formatted service check datagram
29
- #
30
- # @see https://docs.datadoghq.com/developers/dogstatsd/datagram_shell/#events
31
- def _e(title, text, timestamp: nil, hostname: nil, aggregation_key: nil, priority: nil,
32
- source_type_name: nil, alert_type: nil, tags: nil)
18
+ # Constricts an event datagram.
19
+ #
20
+ # @param [String] title Event title.
21
+ # @param [String] text Event description. Newlines are allowed.
22
+ # @param [Time] timestamp The of the event. If not provided,
23
+ # Datadog will interpret it as the current timestamp.
24
+ # @param [String] hostname A hostname to associate with the event.
25
+ # @param [String] aggregation_key An aggregation key to group events with the same key.
26
+ # @param [String] priority Priority of the event. Either "normal" (default) or "low".
27
+ # @param [String] source_type_name The source type of the event.
28
+ # @param [String] alert_type Either "error", "warning", "info" (default) or "success".
29
+ # @param [Array, Hash] tags Tags to associate with the event.
30
+ # @return [String] The correctly formatted service check datagram
31
+ #
32
+ # @see https://docs.datadoghq.com/developers/dogstatsd/datagram_shell/#events
33
+ def _e(title, text, timestamp: nil, hostname: nil, aggregation_key: nil, priority: nil,
34
+ source_type_name: nil, alert_type: nil, tags: nil)
33
35
 
34
- escaped_title = "#{@prefix}#{title}".gsub("\n", '\n')
35
- escaped_text = text.gsub("\n", '\n')
36
- tags = normalize_tags(tags) + default_tags
36
+ escaped_title = "#{@prefix}#{title}".gsub("\n", '\n')
37
+ escaped_text = text.gsub("\n", '\n')
38
+ tags = normalize_tags(tags) + default_tags
37
39
 
38
- datagram = +"_e{#{escaped_title.length},#{escaped_text.length}}:#{escaped_title}|#{escaped_text}"
39
- datagram << "|h:#{hostname}" if hostname
40
- datagram << "|d:#{timestamp.to_i}" if timestamp
41
- datagram << "|k:#{aggregation_key}" if aggregation_key
42
- datagram << "|p:#{priority}" if priority
43
- datagram << "|s:#{source_type_name}" if source_type_name
44
- datagram << "|t:#{alert_type}" if alert_type
45
- datagram << "|##{tags.join(',')}" unless tags.empty?
46
- datagram
47
- end
40
+ datagram = +"_e{#{escaped_title.length},#{escaped_text.length}}:#{escaped_title}|#{escaped_text}"
41
+ datagram << "|h:#{hostname}" if hostname
42
+ datagram << "|d:#{timestamp.to_i}" if timestamp
43
+ datagram << "|k:#{aggregation_key}" if aggregation_key
44
+ datagram << "|p:#{priority}" if priority
45
+ datagram << "|s:#{source_type_name}" if source_type_name
46
+ datagram << "|t:#{alert_type}" if alert_type
47
+ datagram << "|##{tags.join(',')}" unless tags.empty?
48
+ datagram
49
+ end
48
50
 
49
- # Constricts a service check datagram.
50
- #
51
- # @param [String] name Name of the service
52
- # @param [Symbol] status Either `:ok`, `:warning`, `:critical` or `:unknown`
53
- # @param [Time] timestamp The moment when the service was checked. If not provided,
54
- # Datadog will interpret it as the current timestamp.
55
- # @param [String] hostname A hostname to associate with the check.
56
- # @param [Array, Hash] tags Tags to associate with the check.
57
- # @param [String] message A message describing the current state of the service check.
58
- # @return [String] The correctly formatted service check datagram
59
- #
60
- # @see https://docs.datadoghq.com/developers/dogstatsd/datagram_shell/#service-checks
61
- def _sc(name, status, timestamp: nil, hostname: nil, tags: nil, message: nil)
62
- status_number = status.is_a?(Integer) ? status : SERVICE_CHECK_STATUS_VALUES.fetch(status.to_sym)
63
- tags = normalize_tags(tags) + default_tags
51
+ # Constricts a service check datagram.
52
+ #
53
+ # @param [String] name Name of the service
54
+ # @param [Symbol] status Either `:ok`, `:warning`, `:critical` or `:unknown`
55
+ # @param [Time] timestamp The moment when the service was checked. If not provided,
56
+ # Datadog will interpret it as the current timestamp.
57
+ # @param [String] hostname A hostname to associate with the check.
58
+ # @param [Array, Hash] tags Tags to associate with the check.
59
+ # @param [String] message A message describing the current state of the service check.
60
+ # @return [String] The correctly formatted service check datagram
61
+ #
62
+ # @see https://docs.datadoghq.com/developers/dogstatsd/datagram_shell/#service-checks
63
+ def _sc(name, status, timestamp: nil, hostname: nil, tags: nil, message: nil)
64
+ status_number = status.is_a?(Integer) ? status : SERVICE_CHECK_STATUS_VALUES.fetch(status.to_sym)
65
+ tags = normalize_tags(tags) + default_tags
64
66
 
65
- datagram = +"_sc|#{@prefix}#{normalize_name(name)}|#{status_number}"
66
- datagram << "|h:#{hostname}" if hostname
67
- datagram << "|d:#{timestamp.to_i}" if timestamp
68
- datagram << "|##{tags.join(',')}" unless tags.empty?
69
- datagram << "|m:#{normalize_name(message)}" if message
70
- datagram
71
- end
67
+ datagram = +"_sc|#{@prefix}#{normalize_name(name)}|#{status_number}"
68
+ datagram << "|h:#{hostname}" if hostname
69
+ datagram << "|d:#{timestamp.to_i}" if timestamp
70
+ datagram << "|##{tags.join(',')}" unless tags.empty?
71
+ datagram << "|m:#{normalize_name(message)}" if message
72
+ datagram
73
+ end
72
74
 
73
- SERVICE_CHECK_STATUS_VALUES = { ok: 0, warning: 1, critical: 2, unknown: 3 }.freeze
74
- private_constant :SERVICE_CHECK_STATUS_VALUES
75
+ SERVICE_CHECK_STATUS_VALUES = { ok: 0, warning: 1, critical: 2, unknown: 3 }.freeze
76
+ private_constant :SERVICE_CHECK_STATUS_VALUES
77
+ end
78
+ end
75
79
  end
@@ -1,116 +1,97 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # The environment module is used to detect, and initialize the environment in
4
- # which this library is active. It will use different default values based on the environment.
5
- class StatsD::Instrument::Environment
6
- class << self
7
- def current
8
- @current ||= StatsD::Instrument::Environment.new(ENV)
9
- end
3
+ module StatsD
4
+ module Instrument
5
+ # The environment module is used to detect, and initialize the environment in
6
+ # which this library is active. It will use different default values based on the environment.
7
+ class Environment
8
+ class << self
9
+ def current
10
+ @current ||= StatsD::Instrument::Environment.new(ENV)
11
+ end
10
12
 
11
- # Detects the current environment, either by asking Rails, or by inspecting environment variables.
12
- #
13
- # - Within a Rails application, <tt>Rails.env</tt> is used.
14
- # - It will check the following environment variables in order: <tt>RAILS_ENV</tt>, <tt>RACK_ENV</tt>, <tt>ENV</tt>.
15
- # - If none of these are set, it will return <tt>development</tt>
16
- #
17
- # @return [String] The detected environment.
18
- def environment
19
- current.environment
20
- end
13
+ # @deprecated For backwards compatibility only. Use {StatsD::Instrument::Environment#environment}
14
+ # through {StatsD::Instrument::Environment.current} instead.
15
+ def environment
16
+ current.environment
17
+ end
21
18
 
22
- # Instantiates a default backend for the current environment.
23
- #
24
- # @return [StatsD::Instrument::Backend]
25
- # @see #environment
26
- def default_backend
27
- case environment
28
- when 'production', 'staging'
29
- StatsD::Instrument::Backends::UDPBackend.new(current.statsd_addr, current.statsd_implementation)
30
- when 'test'
31
- StatsD::Instrument::Backends::NullBackend.new
32
- else
33
- StatsD::Instrument::Backends::LoggerBackend.new(StatsD.logger)
19
+ # Sets default values for sample rate and logger.
20
+ #
21
+ # - Default sample rate is set to the value in the STATSD_SAMPLE_RATE environment variable,
22
+ # or 1.0 otherwise. See {StatsD#default_sample_rate}
23
+ # - {StatsD#logger} is set to a logger that send output to stderr.
24
+ #
25
+ # If you are including this library inside a Rails environment, additional initialization will
26
+ # be done as part of the {StatsD::Instrument::Railtie}.
27
+ #
28
+ # @return [void]
29
+ def setup
30
+ StatsD.logger = Logger.new($stderr)
31
+ end
34
32
  end
35
- end
36
33
 
37
- # Sets default values for sample rate and logger.
38
- #
39
- # - Default sample rate is set to the value in the STATSD_SAMPLE_RATE environment variable,
40
- # or 1.0 otherwise. See {StatsD#default_sample_rate}
41
- # - {StatsD#logger} is set to a logger that send output to stderr.
42
- #
43
- # If you are including this library inside a Rails environment, additional initialization will
44
- # be done as part of the {StatsD::Instrument::Railtie}.
45
- #
46
- # @return [void]
47
- def setup
48
- StatsD.prefix = current.statsd_prefix
49
- StatsD.default_tags = current.statsd_default_tags
50
- StatsD.default_sample_rate = current.statsd_sample_rate
51
- StatsD.logger = Logger.new($stderr)
52
- end
53
- end
54
-
55
- attr_reader :env
34
+ attr_reader :env
56
35
 
57
- def initialize(env)
58
- @env = env
59
- end
36
+ def initialize(env)
37
+ @env = env
38
+ end
60
39
 
61
- # Detects the current environment, either by asking Rails, or by inspecting environment variables.
62
- #
63
- # - Within a Rails application, <tt>Rails.env</tt> is used.
64
- # - It will check the following environment variables in order: <tt>RAILS_ENV</tt>, <tt>RACK_ENV</tt>, <tt>ENV</tt>.
65
- # - If none of these are set, it will return <tt>development</tt>
66
- #
67
- # @return [String] The detected environment.
68
- def environment
69
- if env['STATSD_ENV']
70
- env['STATSD_ENV']
71
- elsif defined?(Rails) && Rails.respond_to?(:env)
72
- Rails.env.to_s
73
- else
74
- env['RAILS_ENV'] || env['RACK_ENV'] || env['ENV'] || 'development'
75
- end
76
- end
40
+ # Detects the current environment, either by asking Rails, or by inspecting environment variables.
41
+ #
42
+ # - It will prefer the value set in <tt>ENV['STATSD_ENV']</tt>
43
+ # - Within a Rails application, <tt>Rails.env</tt> is used.
44
+ # - It will check the following environment variables in order:
45
+ # - <tt>RAILS_ENV</tt>,
46
+ # - <tt>RACK_ENV</tt>
47
+ # - <tt>ENV</tt>.
48
+ # - If none of these are set, it will return <tt>development</tt>
49
+ #
50
+ # @return [String] The detected environment.
51
+ def environment
52
+ if env['STATSD_ENV']
53
+ env['STATSD_ENV']
54
+ elsif defined?(Rails) && Rails.respond_to?(:env)
55
+ Rails.env.to_s
56
+ else
57
+ env['RAILS_ENV'] || env['RACK_ENV'] || env['ENV'] || 'development'
58
+ end
59
+ end
77
60
 
78
- def statsd_implementation
79
- env.fetch('STATSD_IMPLEMENTATION', 'datadog')
80
- end
61
+ def statsd_implementation
62
+ env.fetch('STATSD_IMPLEMENTATION', 'datadog')
63
+ end
81
64
 
82
- def statsd_sample_rate
83
- env.fetch('STATSD_SAMPLE_RATE', 1.0).to_f
84
- end
65
+ def statsd_sample_rate
66
+ env.fetch('STATSD_SAMPLE_RATE', 1.0).to_f
67
+ end
85
68
 
86
- def statsd_prefix
87
- env.fetch('STATSD_PREFIX', nil)
88
- end
69
+ def statsd_prefix
70
+ env.fetch('STATSD_PREFIX', nil)
71
+ end
89
72
 
90
- def statsd_addr
91
- env.fetch('STATSD_ADDR', 'localhost:8125')
92
- end
73
+ def statsd_addr
74
+ env.fetch('STATSD_ADDR', 'localhost:8125')
75
+ end
93
76
 
94
- def statsd_default_tags
95
- env.key?('STATSD_DEFAULT_TAGS') ? env.fetch('STATSD_DEFAULT_TAGS').split(',') : nil
96
- end
77
+ def statsd_default_tags
78
+ env.key?('STATSD_DEFAULT_TAGS') ? env.fetch('STATSD_DEFAULT_TAGS').split(',') : nil
79
+ end
97
80
 
98
- def client
99
- if env.key?('STATSD_USE_NEW_CLIENT')
100
- StatsD::Instrument::Client.from_env(self)
101
- else
102
- StatsD::Instrument::LegacyClient.singleton
103
- end
104
- end
81
+ def client
82
+ StatsD::Instrument::Client.from_env(self)
83
+ end
105
84
 
106
- def default_sink_for_environment
107
- case environment
108
- when 'production', 'staging'
109
- StatsD::Instrument::UDPSink.for_addr(statsd_addr)
110
- when 'test'
111
- StatsD::Instrument::NullSink.new
112
- else
113
- StatsD::Instrument::LogSink.new(StatsD.logger)
85
+ def default_sink_for_environment
86
+ case environment
87
+ when 'production', 'staging'
88
+ StatsD::Instrument::UDPSink.for_addr(statsd_addr)
89
+ when 'test'
90
+ StatsD::Instrument::NullSink.new
91
+ else
92
+ StatsD::Instrument::LogSink.new(StatsD.logger)
93
+ end
94
+ end
114
95
  end
115
96
  end
116
97
  end
@@ -1,119 +1,119 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # @private
4
- class StatsD::Instrument::Expectation
5
- class << self
6
- def increment(name, value = nil, **options)
7
- new(type: :c, name: name, value: value, **options)
8
- end
9
-
10
- def measure(name, value = nil, **options)
11
- new(type: :ms, name: name, value: value, **options)
12
- end
3
+ module StatsD
4
+ module Instrument
5
+ # @private
6
+ class Expectation
7
+ class << self
8
+ def increment(name, value = nil, **options)
9
+ new(type: :c, name: name, value: value, **options)
10
+ end
13
11
 
14
- def gauge(name, value = nil, **options)
15
- new(type: :g, name: name, value: value, **options)
16
- end
12
+ def measure(name, value = nil, **options)
13
+ new(type: :ms, name: name, value: value, **options)
14
+ end
17
15
 
18
- def set(name, value = nil, **options)
19
- new(type: :s, name: name, value: value, **options)
20
- end
16
+ def gauge(name, value = nil, **options)
17
+ new(type: :g, name: name, value: value, **options)
18
+ end
21
19
 
22
- def key_value(name, value = nil, **options)
23
- new(type: :kv, name: name, value: value, **options)
24
- end
20
+ def set(name, value = nil, **options)
21
+ new(type: :s, name: name, value: value, **options)
22
+ end
25
23
 
26
- def distribution(name, value = nil, **options)
27
- new(type: :d, name: name, value: value, **options)
28
- end
24
+ def distribution(name, value = nil, **options)
25
+ new(type: :d, name: name, value: value, **options)
26
+ end
29
27
 
30
- def histogram(name, value = nil, **options)
31
- new(type: :h, name: name, value: value, **options)
32
- end
33
- end
28
+ def histogram(name, value = nil, **options)
29
+ new(type: :h, name: name, value: value, **options)
30
+ end
31
+ end
34
32
 
35
- attr_accessor :times, :type, :name, :value, :sample_rate, :tags
33
+ attr_accessor :times, :type, :name, :value, :sample_rate, :tags
36
34
 
37
- def initialize(client: StatsD.singleton_client, type:, name:, value: nil,
38
- sample_rate: nil, tags: nil, no_prefix: false, times: 1)
35
+ def initialize(client: StatsD.singleton_client, type:, name:, value: nil,
36
+ sample_rate: nil, tags: nil, no_prefix: false, times: 1)
39
37
 
40
- @type = type
41
- @name = client.prefix ? "#{client.prefix}.#{name}" : name unless no_prefix
42
- @value = normalized_value_for_type(type, value) if value
43
- @sample_rate = sample_rate
44
- @tags = normalize_tags(tags)
45
- @times = times
46
- end
38
+ @type = type
39
+ @name = no_prefix || !client.prefix ? name : "#{client.prefix}.#{name}"
40
+ @value = normalized_value_for_type(type, value) if value
41
+ @sample_rate = sample_rate
42
+ @tags = normalize_tags(tags)
43
+ @times = times
44
+ end
47
45
 
48
- def normalized_value_for_type(type, value)
49
- case type
50
- when :c then Integer(value)
51
- when :g, :h, :d, :kv, :ms then Float(value)
52
- when :s then String(value)
53
- else value
54
- end
55
- end
46
+ def normalized_value_for_type(type, value)
47
+ case type
48
+ when :c then Integer(value)
49
+ when :g, :h, :d, :kv, :ms then Float(value)
50
+ when :s then String(value)
51
+ else value
52
+ end
53
+ end
56
54
 
57
- def matches(actual_metric)
58
- return false if sample_rate && sample_rate != actual_metric.sample_rate
59
- return false if value && value != normalized_value_for_type(actual_metric.type, actual_metric.value)
55
+ def matches(actual_metric)
56
+ return false if sample_rate && sample_rate != actual_metric.sample_rate
57
+ return false if value && value != normalized_value_for_type(actual_metric.type, actual_metric.value)
60
58
 
61
- if tags
62
- expected_tags = Set.new(tags)
63
- actual_tags = Set.new(actual_metric.tags)
64
- return expected_tags.subset?(actual_tags)
65
- end
66
- true
67
- end
59
+ if tags
60
+ expected_tags = Set.new(tags)
61
+ actual_tags = Set.new(actual_metric.tags)
62
+ return expected_tags.subset?(actual_tags)
63
+ end
64
+ true
65
+ end
68
66
 
69
- def to_s
70
- str = +"#{name}:#{value || '<anything>'}|#{type}"
71
- str << "|@#{sample_rate}" if sample_rate
72
- str << "|#" << tags.join(',') if tags
73
- str << " (expected #{times} times)" if times > 1
74
- str
75
- end
67
+ def to_s
68
+ str = +"#{name}:#{value || '<anything>'}|#{type}"
69
+ str << "|@#{sample_rate}" if sample_rate
70
+ str << "|#" << tags.join(',') if tags
71
+ str << " (expected #{times} times)" if times > 1
72
+ str
73
+ end
76
74
 
77
- def inspect
78
- "#<StatsD::Instrument::Expectation:\"#{self}\">"
79
- end
75
+ def inspect
76
+ "#<StatsD::Instrument::Expectation:\"#{self}\">"
77
+ end
80
78
 
81
- private
79
+ private
82
80
 
83
- # Needed for normalize_tags
84
- unless Regexp.method_defined?(:match?) # for ruby 2.3
85
- module RubyBackports
86
- refine Regexp do
87
- def match?(str)
88
- (self =~ str) != nil
81
+ # Needed for normalize_tags
82
+ unless Regexp.method_defined?(:match?) # for ruby 2.3
83
+ module RubyBackports
84
+ refine Regexp do
85
+ def match?(str)
86
+ (self =~ str) != nil
87
+ end
88
+ end
89
89
  end
90
+
91
+ using(RubyBackports)
90
92
  end
91
- end
92
93
 
93
- using RubyBackports
94
- end
94
+ # @private
95
+ #
96
+ # Utility function to convert tags to the canonical form.
97
+ #
98
+ # - Tags specified as key value pairs will be converted into an array
99
+ # - Tags are normalized to remove unsupported characters
100
+ #
101
+ # @param tags [Array<String>, Hash<String, String>, nil] Tags specified in any form.
102
+ # @return [Array<String>, nil] the list of tags in canonical form.
103
+ #
104
+ # @todo We should delegate this to thje datagram builder of the current client,
105
+ # to ensure that this logic matches the logic of the active datagram builder.
106
+ def normalize_tags(tags)
107
+ return [] unless tags
108
+ tags = tags.map { |k, v| "#{k}:#{v}" } if tags.is_a?(Hash)
109
+
110
+ # Fast path when no string replacement is needed
111
+ return tags unless tags.any? { |tag| /[|,]/.match?(tag) }
112
+ tags.map { |tag| tag.tr('|,', '') }
113
+ end
114
+ end
95
115
 
96
- # @private
97
- #
98
- # Utility function to convert tags to the canonical form.
99
- #
100
- # - Tags specified as key value pairs will be converted into an array
101
- # - Tags are normalized to remove unsupported characters
102
- #
103
- # @param tags [Array<String>, Hash<String, String>, nil] Tags specified in any form.
104
- # @return [Array<String>, nil] the list of tags in canonical form.
105
- #
106
- # @todo We should delegate this to thje datagram builder of the current client,
107
- # to ensure that this logic matches the logic of the active datagram builder.
108
- def normalize_tags(tags)
109
- return [] unless tags
110
- tags = tags.map { |k, v| "#{k}:#{v}" } if tags.is_a?(Hash)
111
-
112
- # Fast path when no string replacement is needed
113
- return tags unless tags.any? { |tag| /[|,]/.match?(tag) }
114
- tags.map { |tag| tag.tr('|,', '') }
116
+ # For backwards compatibility
117
+ MetricExpectation = Expectation
115
118
  end
116
119
  end
117
-
118
- # For backwards compatibility
119
- StatsD::Instrument::MetricExpectation = StatsD::Instrument::Expectation