Class: Wavefront::MetricHelper

Inherits:
Object
  • Object
show all
Defined in:
lib/wavefront-sdk/metric_helper.rb

Overview

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.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(creds, opts = {}) ⇒ MetricHelper

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

dist_port: proxy port to write distributions to. If this is
           unset, distributions will not be handled.


21
22
23
24
25
26
27
# 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

Instance Attribute Details

#bufObject (readonly)

Returns the value of attribute buf.



15
16
17
# File 'lib/wavefront-sdk/metric_helper.rb', line 15

def buf
  @buf
end

#dist_writerObject (readonly)

Returns the value of attribute dist_writer.



15
16
17
# File 'lib/wavefront-sdk/metric_helper.rb', line 15

def dist_writer
  @dist_writer
end

#optsObject (readonly)

Returns the value of attribute opts.



15
16
17
# File 'lib/wavefront-sdk/metric_helper.rb', line 15

def opts
  @opts
end

#writerObject (readonly)

Returns the value of attribute writer.



15
16
17
# File 'lib/wavefront-sdk/metric_helper.rb', line 15

def writer
  @writer
end

Instance Method Details

#counter(path, value = 1, tags = nil) ⇒ Object

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.

Parameters:

  • path (String)

    metric path

  • value (Numeric) (defaults to: 1)

    value to add to counter

  • tags (Hash) (defaults to: nil)

    point tags



51
52
53
54
# 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) ⇒ Object



132
133
134
135
136
137
138
139
# 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) ⇒ Object

These distributions are stored in memory, and sent to Wavefront as native distibutions when the buffer is flushed.

Parameters:

  • path (String)

    metric path

  • value (Array, Numeric)

    value(s) to add to distribution

  • interval (Symbol, String)

    distribution interval, :m, :h, or :d

  • tags (Hash) (defaults to: nil)

    point tags



64
65
66
67
# 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) ⇒ Hash

Returns options hash, with :port replaced by :dist_port.

Returns:

  • (Hash)

    options hash, with :port replaced by :dist_port



155
156
157
# 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) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
# 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

#flushObject

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



72
73
74
75
76
# 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) ⇒ Object



94
95
96
97
98
99
100
101
102
103
# 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) ⇒ Object



105
106
107
108
109
110
111
112
113
114
# 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) ⇒ Object

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.



83
84
85
86
87
88
89
90
91
92
# 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) ⇒ Object

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

Parameters:

  • path (String)

    metric path

  • value (Numeric)

    metric value

  • tags (Hash) (defaults to: nil)

    hash of point tags



37
38
39
40
41
# 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) ⇒ Object

These are already Wavefront-format points



128
129
130
# File 'lib/wavefront-sdk/metric_helper.rb', line 128

def gauges_to_wf(gauges)
  gauges
end

#replay_counters(buffer) ⇒ Object

Play a failed flush full of counters back into the system



118
119
120
# 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) ⇒ Object



122
123
124
# 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