class Statsd::Batch

Batch: A batching statsd proxy

@example Batch a set of instruments using Batch and manual flush:

$statsd = Statsd.new 'localhost', 8125
batch = Statsd::Batch.new($statsd)
batch.increment 'garets'
batch.timing 'glork', 320
batch.gauge 'bork', 100
batch.flush

Batch is a subclass of Statsd, but with a constructor that proxies to a normal Statsd instance. It has it's own batch_size and namespace parameters (that inherit defaults from the supplied Statsd instance). It is recommended that some care is taken if setting very large batch sizes. If the batch size exceeds the allowed packet size for UDP on your network, communication troubles may occur and data will be lost.

Attributes

batch_byte_size[RW]
batch_size[RW]
flush_interval[RW]

Public Class Methods

new(statsd) click to toggle source

@param [Statsd] statsd requires a configured Statsd instance

# File lib/statsd.rb, line 61
def initialize(statsd)
  @statsd = statsd
  @batch_size = statsd.batch_size
  @batch_byte_size = statsd.batch_byte_size
  @flush_interval = statsd.flush_interval
  @backlog = []
  @backlog_bytesize = 0
  @last_flush = Time.now
end

Public Instance Methods

easy() { |self| ... } click to toggle source

@yield [Batch] yields itself

A convenience method to ensure that data is not lost in the event of an exception being thrown. Batches will be transmitted on the parent socket as soon as the batch is full, and when the block finishes.

# File lib/statsd.rb, line 76
def easy
  yield self
ensure
  flush
end
flush() click to toggle source
# File lib/statsd.rb, line 82
def flush
  unless @backlog.empty?
    @statsd.send_to_socket @backlog.join("\n")
    @backlog.clear
    @backlog_bytesize = 0
    @last_flush = Time.now
  end
end

Protected Instance Methods

last_flush_seconds_ago() click to toggle source
# File lib/statsd.rb, line 112
def last_flush_seconds_ago
  Time.now - @last_flush
end
send_to_socket(message) click to toggle source
# File lib/statsd.rb, line 93
def send_to_socket(message)
  # this message wouldn't fit; flush the queue. note that we don't have
  # to do this for message based flushing, because we're incrementing by
  # one, so the post-queue check will always catch it
  if (@batch_byte_size && @backlog_bytesize + message.bytesize + 1 > @batch_byte_size) ||
      (@flush_interval && last_flush_seconds_ago >= @flush_interval)
    flush
  end
  @backlog << message
  @backlog_bytesize += message.bytesize
  # skip the interleaved newline for the first item
  @backlog_bytesize += 1 if @backlog.length != 1
  # if we're precisely full now, flush
  if (@batch_size && @backlog.size == @batch_size) ||
      (@batch_byte_size && @backlog_bytesize == @batch_byte_size)
    flush
  end
end