class StatsD::Instrument::Backends::UDPBackend

Constants

DEFAULT_IMPLEMENTATION

Attributes

default_metric_tags[RW]
host[R]
implementation[RW]
port[R]

Public Class Methods

new(server = nil, implementation = nil, default_metric_tags = {}) click to toggle source
Calls superclass method
# File lib/statsd/instrument/backends/udp_backend.rb, line 13
def initialize(server = nil, implementation = nil, default_metric_tags = {})
  super()
  self.server = server || "localhost:8125"
  self.implementation = (implementation || DEFAULT_IMPLEMENTATION).to_sym
  self.default_metric_tags = default_metric_tags
end

Public Instance Methods

collect_metric(metric) click to toggle source
# File lib/statsd/instrument/backends/udp_backend.rb, line 20
def collect_metric(metric)
  unless implementation_supports_metric_type?(metric.type)
    StatsD.logger.warn("[StatsD] Metric type #{metric.type.inspect} not supported on #{implementation} implementation.")
    return false
  end

  if metric.sample_rate < 1.0 && rand > metric.sample_rate
    return false
  end

  write_packet(generate_packet(metric))
end
generate_packet(metric) click to toggle source
# File lib/statsd/instrument/backends/udp_backend.rb, line 65
def generate_packet(metric)
  command = "#{metric.name}:#{metric.value}|#{metric.type}"
  command << "|@#{metric.sample_rate}" if metric.sample_rate < 1 || (implementation == :statsite && metric.sample_rate > 1)
  
  metric_tags_map = self.default_metric_tags.dup
  if metric.tags
    metric.tags.each do |tag|
      key, value = tag.split(":") rescue nil
      metric_tags_map[key] = value
    end
  end
  
  metric_tags = []
  metric_tags_map.each do |k ,v|
    if v.nil?
      metric_tags << "#{k}"
    else
      metric_tags << "#{k}:#{v}"
    end
  end
      
  if metric_tags.size > 0
    if tags_supported?
      if implementation == :datadog
        command << "|##{metric_tags.join(',')}"
      elsif implementation == :collectd
        metric_tags = "[#{metric_tags.join(',')}]"
        command.prepend(metric_tags.gsub(":", "="))
      end
    else
      StatsD.logger.warn("[StatsD] Tags are only supported on Datadog and CollectD implementation.")
    end
  end

  command << "\n" if implementation == :statsite
  command
end
host=(host) click to toggle source
# File lib/statsd/instrument/backends/udp_backend.rb, line 47
def host=(host)
  @host = host
  invalidate_socket
end
implementation_supports_metric_type?(type) click to toggle source
# File lib/statsd/instrument/backends/udp_backend.rb, line 33
def implementation_supports_metric_type?(type)
  case type
    when :h;  implementation == :datadog
    when :kv; implementation == :statsite
    else true
  end
end
invalidate_socket() click to toggle source
# File lib/statsd/instrument/backends/udp_backend.rb, line 120
def invalidate_socket
  @socket = nil
end
port=(port) click to toggle source
# File lib/statsd/instrument/backends/udp_backend.rb, line 52
def port=(port)
  @port = port
  invalidate_socket
end
server=(connection_string) click to toggle source
# File lib/statsd/instrument/backends/udp_backend.rb, line 41
def server=(connection_string)
  self.host, port = connection_string.split(':', 2)
  self.port = port.to_i
  invalidate_socket
end
socket() click to toggle source
# File lib/statsd/instrument/backends/udp_backend.rb, line 57
def socket
  if @socket.nil?
    @socket = UDPSocket.new
    @socket.connect(host, port)
  end
  @socket
end
tags_supported?() click to toggle source
# File lib/statsd/instrument/backends/udp_backend.rb, line 103
def tags_supported?
  implementation == :datadog || implementation == :collectd
end
write_packet(command) click to toggle source
# File lib/statsd/instrument/backends/udp_backend.rb, line 107
def write_packet(command)
  synchronize do
    socket.send(command, 0) > 0
  end
rescue ThreadError => e
  # In cases where a TERM or KILL signal has been sent, and we send stats as
  # part of a signal handler, locks cannot be acquired, so we do our best
  # to try and send the command without a lock.
  socket.send(command, 0) > 0
rescue SocketError, IOError, SystemCallError, Errno::ECONNREFUSED => e
  StatsD.logger.error "[StatsD] #{e.class.name}: #{e.message}"
end