class Spectator::Histogram::PercentileTimer

Timer that buckets the counts to allow for estimating percentiles. This timer type will track the data distribution for the timer by maintaining a set of counters. The distribution can then be used on the server side to estimate percentiles while still allowing for arbitrary slicing and dicing based on dimensions.

Percentile timers are expensive compared to basic timers from the registry. In particular they have a higher storage cost, worst case ~300x, to maintain the data distribution. Be diligent about any additional dimensions added to percentile timers and ensure they have a small bounded cardinality. In addition it is highly recommended to set a range (using the min and max parameters in the constructor which expect times in seconds) to greatly restrict the worst case overhead.

Public Class Methods

new(registry, name, tags = nil, min = 10e-3, max = 60) click to toggle source
# File lib/spectator/histogram/percentiles.rb, line 450
def initialize(registry, name, tags = nil, min = 10e-3, max = 60)
  @registry = registry
  @id = Spectator::MeterId.new(name, tags)
  @min = min * 1e9
  @max = max * 1e9
  @timer = registry.timer_with_id(@id)
  @counters = PercentileBuckets.counters(registry, @id, 'T')
end

Public Instance Methods

count() click to toggle source
# File lib/spectator/histogram/percentiles.rb, line 484
def count
  @timer.count
end
percentile(perc) click to toggle source

return the given percentile in seconds

# File lib/spectator/histogram/percentiles.rb, line 474
def percentile(perc)
  counts = @counters.map(&:count)
  v = PercentileBuckets.percentile(counts, perc)
  v / 1e9
end
record(nanos) click to toggle source
# File lib/spectator/histogram/percentiles.rb, line 459
def record(nanos)
  @timer.record(nanos)
  restricted = restrict(nanos)
  idx = PercentileBuckets.index_of(restricted)
  @counters[idx].increment
end
time() { || ... } click to toggle source
# File lib/spectator/histogram/percentiles.rb, line 466
def time
  start = @registry.clock.monotonic_time
  yield
  elapsed = @registry.clock.monotonic_time - start
  record(elapsed)
end
total_time() click to toggle source
# File lib/spectator/histogram/percentiles.rb, line 480
def total_time
  @timer.total_time
end

Private Instance Methods

restrict(nanos) click to toggle source
# File lib/spectator/histogram/percentiles.rb, line 490
def restrict(nanos)
  nanos = @max if nanos > @max
  nanos = @min if nanos < @min
  nanos.floor
end