inst_statsd 2.2.0 → 3.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4be1145693a7188f19fe5b64206465eeece936dd9220f9185d1d87e5d895e91c
4
- data.tar.gz: f9f61e0ceb159ff2dabc3b8bda50e9ab5edb299e94d5ab3fed4a664815137697
3
+ metadata.gz: a91fe00f6ca513926589fdd5d3cb3f316e26a6fc5bb5b8ceb1a49ba20f42769f
4
+ data.tar.gz: 82a6dd4759cb55054a20e6c394d19c000b571aabe8df48251f0661fdb86de7ec
5
5
  SHA512:
6
- metadata.gz: c588cc8d11fc48e12808183efc310f98468b2c1e508e98864c8c796d60a22508fec115694dc56f03a311511e17cd221badff168bfaf77dc414581ca829f62a24
7
- data.tar.gz: 7020ddd2f162501c846c280b7e93d4e037479edd7cea347267911607c3da3b578096cb2ef426f0fd86ddeac077b8ded803c7ebe50dd1c501704c9f537ce1e9af
6
+ metadata.gz: dbddd5f2e3069681cd2f6e4b2843d4c7ea123cbaee2a3537cd35ef4b6fffe8f2c90b20b4bf30d5e109967151d29926ad993597575ee6042942587ef7ba75fa43
7
+ data.tar.gz: e5d8af2078d7d320732285b3e071c1c18da70e9aeb0cad060eb589b8b1de592d6093fab0d836c74a9380e10df19e3f46090edb73a14bf1a18e8a2e5d95bf51fa
@@ -2,13 +2,9 @@
2
2
 
3
3
  module InstStatsd
4
4
  class BlockStat
5
+ attr_accessor :stats, :common_key, :short_stat, :tags
5
6
 
6
- attr_accessor :stats
7
- attr_accessor :common_key
8
- attr_accessor :short_stat
9
- attr_accessor :tags
10
-
11
- def initialize(common_key, statsd=InstStatsd::Statsd, tags: {}, short_stat: nil)
7
+ def initialize(common_key, statsd = InstStatsd::Statsd, tags: {}, short_stat: nil)
12
8
  self.common_key = common_key
13
9
  @tags = tags
14
10
  @short_stat = short_stat
@@ -27,17 +23,21 @@ module InstStatsd
27
23
 
28
24
  def exclusive_stats
29
25
  return nil unless @exclusives
30
- stats.map { |key, value| [key, value - (@exclusives[key] || 0.0)] }.to_h
26
+
27
+ stats.to_h { |key, value| [key, value - (@exclusives[key] || 0.0)] }
31
28
  end
32
29
 
33
30
  def report
34
- if common_key
35
- stats.each do |(key, value)|
36
- @statsd.timing("#{common_key}.#{key}", value, tags: @tags, short_stat: "#{@short_stat}.#{key}")
37
- end
38
- exclusive_stats&.each do |(key, value)|
39
- @statsd.timing("#{common_key}.exclusive.#{key}", value, tags: @tags, short_stat: "#{@short_stat}.exclusive.#{key}")
40
- end
31
+ return unless common_key
32
+
33
+ stats.each do |(key, value)|
34
+ @statsd.timing("#{common_key}.#{key}", value, tags: @tags, short_stat: "#{@short_stat}.#{key}")
35
+ end
36
+ exclusive_stats&.each do |(key, value)|
37
+ @statsd.timing("#{common_key}.exclusive.#{key}",
38
+ value,
39
+ tags: @tags,
40
+ short_stat: "#{@short_stat}.exclusive.#{key}")
41
41
  end
42
42
  end
43
43
  end
@@ -1,21 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'benchmark'
3
+ require "benchmark"
4
4
 
5
5
  module InstStatsd
6
6
  class BlockTracking
7
7
  class << self
8
8
  attr_accessor :logger
9
9
 
