Class: Librato::Metrics::Aggregator

Inherits:
Object
  • Object
show all
Includes:
Processor
Defined in:
lib/librato/metrics/aggregator.rb

Overview

If you are measuring something very frequently you can sample into an aggregator and it will track and submit a single aggregate measurement

Examples:

aggregator = Libato::Metrics::Aggregator.new

40.times do
  # do work...
  aggregator.add 'work.time' => work_time
end

# send directly
aggregator.submit

# or merge into a queue for submission
queue.merge!(aggregator)

Constant Summary collapse

SEPARATOR =

must not be in valid tags and/or source criteria

'%%'

Constants included from Processor

Processor::MEASUREMENTS_PER_REQUEST

Instance Attribute Summary collapse

Attributes included from Processor

#last_submit_time, #per_request, #prefix, #tags

Instance Method Summary collapse

Methods included from Processor

#client, #has_tags?, #persister, #submit, #time

Constructor Details

#initialize(opts = {}) ⇒ Aggregator

Returns a new instance of Aggregator.

Parameters:

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :autosubmit_interval (Integer)

    If set the aggregator will auto-submit if the given number of seconds has passed when a new metric is added.

  • :clear_failures (Boolean)

    Should the aggregator remove all stored data if it runs into problems with a request? (default: false)

  • :client (Client)

    The client object to use to connect to Metrics. (default: Librato::Metrics.client)

  • :measure_time (Time|Integer)

    A default measure_time to use for measurements added.

  • :prefix (String)

    If set will apply the given prefix to all metric names of measurements added.

  • :source (String)

    The default source to use for measurements added.



38
39
40
41
# File 'lib/librato/metrics/aggregator.rb', line 38

def initialize(opts={})
  @aggregated = {}
  setup_common_options(opts)
end

Instance Attribute Details

#sourceObject (readonly)

Returns the value of attribute source.



30
31
32
# File 'lib/librato/metrics/aggregator.rb', line 30

def source
  @source
end

Instance Method Details

#add(measurements) ⇒ Aggregator

Add a metric entry to the metric set:

Examples:

Basic use

aggregator.add 'request.time' => 30.24

With a custom source

aggregator.add 'request.time' => {value: 20.52, source: 'staging'}

Parameters:

  • measurements (Hash)

    measurements to add

Returns:



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/librato/metrics/aggregator.rb', line 53

def add(measurements)
  measurements.each do |metric, data|
    entry = {}
    if @prefix
      metric = "#{@prefix}.#{metric}"
    end
    entry[:name] = metric.to_s
    if data.respond_to?(:each) # hash form
      validate_parameters(data)
      value = data[:value]
      if data[:source]
        metric = "#{metric}#{SEPARATOR}#{data[:source]}"
        entry[:source] = data[:source].to_s
      elsif data[:tags] && data[:tags].respond_to?(:each)
        metric = Librato::Metrics::Util.build_key_for(metric.to_s, data[:tags])
        entry[:tags] = data[:tags]
      end
    else
      value = data
    end

    @aggregated[metric] = {} unless @aggregated[metric]
    @aggregated[metric][:aggregate] ||= Aggregate.new
    @aggregated[metric][:aggregate] << value
    @aggregated[metric].merge!(entry)
  end
  autosubmit_check
  self
end

#clearObject Also known as: flush

Remove all queued metrics



92
93
94
# File 'lib/librato/metrics/aggregator.rb', line 92

def clear
  @aggregated = {}
end

#empty?Boolean

Returns true if aggregate contains no measurements

Returns:

  • (Boolean)


86
87
88
# File 'lib/librato/metrics/aggregator.rb', line 86

def empty?
  @aggregated.empty?
end

#queuedObject

Returns currently queued data



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/librato/metrics/aggregator.rb', line 99

def queued
  entries = []
  multidimensional = has_tags?

  @aggregated.each_value do |data|
    entry = {
      name: data[:name],
      count: data[:aggregate].count,
      sum: data[:aggregate].sum,
      # TODO: make float/non-float consistent in the gem
      min: data[:aggregate].min.to_f,
      max: data[:aggregate].max.to_f
      # TODO: expose v.sum2 and include
    }
    if data[:source]
      entry[:source] = data[:source]
    elsif data[:tags]
      multidimensional = true
      entry[:tags] = data[:tags]
    end
    multidimensional = true if data[:time]
    entries << entry
  end
  time = multidimensional ? :time : :measure_time
  req =
    if multidimensional
      { measurements: entries }
    else
      { gauges: entries }
    end
  req[:source] = @source if @source
  req[:tags] = @tags if has_tags?
  req[time] = @time if @time

  req
end