class Wavefront::MetricHelper

A helper class for quickly and efficiently sending metrics. This class creates an in-memory buffer to which you can write information using a number of methods. When the buffer is flushed, the points are send to Wavefront using any Writer class. You can currently write gauges, counters, and distributions. This list may grow in the future.

Attributes

buf[R]
dist_writer[R]
opts[R]
writer[R]

Public Class Methods

new(creds, opts = {}) click to toggle source

See Wavefront::Write#initialize for parameters. Additionally,

dist_port: proxy port to write distributions to. If this is
           unset, distributions will not be handled.
# File lib/wavefront-sdk/metric_helper.rb, line 21
def initialize(creds, opts = {})
  @opts        = opts
  @buf         = { gauges: empty_gauges,
                   counters: empty_counters }
  @writer      = setup_writer(creds, opts)
  @dist_writer = setup_dist_writer(creds, opts) if opts[:dist_port]
end

Public Instance Methods

counter(path, value = 1, tags = nil) click to toggle source

These counters are internal, and specific to the SDK. When the buffer is flushed, a single value is sent to Wavefront for each counter. The value sent is a Wavefront delta metric.

@param path [String] metric path @param value [Numeric] value to add to counter @param tags [Hash] point tags

# File lib/wavefront-sdk/metric_helper.rb, line 51
def counter(path, value = 1, tags = nil)
  key = [path, tags]
  @buf[:counters][key] += value
end
counters_to_wf(counters) click to toggle source
# File lib/wavefront-sdk/metric_helper.rb, line 132
def counters_to_wf(counters)
  counters.map do |k, v|
    path, tags = k
    metric = { path: path, value: v, ts: Time.now.utc.to_i }
    metric[:tags] = tags unless tags.nil?
    metric
  end
end
dist(path, interval, value, tags = nil) click to toggle source

These distributions are stored in memory, and sent to Wavefront as native distibutions when the buffer is flushed. @param path [String] metric path @param value [Array, Numeric] value(s) to add to distribution @param interval [Symbol, String] distribution interval, :m,

:h, or :d

@param tags [Hash] point tags

# File lib/wavefront-sdk/metric_helper.rb, line 64
def dist(path, interval, value, tags = nil)
  key = [path, interval, tags]
  @buf[:dists][key] += [value].flatten
end
dist_creds(creds, opts) click to toggle source

@return [Hash] options hash, with :port replaced by :dist_port

# File lib/wavefront-sdk/metric_helper.rb, line 155
def dist_creds(creds, opts)
  creds.dup.tap { |o| o[:port] = opts[:dist_port] }
end
dists_to_wf(dists) click to toggle source
# File lib/wavefront-sdk/metric_helper.rb, line 141
def dists_to_wf(dists)
  dists.map do |k, v|
    path, interval, tags = k
    dist = { path: path,
             value: dist_writer.mk_distribution(v),
             ts: Time.now.utc.to_i,
             interval: interval }
    dist[:tags] = tags unless tags.nil?
    dist
  end
end
flush() click to toggle source

Flush all stored metrics. Though you can flush by individual type, this is the preferred method

# File lib/wavefront-sdk/metric_helper.rb, line 72
def flush
  flush_gauges(buf[:gauges])
  flush_counters(buf[:counters])
  flush_dists(buf[:dists]) if opts.key?(:dist_port)
end
flush_counters(counters) click to toggle source
# File lib/wavefront-sdk/metric_helper.rb, line 94
def flush_counters(counters)
  return if counters.empty?

  to_flush = counters.dup
  @buf[:counters] = empty_counters

  writer.write_delta(counters_to_wf(counters)).tap do |resp|
    replay_counters(to_flush) unless resp.ok?
  end
end
flush_dists(dists) click to toggle source
# File lib/wavefront-sdk/metric_helper.rb, line 105
def flush_dists(dists)
  return if dists.empty?

  to_flush = dists.dup
  @buf[:dists] = empty_dists

  dist_writer.write(dists_to_wf(dists)).tap do |resp|
    replay_dists(to_flush) unless resp.ok?
  end
end
flush_gauges(gauges) click to toggle source

When we are asked to flush the buffers, duplicate the current one, hand it off to the writer class, and clear. If writer tells us there was an error, dump the old buffer into the the new one for the next flush.

# File lib/wavefront-sdk/metric_helper.rb, line 83
def flush_gauges(gauges)
  return if gauges.empty?

  to_flush = gauges.dup
  @buf[:gauges] = empty_gauges

  writer.write(gauges_to_wf(gauges)).tap do |resp|
    @buf[:gauges] += to_flush unless resp.ok?
  end
end
gauge(path, value, tags = nil) click to toggle source

Writes a simple path/metric point, with optional tags, to the buffer. The timestamp is automatically set to the current epoch second. For more control, use Wavefront::Write#write @param path [String] metric path @param value [Numeric] metric value @param tags [Hash] hash of point tags

# File lib/wavefront-sdk/metric_helper.rb, line 37
def gauge(path, value, tags = nil)
  gauge = { path: path, ts: Time.now.to_i, value: value }
  gauge[:tags] = tags if tags
  @buf[:gauges].<< gauge
end
gauges_to_wf(gauges) click to toggle source

These are already Wavefront-format points

# File lib/wavefront-sdk/metric_helper.rb, line 128
def gauges_to_wf(gauges)
  gauges
end
replay_counters(buffer) click to toggle source

Play a failed flush full of counters back into the system

# File lib/wavefront-sdk/metric_helper.rb, line 118
def replay_counters(buffer)
  buffer.each { |k, v| counter(k[0], v, k[1]) }
end
replay_dists(buffer) click to toggle source
# File lib/wavefront-sdk/metric_helper.rb, line 122
def replay_dists(buffer)
  buffer.each { |k, v| dist(k[0], k[1], v, k[2]) }
end

Private Instance Methods

empty_counters() click to toggle source
# File lib/wavefront-sdk/metric_helper.rb, line 165
def empty_counters
  Hash.new(0)
end
empty_dists() click to toggle source
# File lib/wavefront-sdk/metric_helper.rb, line 169
def empty_dists
  Hash.new([])
end
empty_gauges() click to toggle source
# File lib/wavefront-sdk/metric_helper.rb, line 161
def empty_gauges
  []
end
setup_dist_writer(creds, opts) click to toggle source
# File lib/wavefront-sdk/metric_helper.rb, line 177
def setup_dist_writer(creds, opts)
  require_relative 'distribution'
  @buf[:dists] = empty_dists
  Wavefront::Distribution.new(dist_creds(creds, opts), opts)
end
setup_writer(creds, opts) click to toggle source
# File lib/wavefront-sdk/metric_helper.rb, line 173
def setup_writer(creds, opts)
  Wavefront::Write.new(creds, opts)
end