class Sqreen::MetricsStore

This store and register metrics

Constants

KIND_KEY
NAME_KEY

definition keys

OPTIONS_KEY
PERIOD_KEY

Attributes

metrics[R]

All known metrics

store[R]

Currently ready samples

Public Class Methods

new() click to toggle source
# File lib/sqreen/metrics_store.rb, line 27
def initialize
  @store = []
  @metrics = {} # name => (metric, period, start)
  @mutex = Mutex.new
end

Public Instance Methods

create_metric(definition, rule = nil, mklass = nil) click to toggle source

Definition contains a name,period and aggregate at least @param definition [Hash] a metric definition @param rule [RuleCB] the rule associated with this metric, if any @param mklass [Object] Override metric object (used in testing)

# File lib/sqreen/metrics_store.rb, line 37
def create_metric(definition, rule = nil, mklass = nil)
  @mutex.lock

  name = definition[NAME_KEY]
  kind = definition[KIND_KEY]
  klass = valid_metric(kind, name)

  opts = definition[OPTIONS_KEY]
  metric = mklass || klass.new(opts)
  @metrics[name] = [
    metric,
    definition[PERIOD_KEY],
    nil # Start
  ]
  metric.name = name
  metric.rule = rule
  metric.period = definition[PERIOD_KEY]
  metric
ensure
  @mutex.unlock
end
metric?(name) click to toggle source
# File lib/sqreen/metrics_store.rb, line 59
def metric?(name)
  @metrics.key?(name)
end
publish(flush = true, at = Sqreen.time) click to toggle source

Drains every metrics and returns the store content @param at [Time] when is the store emptied

# File lib/sqreen/metrics_store.rb, line 76
def publish(flush = true, at = Sqreen.time)
  @mutex.lock
  @metrics.each do |name, (_, period, start)|
    next_sample(name, at) if flush || !start.nil? && (start + period) < at
  end
  out = @store
  @store = []
  out
ensure
  @mutex.unlock
end
update(name, at, key, value) click to toggle source

@param at [Time] when is the store emptied

# File lib/sqreen/metrics_store.rb, line 64
def update(name, at, key, value)
  @mutex.lock
  metric, period, start = @metrics[name]
  raise UnregisteredMetric, "Unknown metric #{name}" unless metric
  next_sample(name, at) if start.nil? || (start + period) < at
  metric.update(key, value)
ensure
  @mutex.unlock
end

Protected Instance Methods

next_sample(name, at) click to toggle source
# File lib/sqreen/metrics_store.rb, line 90
def next_sample(name, at)
  metric = @metrics[name][0]
  r = metric.next_sample(at)
  @metrics[name][2] = at # new start
  return unless r

  r[NAME_KEY] = name
  obs = r[Metric::OBSERVATION_KEY]
  return unless obs && (!obs.respond_to?(:empty?) || !obs.empty?)
  start_of_mono = Time.now.utc - Sqreen.time

  agg = AggregatedMetric.new
  agg.metric = metric
  agg.rule = agg.metric.rule
  agg.start = start_of_mono + r[Metric::START_KEY]
  agg.finish = start_of_mono + r[Metric::FINISH_KEY]
  agg.data = obs
  @store << agg
end
valid_metric(kind, name) click to toggle source
# File lib/sqreen/metrics_store.rb, line 110
def valid_metric(kind, name)
  unless Sqreen::Metric.const_defined?(kind)
    raise UnknownMetric, "No such #{kind} metric"
  end
  klass = Sqreen::Metric.const_get(kind)
  metric = @metrics[name] && @metrics[name][0]
  if metric && metric.class != klass
    msg = "Was a #{metric.class.name} not a #{klass.name} "
    raise AlreadyRegisteredMetric, msg
  end
  klass
end