lib/librato/metrics/processor.rb
require "set"
module Librato
module Metrics
# Mixin which provides common logic between {Queue} and {Aggregator}
# objects.
module Processor
MEASUREMENTS_PER_REQUEST = 500
attr_reader :per_request, :last_submit_time
attr_accessor :prefix, :tags
def tags
@tags ||= {}
end
# The current Client instance this queue is using to authenticate
# and connect to Librato Metrics. This will default to the primary
# client used by the Librato::Metrics module unless it has been
# set to something else.
#
# @return [Librato::Metrics::Client]
def client
@client ||= Librato::Metrics.client
end
def has_tags?
!@tags.empty?
end
alias :tags? :has_tags?
# The object this MetricSet will use to persist
#
def persister
@persister ||= create_persister
end
# Persist currently queued metrics
#
# @return Boolean
def submit
return true if self.empty?
options = {per_request: @per_request}
if persister.persist(self.client, self.queued, options)
@last_submit_time = Time.now
clear and return true
end
false
rescue ClientError
# clean up if we hit exceptions if asked to
clear if @clear_on_failure
raise
end
# Capture execution time for a block and queue
# it as the value for a metric. Times are recorded
# in milliseconds.
#
# Options are the same as for #add.
#
# @example Queue API request response time
# queue.time :api_request_time do
# # API request..
# end
#
# @example Queue API request response time w/ source
# queue.time :api_request_time, source: 'app1' do
# # API request..
# end
#
# @param [Symbol|String] name Metric name
# @param [Hash] options Metric options
def time(name, options={})
start = Time.now
yield.tap do
duration = (Time.now - start) * 1000.0 # milliseconds
metric = {name => options.merge({value: duration})}
add metric
end
end
alias :benchmark :time
private
def create_persister
type = self.client.persistence.to_s.capitalize
Librato::Metrics::Persistence.const_get(type).new
end
def epoch_time
Time.now.to_i
end
def setup_common_options(options)
validate_parameters(options)
@autosubmit_interval = options[:autosubmit_interval]
@client = options[:client] || Librato::Metrics.client
@per_request = options[:per_request] || MEASUREMENTS_PER_REQUEST
@source = options[:source]
@tags = options.fetch(:tags, {})
@time = (options[:time] && options[:time].to_i || options[:measure_time] && options[:measure_time].to_i)
@create_time = Time.now
@clear_on_failure = options[:clear_failures] || false
@prefix = options[:prefix]
end
def autosubmit_check
if @autosubmit_interval
last = @last_submit_time || @create_time
self.submit if (Time.now - last).to_i >= @autosubmit_interval
end
end
def validate_parameters(options)
invalid_combinations = [
[:source, :tags],
]
opts = options.keys.to_set
invalid_combinations.each do |combo|
if combo.to_set.subset?(opts)
raise InvalidParameters, "#{combo} cannot be simultaneously set"
end
end
end
end
end
end