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.


19
20
21
22
23
24
25
# File 'lib/wavefront-sdk/metric_helper.rb', line 19

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.



13
14
15
# File 'lib/wavefront-sdk/metric_helper.rb', line 13

def buf
  @buf
end

#dist_writerObject (readonly)

Returns the value of attribute dist_writer.



13
14
15
# File 'lib/wavefront-sdk/metric_helper.rb', line 13

def dist_writer
  @dist_writer
end

#optsObject (readonly)

Returns the value of attribute opts.



13
14
15
# File 'lib/wavefront-sdk/metric_helper.rb', line 13

def opts
  @opts
end

#writerObject (readonly)

Returns the value of attribute writer.



13
14
15
# File 'lib/wavefront-sdk/metric_helper.rb', line 13

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



49
50
51
52
# File 'lib/wavefront-sdk/metric_helper.rb', line 49

def counter(path, value = 1, tags = nil)
  key = [path, tags]
  @buf[:counters][key] += value
end

#counters_to_wf(counters) ⇒ Object



130
131
132
133
134
135
136
137
# File 'lib/wavefront-sdk/metric_helper.rb', line 130

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



62
63
64
65
# File 'lib/wavefront-sdk/metric_helper.rb', line 62

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



153
154
155
# File 'lib/wavefront-sdk/metric_helper.rb', line 153

def dist_creds(creds, opts)
  creds.dup.tap { |o| o[:port] = opts[:dist_port] }
end

#dists_to_wf(dists) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
# File 'lib/wavefront-sdk/metric_helper.rb', line 139

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



70
71
72
73
74
# File 'lib/wavefront-sdk/metric_helper.rb', line 70

def flush
  flush_gauges(buf[:gauges])
  flush_counters(buf[:counters])
  flush_dists(buf[:dists]) if opts.key?(:dist_port)
end

#flush_counters(counters) ⇒ Object



92
93
94
95
96
97
98
99
100
101
# File 'lib/wavefront-sdk/metric_helper.rb', line 92

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



103
104
105
106
107
108
109
110
111
112
# File 'lib/wavefront-sdk/metric_helper.rb', line 103

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.



81
82
83
84
85
86
87
88
89
90
# File 'lib/wavefront-sdk/metric_helper.rb', line 81

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



35
36
37
38
39
# File 'lib/wavefront-sdk/metric_helper.rb', line 35

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



126
127
128
# File 'lib/wavefront-sdk/metric_helper.rb', line 126

def gauges_to_wf(gauges)
  gauges
end

#replay_counters(buffer) ⇒ Object

Play a failed flush full of counters back into the system



116
117
118
# File 'lib/wavefront-sdk/metric_helper.rb', line 116

def replay_counters(buffer)
  buffer.each { |k, v| counter(k[0], v, k[1]) }
end

#replay_dists(buffer) ⇒ Object



120
121
122
# File 'lib/wavefront-sdk/metric_helper.rb', line 120

def replay_dists(buffer)
  buffer.each { |k, v| dist(k[0], k[1], v, k[2]) }
end