10
- [:mask, :negative_mask].each do |method|
10
+ %i[mask negative_mask].each do |method|
11
11
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
12
- def #{method}
13
- InstStatsd.settings[:#{method}]
14
- end
15
-
16
- def #{method}=(value)
17
- InstStatsd.settings[:#{method}] = value
18
- end
12
+ def #{method} # def mask
13
+ InstStatsd.settings[:#{method}] # InstStatsd.settings[:mask]
14
+ end # end
15
+ #
16
+ def #{method}=(value) # def mask=(value)
17
+ InstStatsd.settings[:#{method}] = value # InstStatsd.settings[:mask] = value
18
+ end # end
19
19
  RUBY
20
20
  end
21
21
 
@@ -38,12 +38,12 @@ module InstStatsd
38
38
  # to be consistent with ActionPack, measure in milliseconds
39
39
  elapsed *= 1000
40
40
 
41
- block_stat.stats = cookies.map { |(name, cookie)| [name, Counter.counters[name].finalize_count(cookie)] }.to_h
42
- block_stat.stats['total'] = elapsed
41
+ block_stat.stats = cookies.to_h { |(name, cookie)| [name, Counter.counters[name].finalize_count(cookie)] }
42
+ block_stat.stats["total"] = elapsed
43
43
  # we need to make sure to report exclusive timings, even if nobody called us re-entrantly
44
44
  block_stat.subtract_exclusives({}) if category
45
45
  block_stat.report
46
- logger.log(block_stat, "STATSD #{key}") if logger
46
+ logger&.log(block_stat, "STATSD #{key}")
47
47
  # -1 is ourselves; we want to subtract from the block above us
48
48
  stack(category)[-2].subtract_exclusives(block_stat.stats) if category && stack(category)[-2]
49
49
 
@@ -59,6 +59,5 @@ module InstStatsd
59
59
  Thread.current[:stats_block_stack][category] ||= []
60
60
  end
61
61
  end
62
-
63
62
  end
64
63
  end
@@ -12,10 +12,9 @@ module InstStatsd
12
12
  end
13
13
  end
14
14
 
15
- attr_reader :key
16
- attr_reader :blocked_names
15
+ attr_reader :key, :blocked_names
17
16
 
18
- def initialize(key, blocked_names=[], tags: {}, short_stat: nil)
17
+ def initialize(key, blocked_names = [], tags: {}, short_stat: nil)
19
18
  @blocked_names = blocked_names
20
19
  @key = key
21
20
  @tls_key = "statsd.#{key}"
@@ -41,6 +40,5 @@ module InstStatsd
41
40
  def accepted_name?(name)
42
41
  !blocked_names.include?(name)
43
42
  end
44
-
45
43
  end
46
44
  end
@@ -4,41 +4,44 @@ require "active_support"
4
4
 
5
5
  module InstStatsd
6
6
  class DefaultTracking
7
- def self.track_sql
8
- return if @sql_tracker
9
- @sql_tracker = InstStatsd::SqlTracker.new(blocked_names: ['SCHEMA'])
10
- ActiveSupport::Notifications.subscribe(/sql\.active_record/) {|*args| update_sql_count(*args)}
11
- end
7
+ class << self
8
+ def track_sql
9
+ return if @sql_tracker
12
10
 
13
- def self.track_active_record
14
- return if @ar_counter
15
- require 'aroi'
11
+ @sql_tracker = InstStatsd::SqlTracker.new(blocked_names: ["SCHEMA"])
12
+ ActiveSupport::Notifications.subscribe(/sql\.active_record/) { |*args| update_sql_count(*args) }
13
+ end
16
14
 
17
- ::Aroi::Instrumentation.instrument_creation!
18
- @ar_counter = InstStatsd::Counter.new('active_record')
19
- ActiveSupport::Notifications.subscribe(/instance\.active_record/) {|*args| update_active_record_count(*args)}
20
- end
15
+ def track_active_record
16
+ return if @ar_counter
21
17
 
22
- def self.track_cache
23
- return if @cache_read_counter
18
+ require "aroi"
24
19
 
25
- @cache_read_counter = InstStatsd::Counter.new('cache.read')
26
- ActiveSupport::Notifications.subscribe(/cache_read\.active_support/) {|*args| update_cache_read_count(*args)}
27
- end
20
+ ::Aroi::Instrumentation.instrument_creation!
21
+ @ar_counter = InstStatsd::Counter.new("active_record")
22
+ ActiveSupport::Notifications.subscribe(/instance\.active_record/) { |*args| update_active_record_count(*args) }
23
+ end
28
24
 
29
- private
25
+ def track_cache
26
+ return if @cache_read_counter
30
27
 
31
- def self.update_sql_count(_name, _start, _finish, _id, payload)
32
- @sql_tracker.track payload.fetch(:name), payload.fetch(:sql)
33
- end
28
+ @cache_read_counter = InstStatsd::Counter.new("cache.read")
29
+ ActiveSupport::Notifications.subscribe(/cache_read\.active_support/) { |*args| update_cache_read_count(*args) }
30
+ end
34
31
 
35
- def self.update_active_record_count(_name, _start, _finish, _id, payload)
36
- @ar_counter.track payload.fetch(:name, '')
37
- end
32
+ private
38
33
 
39
- def self.update_cache_read_count(_name, _start, _finish, _id, _payload)
40
- @cache_read_counter.track "read"
41
- end
34
+ def update_sql_count(_name, _start, _finish, _id, payload)
35
+ @sql_tracker.track payload.fetch(:name), payload.fetch(:sql)
36
+ end
42
37
 
38
+ def update_active_record_count(_name, _start, _finish, _id, payload)
39
+ @ar_counter.track payload.fetch(:name, "")
40
+ end
41
+
42
+ def update_cache_read_count(_name, _start, _finish, _id, _payload)
43
+ @cache_read_counter.track "read"
44
+ end
45
+ end
43
46
  end
44
47
  end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module InstStatsd
4
+ # Mix-in methods for supporting DataDog events
5
+ # See https://docs.datadoghq.com/service_management/events/
6
+ module Event
7
+ SUPPORTED_TYPES = %i[
8
+ deploy
9
+ feature_disabled
10
+ feature_enabled
11
+ provision
12
+ refresh
13
+ ].freeze
14
+
15
+ def instance; end
16
+ def data_dog?; end
17
+ def dog_tags; end
18
+
19
+ # This end point allows you to post events to the DatDog event stream.
20
+ #
21
+ # @param [String] title Event title
22
+ # @param [String] text Event text. Supports newlines (+\n+)
23
+ # @param [String, nil] :type Can be "deploy", "feature_disabled",
24
+ # "feature_enabled", "provision", or "refresh"
25
+ # @param [Hash] :tags tags to be added to event. Note that the
26
+ # environment, service, and other data are automatically
27
+ # added as tags for you without specifying them here.
28
+ # @param [Integer, String, nil] :date_happened (nil) Assign a timestamp
29
+ # to the event. Default is now when none
30
+ # @param [String, nil] :priority ('normal') Can be "normal" or "low"
31
+ # @param [String, nil] :alert_type ('info') Can be "error", "warning", "info" or "success".
32
+ #
33
+ # @example Report an event:
34
+ # InstStatsd::Statsd.event(
35
+ # "Quiz API Deploy",
36
+ # "<release> was deployed to Quiz API",
37
+ # tags: {foo: 'bar'},
38
+ # type: 'deploy',
39
+ # alert_type: :success
40
+ # )
41
+ def event(title, text, type: nil, tags: {}, alert_type: nil, priority: nil, date_happened: nil)
42
+ return unless instance && data_dog?
43
+
44
+ instance.event(
45
+ title,
46
+ text,
47
+ **{
48
+ alert_type: alert_type,
49
+ priority: priority,
50
+ date_happened: date_happened,
51
+ tags: tags_from_opts(tags, type, dog_tags)
52
+ }.compact
53
+ )
54
+ end
55
+
56
+ private
57
+
58
+ def tags_from_opts(tags, type, dd_tags)
59
+ custom_tags = tags.merge(dd_tags)
60
+ custom_tags[:type] = type if SUPPORTED_TYPES.include? type
61
+ custom_tags.compact
62
+ end
63
+ end
64
+ end
@@ -1,13 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'logger'
3
+ require "logger"
4
4
 
5
5
  module InstStatsd
6
6
  class NullLogger < Logger
7
- def initialize(*args)
7
+ def initialize(*) # rubocop:disable Lint/MissingSuper
8
8
  end
9
9
 
10
- def add(*args, &block)
11
- end
10
+ def add(*); end
12
11
  end
13
12
  end
@@ -2,26 +2,24 @@
2
2
 
3
3
  module InstStatsd
4
4
  class RequestLogger
5
-
6
5
  def initialize(logger)
7
6
  @logger = logger || InstStatsd::NullLogger.new
8
7
  end
9
8
 
10
- def log(request_stat, header=nil)
9
+ def log(request_stat, header = nil)
11
10
  @logger.info(build_log_message(request_stat, header))
12
11
  end
13
12
 
14
- def build_log_message(request_stat, header=nil)
13
+ def build_log_message(request_stat, header = nil)
15
14
  header ||= "STATSD"
16
15
  message = "[#{header}]"
17
16
  request_stat.stats.each do |(name, value)|
18
- message += " (#{name.to_s.gsub('.', '_')}: #{"%.2f" % value})"
17
+ message += " (#{name.to_s.tr(".", "_")}: #{format("%.2f", value)})"
19
18
  end
20
19
  request_stat.exclusive_stats&.each do |(name, value)|
21
- message += " (exclusive_#{name.to_s.gsub('.', '_')}: #{"%.2f" % value})"
20
+ message += " (exclusive_#{name.to_s.tr(".", "_")}: #{format("%.2f", value)})"
22
21
  end
23
22
  message
24
23
  end
25
-
26
24
  end
27
25
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module InstStatsd
4
4
  class RequestStat < BlockStat
5
- def initialize(name, start, finish, id, payload, statsd=InstStatsd::Statsd)
5
+ def initialize(name, start, finish, id, payload, statsd = InstStatsd::Statsd)
6
6
  super(nil, statsd)
7
7
  @name = name
8
8
  @start = start
@@ -15,20 +15,22 @@ module InstStatsd
15
15
  def common_key
16
16
  common_key = super
17
17
  return common_key if common_key
18
+
18
19
  if @statsd.data_dog?
19
20
  self.common_key = "request"
20
21
  self.short_stat = "request"
21
- self.tags[:controller] = controller if controller
22
- self.tags[:action] = action if action
23
- else
24
- self.common_key = "request.#{controller}.#{action}" if controller && action
22
+ tags[:controller] = controller if controller
23
+ tags[:action] = action if action
24
+ tags[:status] = status if status
25
+ elsif controller && action
26
+ self.common_key = "request.#{controller}.#{action}"
25
27
  end
26
28
  end
27
29
 
28
30
  def report
29
- stats['total'] = total
30
- stats['view'] = view_runtime if view_runtime
31
- stats['db'] = db_runtime if db_runtime
31
+ stats["total"] = total
32
+ stats["view"] = view_runtime if view_runtime
33
+ stats["db"] = db_runtime if db_runtime
32
34
  super
33
35
  end
34
36
 
@@ -41,19 +43,29 @@ module InstStatsd
41
43
  end
42
44
 
43
45
  def controller
44
- @payload.fetch(:params, {})['controller']
46
+ @payload.fetch(:params, {})["controller"]
45
47
  end
46
48
 
47
49
  def action
48
- @payload.fetch(:params, {})['action']
50
+ @payload.fetch(:params, {})["action"]
51
+ end
52
+
53
+ def status
54
+ status = @payload.fetch(:status, 0)
55
+ # Only return status group to reduce the number of indexed custom metrics (and cost) of datadog
56
+ return "1XX" if (status >= 100) && (status < 200)
57
+ return "2XX" if (status >= 200) && (status < 300)
58
+ return "3XX" if (status >= 300) && (status < 400)
59
+ return "4XX" if (status >= 400) && (status < 500)
60
+ return "5XX" if (status >= 500) && (status < 600)
61
+
62
+ nil
49
63
  end
50
64
 
51
65
  def total
52
- if (!@finish || !@start)
53
- return 0
54
- end
66
+ return 0 if !@finish || !@start
67
+
55
68
  (@finish - @start) * 1000
56
69
  end
57
-
58
70
  end
59
71
  end
@@ -2,28 +2,29 @@
2
2
 
3
3
  module InstStatsd
4
4
  class RequestTracking
5
+ class << self
6
+ def enable(logger: nil)
7
+ @logger = RequestLogger.new(logger)
8
+ track_timing
9
+ end
5
10
 
6
- def self.enable(logger: nil)
7
- @logger = RequestLogger.new(logger)
8
- track_timing
9
- end
10
-
11
- private
11
+ private
12
12
 
13
- def self.track_timing
14
- ActiveSupport::Notifications.subscribe(/start_processing\.action_controller/, &method(:start_processing))
15
- ActiveSupport::Notifications.subscribe(/process_action\.action_controller/, &method(:finalize_processing))
16
- end
13
+ def track_timing
14
+ ActiveSupport::Notifications.subscribe(/start_processing\.action_controller/, &method(:start_processing))
15
+ ActiveSupport::Notifications.subscribe(/process_action\.action_controller/, &method(:finalize_processing))
16
+ end
17
17
 
18
- def self.start_processing(*_args)
19
- @cookies = Counter.counters.map { |(name, counter)| [name, counter.start] }
20
- end
18
+ def start_processing(*_args)
19
+ @cookies = Counter.counters.map { |(name, counter)| [name, counter.start] }
20
+ end
21
21
 
22
- def self.finalize_processing *args
23
- request_stat = InstStatsd::RequestStat.new(*args)
24
- request_stat.stats = @cookies.map { |(name, cookie)| [name, Counter.counters[name].finalize_count(cookie)] }.to_h
25
- request_stat.report
26
- @logger.log(request_stat)
22
+ def finalize_processing *args
23
+ request_stat = InstStatsd::RequestStat.new(*args)
24
+ request_stat.stats = @cookies.to_h { |(name, cookie)| [name, Counter.counters[name].finalize_count(cookie)] }
25
+ request_stat.report
26
+ @logger.log(request_stat)
27
+ end
27
28
  end
28
29
  end
29
30
  end
@@ -2,27 +2,26 @@
2
2
 
3
3
  module InstStatsd
4
4
  class SqlTracker
5
-
6
5
  attr_reader :blocked_names, :read_counts, :write_counts, :cache_counts
7
6
 
8
- def initialize(opts=nil)
7
+ def initialize(opts = nil)
9
8
  opts ||= {}
10
9
  @blocked_names = opts.fetch(:blocked_names, [])
11
- @read_counts = opts.fetch(:read_counter, InstStatsd::Counter.new('sql.read'))
12
- @write_counts = opts.fetch(:write_counter, InstStatsd::Counter.new('sql.write'))
13
- @cache_counts = opts.fetch(:cache_counter, InstStatsd::Counter.new('sql.cache'))
10
+ @read_counts = opts.fetch(:read_counter, InstStatsd::Counter.new("sql.read"))
11
+ @write_counts = opts.fetch(:write_counter, InstStatsd::Counter.new("sql.write"))
12
+ @cache_counts = opts.fetch(:cache_counter, InstStatsd::Counter.new("sql.cache"))
14
13
  end
15
14
 
16
15
  def start
17
16
  [read_counts, write_counts, cache_counts].map(&:start)
18
17
  end
19
18
 
20
- def track name, sql
19
+ def track(name, sql)
21
20
  return unless sql && accepted_name?(name)
22
21
 
23
- if name.match(/CACHE/)
22
+ if name.include?("CACHE")
24
23
  cache_counts.track name
25
- elsif truncate(sql).match(/SELECT/) || name.match(/LOAD/)
24
+ elsif truncate(sql).include?("SELECT") || name.include?("LOAD")
26
25
  read_counts.track(sql)
27
26
  else
28
27
  write_counts.track(sql)
@@ -43,10 +42,9 @@ module InstStatsd
43
42
  !!(name && !blocked_names.include?(name))
44
43
  end
45
44
 
46
- def truncate(sql, length=15)
47
- sql ||= ''
45
+ def truncate(sql, length = 15)
46
+ sql ||= ""
48
47
  sql.strip[0..length]
49
48
  end
50
-
51
49
  end
52
50
  end
@@ -10,27 +10,33 @@
10
10
  # InstStatsd::Statsd.timing("my_stat", ms)
11
11
  #
12
12
  # Configured in config/statsd.yml, see config/statsd.yml.example
13
- # At least a host needs to be defined for the environment, all other config is optional
13
+ # At least a host needs to be defined for the environment, all other config is
14
+ # optional
14
15
  #
15
16
  # If a namespace is defined in statsd.yml, it'll be prepended to the stat name.
16
- # The hostname of the server will be appended to the stat name, unless `append_hostname: false` is specified in the config.
17
- # So if the namespace is "canvas" and the hostname is "app01", the final stat name of "my_stat" would be "stats.canvas.my_stat.app01"
18
- # (assuming the default statsd/graphite configuration)
17
+ # The hostname of the server will be appended to the stat name, unless
18
+ # `append_hostname: false` is specified in the config.
19
+ # So if the namespace is "canvas" and the hostname is "app01", the final stat
20
+ # name of "my_stat" would be "stats.canvas.my_stat.app01" (assuming the default
21
+ # statsd/graphite configuration)
19
22
  #
20
23
  # If dog_tags is set in statsd.yml, it'll use the tags param and will use
21
24
  # Data Dog instead of Statsd
22
25
  #
23
- # If statsd isn't configured and enabled, then calls to InstStatsd::Statsd.* will do nothing and return nil
26
+ # If statsd isn't configured and enabled, then calls to InstStatsd::Statsd.*
27
+ # will do nothing and return nil
24
28
 
25
29
  module InstStatsd
26
30
  module Statsd
31
+ extend InstStatsd::Event
32
+
27
33
  # replace "." in key names with another character to avoid creating spurious sub-folders in graphite
28
- def self.escape(str, replacement = '_')
29
- str.respond_to?(:gsub) ? str.gsub('.', replacement) : str
34
+ def self.escape(str, replacement = "_")
35
+ str.respond_to?(:gsub) ? str.gsub(".", replacement) : str
30
36
  end
31
37
 
32
38
  def self.hostname
33
- @hostname ||= Socket.gethostname.split('.').first
39
+ @hostname ||= Socket.gethostname.split(".").first
34
40
  end
35
41
 
36
42
  def self.dog_tags
@@ -39,50 +45,49 @@ module InstStatsd
39
45
 
40
46
  %w[increment decrement count gauge timing].each do |method|
41
47
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
42
- def self.#{method}(stat, *args, tags: {}, short_stat: nil)
43
- if self.instance
44
- if Array === stat
45
- stat.each do |st|
46
- self.#{method}(st, *args, tags: {}, short_stat: nil)
47
- end
48
- return
49
- end
50
-
51
- if self.append_hostname?
52
- stat_name = "\#{stat}.\#{hostname}"
53
- else
54
- stat_name = stat.to_s
55
- end
56
-
57
- if data_dog?
58
- tags ||= {}
59
- tags.merge!(dog_tags) if tags.is_a? Hash
60
- tags = convert_tags(tags)
61
- tags << 'host:' unless self.append_hostname?
62
- short_stat ||= stat_name
63
- opts = { tags: tags }
64
- opts[:sample_rate] = args.pop if args.length == 2
65
- args << opts
66
- self.instance.#{method}(short_stat, *args)
67
- else
68
- self.instance.#{method}(stat_name, *args)
69
- end
70
- else
71
- nil
72
- end
73
- end
48
+ def self.#{method}(stat, *args, tags: {}, short_stat: nil) # def self.increment(stat, *args, tags: {}, short_stat: nil)
49
+ if self.instance # if self.instance
50
+ if Array === stat # if Array === stat
51
+ stat.each do |st| # stat.each do |st|
52
+ self.#{method}(st, *args, tags: tags, short_stat: nil) # self.increment(st, *args, tags: tags, short_stat: nil)
53
+ end # end
54
+ return # return
55
+ end # end
56
+ #
57
+ if self.append_hostname? # if self.append_hostname?
58
+ stat_name = "\#{stat}.\#{hostname}" # stat_name = "\#{stat}.\#{hostname}"
59
+ else # else
60
+ stat_name = stat.to_s # stat_name = stat.to_s
61
+ end # end
62
+ #
63
+ if data_dog? # if data_dog?
64
+ tags = tags ? tags.dup : {} # tags ||= {}
65
+ tags.merge!(dog_tags) if tags.is_a? Hash # tags.merge!(dog_tags) if tags.is_a? Hash
66
+ tags = convert_tags(tags) # tags = convert_tags(tags)
67
+ tags << 'host:' unless self.append_hostname? # tags << 'host:' unless self.append_hostname?
68
+ short_stat ||= stat_name # short_stat ||= stat_name
69
+ opts = { tags: tags } # opts = { tags: tags }
70
+ opts[:sample_rate] = args.pop if args.length == 2 # opts[:sample_rate] = args.pop if args.length == 2
71
+ args << opts # args << opts
72
+ self.instance.#{method}(short_stat, *args) # self.instance.increment(short_stat, *args)
73
+ else # else
74
+ self.instance.#{method}(stat_name, *args) # self.instance.increment(stat_name, *args)
75
+ end # end
76
+ else # else
77
+ nil # nil
78
+ end # end
79
+ end # end
74
80
  RUBY
75
81
  end
76
82
 
77
83
  def self.convert_tags(tags)
78
84
  new_tags = []
79
- if tags.is_a? Hash
80
- tags.each do |tag, v|
81
- new_tags << "#{tag}:#{v}"
82
- end
83
- else
84
- return tags
85
+ return tags unless tags.is_a? Hash
86
+
87
+ tags.each do |tag, v|
88
+ new_tags << "#{tag}:#{v}"
85
89
  end
90
+
86
91
  new_tags
87
92
  end
88
93
 
@@ -95,6 +100,7 @@ module InstStatsd
95
100
 
96
101
  def self.batch
97
102
  return yield unless (old_instance = instance)
103
+
98
104
  old_instance.batch do |batch|
99
105
  Thread.current[:inst_statsd] = batch
100
106
  yield
@@ -111,19 +117,24 @@ module InstStatsd
111
117
  statsd_settings = InstStatsd.settings
112
118
  if statsd_settings.key?(:dog_tags)
113
119
  @data_dog = true
114
- host = statsd_settings[:host] || 'localhost'
120
+ host = statsd_settings[:host] || "localhost"
115
121
  port = statsd_settings[:port] || 8125
116
- require 'datadog/statsd'
117
- @statsd = ::Datadog::Statsd.new(host, port, namespace: statsd_settings[:namespace])
118
- self.dog_tags.replace(statsd_settings[:dog_tags] || {})
119
- @append_hostname = !statsd_settings.key?(:append_hostname) || !!statsd_settings[:append_hostname]
122
+ socket_path = statsd_settings[:socket_path]
123
+ require "datadog/statsd"
124
+ @statsd = if socket_path
125
+ Datadog::Statsd.new(socket_path: socket_path, namespace: statsd_settings[:namespace])
126
+ else
127
+ Datadog::Statsd.new(host, port, namespace: statsd_settings[:namespace])
128
+ end
129
+ dog_tags.replace(statsd_settings[:dog_tags] || {})
130
+ @append_hostname = statsd_settings[:append_hostname]
120
131
  elsif statsd_settings && statsd_settings[:host]
121
132
  @statsd = ::Statsd.new(statsd_settings[:host])
122
133
  @statsd.port = statsd_settings[:port] if statsd_settings[:port]
123
134
  @statsd.namespace = statsd_settings[:namespace] if statsd_settings[:namespace]
124
135
  @statsd.batch_size = statsd_settings[:batch_size] if statsd_settings.key?(:batch_size)
125
136
  @statsd.batch_byte_size = statsd_settings[:batch_byte_size] if statsd_settings.key?(:batch_byte_size)
126
- @append_hostname = !statsd_settings.key?(:append_hostname) || !!statsd_settings[:append_hostname]
137
+ @append_hostname = statsd_settings[:append_hostname]
127
138
  else
128
139
  @statsd = nil
129
140
  end