class Cabin::Metrics

What type of metrics do we want?

What metrics should come by default? Per-call/transaction/request metrics like:

- hit (count++ type metrics)
- latencies/timings

Per app or generally long-lifetime metrics like:

- "uptime"
- cpu usage
- memory usage
- count of active/in-flight actions/requests/calls/transactions
- peer metrics (number of cluster members, etc)

github.com/codahale/metrics/tree/master/metrics-core/src/main/java/com/yammer/metrics/core Reading what Coda Hale's “Metrics” stuff has, here's my summary:

gauges (callback to return a number)
counters (.inc and .dec methods)
meters (.mark to track each 'hit')
  Also exposes 1, 5, 15 minute moving averages
histograms: (.update(value) to record a new value)
  like meter, but takes values more than simply '1'
  as a result, exposes percentiles, median, etc.
timers
  a time-observing interface on top of histogram.

With the exception of gauges, all the other metrics are all active/pushed. Gauges take callbacks, so their values are pulled, not pushed. The active metrics can be represented as events since they the update occurs at the time of the change.

These active/push metrics can therefore be considered events.

All metrics (active/passive) can be queried for 'current state', too, making this suitable for serving to interested parties like monitoring and management tools.

Public Class Methods

new() click to toggle source

Get us a new metrics container.

# File lib/cabin/metrics.rb, line 53
def initialize
  @metrics_lock = Mutex.new
  @metrics = {}
end

Public Instance Methods

counter(instance, name=nil) click to toggle source

Create a new Counter metric 'instance' is usually an object owning this metric, but it can be a string. 'name' is the name of the metric.

# File lib/cabin/metrics.rb, line 89
def counter(instance, name=nil)
  return create(instance, name, Cabin::Metrics::Counter.new)
end
each(&block) click to toggle source

iterate over each metric. yields identifer, metric

# File lib/cabin/metrics.rb, line 118
def each(&block)
  # delegate to the @metrics hash until we need something fancier
  @metrics_lock.synchronize do
    @metrics.each(&block)
  end
end
histogram(instance, name=nil) click to toggle source

Create a new Histogram metric 'instance' is usually an object owning this metric, but it can be a string. 'name' is the name of the metric.

# File lib/cabin/metrics.rb, line 105
def histogram(instance, name=nil)
  return create(instance, name, Cabin::Metrics::Histogram.new)
end
meter(instance, name=nil) click to toggle source

Create a new Meter metric 'instance' is usually an object owning this metric, but it can be a string. 'name' is the name of the metric.

# File lib/cabin/metrics.rb, line 97
def meter(instance, name=nil)
  return create(instance, name, Cabin::Metrics::Meter.new)
end
timer(instance, name=nil) click to toggle source

Create a new Timer metric 'instance' is usually an object owning this metric, but it can be a string. 'name' is the name of the metric.

# File lib/cabin/metrics.rb, line 113
def timer(instance, name=nil)
  return create(instance, name, Cabin::Metrics::Timer.new)
end

Private Instance Methods

create(instance, name, metric_object) click to toggle source
# File lib/cabin/metrics.rb, line 59
def create(instance, name, metric_object)
  if !instance.is_a?(String)
    instance = "#{instance.class.name}<#{instance.object_id}>"
  end

  if name.nil?
    # If no name is given, use the class name of the metric.
    # For example, if we invoke Metrics#timer("foo"), the metric
    # name will be "foo/timer"
    metric_name = "#{instance}/#{metric_object.class.name.split("::").last.downcase}"
  else
    # Otherwise, use "instance/name" as the name.
    metric_name = "#{instance}/#{name}"
  end

  metric_object.channel = @channel
  metric_object.instance = metric_name

  if @channel
    @channel.debug("Created metric", :instance => instance, :type => metric_object.class)
  end
  return @metrics_lock.synchronize do
    @metrics[metric_name] = metric_object
  end
end