Explorar o código

Comments for godoc.

Richard Crowley %!s(int64=14) %!d(string=hai) anos
pai
achega
af687e233a
Modificáronse 11 ficheiros con 201 adicións e 7 borrados
  1. 14 0
      counter.go
  2. 20 0
      ewma.go
  3. 11 0
      gauge.go
  4. 12 0
      healthcheck.go
  5. 28 0
      histogram.go
  6. 2 0
      log.go
  7. 21 0
      meter.go
  8. 40 7
      registry.go
  9. 29 0
      sample.go
  10. 2 0
      syslog.go
  11. 22 0
      timer.go

+ 14 - 0
counter.go

@@ -2,6 +2,10 @@ package metrics
 
 import "sync/atomic"
 
+// Counters hold an int64 value that can be incremented and decremented.
+//
+// This is an interface so as to encourage other structs to implement
+// the Counter API as appropriate.
 type Counter interface {
 	Clear()
 	Count() int64
@@ -9,26 +13,36 @@ type Counter interface {
 	Inc(int64)
 }
 
+// The standard implementation of a Counter uses the sync/atomic package
+// to manage a single int64 value.  When the latest weeklies land in a
+// release, atomic.LoadInt64 will be available and this code will become
+// safe on 32-bit architectures.
 type counter struct {
 	count int64
 }
 
+// Create a new counter.
 func NewCounter() Counter {
 	return &counter{0}
 }
 
+// Clear the counter: set it to zero.
 func (c *counter) Clear() {
 	c.count = 0
 }
 
+// Return the current count.  This is the method that's currently unsafe
+// on 32-bit architectures.
 func (c *counter) Count() int64 {
 	return c.count
 }
 
+// Decrement the counter by the given amount.
 func (c *counter) Dec(i int64) {
 	atomic.AddInt64(&c.count, -i)
 }
 
+// Increment the counter by the given amount.
 func (c *counter) Inc(i int64) {
 	atomic.AddInt64(&c.count, i)
 }

+ 20 - 0
ewma.go

@@ -5,12 +5,22 @@ import (
 	"sync/atomic"
 )
 
+// EWMAs continuously calculate an exponentially-weighted moving average
+// based on an outside source of clock ticks.
+//
+// This is an interface so as to encourage other structs to implement
+// the EWMA API as appropriate.
 type EWMA interface {
 	Rate() float64
 	Tick()
 	Update(int64)
 }
 
+// The standard implementation of an EWMA tracks the number of uncounted
+// events and processes them on each tick.  It uses the sync/atomic package
+// to manage uncounted events.  When the latest weeklies land in a release,
+// atomic.LoadInt64 will be available and this code will become safe on
+// 32-bit architectures.
 type ewma struct {
 	alpha float64
 	uncounted int64
@@ -19,36 +29,46 @@ type ewma struct {
 	tick chan bool
 }
 
+// Create a new EWMA with the given alpha.  Create the clock channel and
+// start the ticker goroutine.
 func NewEWMA(alpha float64) EWMA {
 	a := &ewma{alpha, 0, 0.0, false, make(chan bool)}
 	go a.ticker()
 	return a
 }
 
+// Create a new EWMA with alpha set for a one-minute moving average.
 func NewEWMA1() EWMA {
 	return NewEWMA(1 - math.Exp(-5.0 / 60.0 / 1))
 }
 
+// Create a new EWMA with alpha set for a five-minute moving average.
 func NewEWMA5() EWMA {
 	return NewEWMA(1 - math.Exp(-5.0 / 60.0 / 5))
 }
 
+// Create a new EWMA with alpha set for a fifteen-minute moving average.
 func NewEWMA15() EWMA {
 	return NewEWMA(1 - math.Exp(-5.0 / 60.0 / 15))
 }
 
+// Return the moving average rate of events per second.
 func (a *ewma) Rate() float64 {
 	return a.rate * float64(1e9)
 }
 
+// Tick the clock to update the moving average.
 func (a *ewma) Tick() {
 	a.tick <- true
 }
 
+// Add n uncounted events.
 func (a *ewma) Update(n int64) {
 	atomic.AddInt64(&a.uncounted, n)
 }
 
+// On each clock tick, update the moving average to reflect the number of
+// events seen since the last tick.
 func (a *ewma) ticker() {
 	for <-a.tick {
 		count := a.uncounted

+ 11 - 0
gauge.go

@@ -2,23 +2,34 @@ package metrics
 
 import "sync/atomic"
 
+// Gauges hold an int64 value that can be set arbitrarily.
+//
+// This is an interface so as to encourage other structs to implement
+// the Gauge API as appropriate.
 type Gauge interface {
 	Update(int64)
 	Value() int64
 }
 
+// The standard implementation of a Gauge uses the sync/atomic package
+// to manage a single int64 value.  When the latest weeklies land in a
+// release, atomic.LoadInt64 will be available and this code will become
+// safe on 32-bit architectures.
 type gauge struct {
 	value int64
 }
 
+// Create a new gauge.
 func NewGauge() Gauge {
 	return &gauge{0}
 }
 
+// Update the gauge's value.
 func (g *gauge) Update(v int64) {
 	atomic.AddInt64(&g.value, v)
 }
 
+// Return the gauge's current value.
 func (g *gauge) Value() int64 {
 	return g.value
 }

+ 12 - 0
healthcheck.go

@@ -2,6 +2,10 @@ package metrics
 
 import "os"
 
+// Healthchecks hold an os.Error value describing an arbitrary up/down status.
+//
+// This is an interface so as to encourage other structs to implement
+// the Healthcheck API as appropriate.
 type Healthcheck interface {
 	Check()
 	Error() os.Error
@@ -9,27 +13,35 @@ type Healthcheck interface {
 	Unhealthy(os.Error)
 }
 
+// The standard implementation of a Healthcheck stores the status and a
+// function to call to update the status.
 type healthcheck struct {
 	err os.Error
 	f func(Healthcheck)
 }
 
+// Create a new healthcheck, which will use the given function to update
+// its status.
 func NewHealthcheck(f func(Healthcheck)) Healthcheck {
 	return &healthcheck{nil, f}
 }
 
+// Update the healthcheck's status.
 func (h *healthcheck) Check() {
 	h.f(h)
 }
 
+// Return the healthcheck's status, which will be nil if it is healthy.
 func (h *healthcheck) Error() os.Error {
 	return h.err
 }
 
+// Mark the healthcheck as healthy.
 func (h *healthcheck) Healthy() {
 	h.err = nil
 }
 
+// Mark the healthcheck as unhealthy.  The error should provide details.
 func (h *healthcheck) Unhealthy(err os.Error) {
 	h.err = err
 }

+ 28 - 0
histogram.go

@@ -5,6 +5,10 @@ import (
 	"sort"
 )
 
+// Histograms calculate distribution statistics from an int64 value.
+//
+// This is an interface so as to encourage other structs to implement
+// the Histogram API as appropriate.
 type Histogram interface {
 	Clear()
 	Count() int64
@@ -18,6 +22,8 @@ type Histogram interface {
 	Variance() float64
 }
 
+// The standard implementation of a Histogram uses a Sample and a goroutine
+// to synchronize its calculations.
 type histogram struct {
 	s Sample
 	in chan int64
@@ -25,11 +31,15 @@ type histogram struct {
 	reset chan bool
 }
 
+// A histogramV contains all the values that would need to be passed back
+// from the synchronizing goroutine.
 type histogramV struct {
 	count, sum, min, max int64
 	variance [2]float64
 }
 
+// Create a new histogram with the given Sample.  Create the communication
+// channels and start the synchronizing goroutine.
 func NewHistogram(s Sample) Histogram {
 	h := &histogram{
 		s,
@@ -41,6 +51,9 @@ func NewHistogram(s Sample) Histogram {
 	return h
 }
 
+// Create a new histogramV.  The initial values compare so that the first
+// value will be both min and max and the variance is flagged for special
+// treatment on its first iteration.
 func newHistogramV() histogramV {
 	return histogramV{
 		0, 0, math.MaxInt64, math.MinInt64,
@@ -48,20 +61,24 @@ func newHistogramV() histogramV {
 	}
 }
 
+// Clear the histogram.
 func (h *histogram) Clear() {
 	h.reset <- true
 }
 
+// Return the count of inputs since the histogram was last cleared.
 func (h *histogram) Count() int64 {
 	return (<-h.out).count
 }
 
+// Return the maximal value seen since the histogram was last cleared.
 func (h *histogram) Max() int64 {
 	hv := <-h.out
 	if 0 < hv.count { return hv.max }
 	return 0
 }
 
+// Return the mean of all values seen since the histogram was last cleared.
 func (h *histogram) Mean() float64 {
 	hv := <-h.out
 	if 0 < hv.count {
@@ -70,16 +87,21 @@ func (h *histogram) Mean() float64 {
 	return 0
 }
 
+// Return the minimal value seen since the histogram was last cleared.
 func (h *histogram) Min() int64 {
 	hv := <-h.out
 	if 0 < hv.count { return hv.min }
 	return 0
 }
 
+// Return an arbitrary percentile of all values seen since the histogram was
+// last cleared.
 func (h *histogram) Percentile(p float64) float64 {
 	return h.Percentiles([]float64{p})[0]
 }
 
+// Return a slice of arbitrary percentiles of all values seen since the
+// histogram was last cleared.
 func (h *histogram) Percentiles(ps []float64) []float64 {
 	scores := make([]float64, len(ps))
 	values := int64Slice(h.s.Values())
@@ -102,20 +124,26 @@ func (h *histogram) Percentiles(ps []float64) []float64 {
 	return scores
 }
 
+// Return the standard deviation of all values seen since the histogram was
+// last cleared.
 func (h *histogram) StdDev() float64 {
 	return math.Sqrt(h.Variance())
 }
 
+// Update the histogram with a new value.
 func (h *histogram) Update(v int64) {
 	h.in <- v
 }
 
+// Return the variance of all values seen since the histogram was last cleared.
 func (h *histogram) Variance() float64 {
 	hv := <-h.out
 	if 1 >= hv.count { return 0.0 }
 	return hv.variance[1] / float64(hv.count - 1)
 }
 
+// Receive inputs and send outputs.  Sample each input and update values in
+// the histogramV.  Send a copy of the histogramV as output.
 func (h *histogram) arbiter() {
 	hv := newHistogramV()
 	for {

+ 2 - 0
log.go

@@ -5,6 +5,8 @@ import (
 	"time"
 )
 
+// Output each metric in the given registry periodically using the given
+// logger.  The interval is to be given in seconds.
 func Log(r Registry, interval int, l *log.Logger) {
 	for {
 		r.EachCounter(func(name string, c Counter) {

+ 21 - 0
meter.go

@@ -2,6 +2,11 @@ package metrics
 
 import "time"
 
+// Meters count events to produce exponentially-weighted moving average rates
+// at one-, five-, and fifteen-minutes and a mean rate.
+//
+// This is an interface so as to encourage other structs to implement
+// the Meter API as appropriate.
 type Meter interface {
 	Count() int64
 	Mark(int64)
@@ -11,17 +16,24 @@ type Meter interface {
 	RateMean() float64
 }
 
+// The standard implementation of a Meter uses a goroutine to synchronize
+// its calculations and another goroutine (via time.Ticker) to produce
+// clock ticks.
 type meter struct {
 	in chan int64
 	out chan meterV
 	ticker *time.Ticker
 }
 
+// A meterV contains all the values that would need to be passed back
+// from the synchronizing goroutine.
 type meterV struct {
 	count int64
 	rate1, rate5, rate15, rateMean float64
 }
 
+// Create a new meter.  Create the communication channels and start the
+// synchronizing goroutine.
 func NewMeter() Meter {
 	m := &meter{
 		make(chan int64),
@@ -32,30 +44,39 @@ func NewMeter() Meter {
 	return m
 }
 
+// Return the count of events seen.
 func (m *meter) Count() int64 {
 	return (<-m.out).count
 }
 
+// Mark the occurance of n events.
 func (m *meter) Mark(n int64) {
 	m.in <- n
 }
 
+// Return the meter's one-minute moving average rate of events.
 func (m *meter) Rate1() float64 {
 	return (<-m.out).rate1
 }
 
+// Return the meter's five-minute moving average rate of events.
 func (m *meter) Rate5() float64 {
 	return (<-m.out).rate5
 }
 
+// Return the meter's fifteen-minute moving average rate of events.
 func (m *meter) Rate15() float64 {
 	return (<-m.out).rate15
 }
 
+// Return the meter's mean rate of events.
 func (m *meter) RateMean() float64 {
 	return (<-m.out).rateMean
 }
 
+// Receive inputs and send outputs.  Count each input and update the various
+// moving averages and the mean rate of events.  Send a copy of the meterV
+// as output.
 func (m *meter) arbiter() {
 	var mv meterV
 	a1 := NewEWMA1()

+ 40 - 7
registry.go

@@ -2,7 +2,12 @@ package metrics
 
 import "sync"
 
-type Registry interface{
+// A Registry holds references to a set of metrics by name and can iterate
+// over them, calling callback functions provided by the user.
+//
+// This is an interface so as to encourage other structs to implement
+// the Registry API as appropriate.
+type Registry interface {
 
 	EachCounter(func(string, Counter))
 	EachGauge(func(string, Gauge))
@@ -36,6 +41,8 @@ type Registry interface{
 
 }
 
+// The standard implementation of a Registry is a set of mutex-protected
+// maps of names to metrics.
 type registry struct {
 	mutex *sync.Mutex
 	counters map[string]Counter
@@ -46,6 +53,7 @@ type registry struct {
 	timers map[string]Timer
 }
 
+// Create a new registry.
 func NewRegistry() Registry {
 	return &registry {
 		&sync.Mutex{},
@@ -58,48 +66,49 @@ func NewRegistry() Registry {
 	}
 }
 
+// Call the given function for each registered counter.
 func (r *registry) EachCounter(f func(string, Counter)) {
 	r.mutex.Lock()
 	for name, c := range r.counters { f(name, c) }
 	r.mutex.Unlock()
 }
 
+// Call the given function for each registered gauge.
 func (r *registry) EachGauge(f func(string, Gauge)) {
 	r.mutex.Lock()
 	for name, g := range r.gauges { f(name, g) }
 	r.mutex.Unlock()
 }
 
+// Call the given function for each registered healthcheck.
 func (r *registry) EachHealthcheck(f func(string, Healthcheck)) {
 	r.mutex.Lock()
 	for name, h := range r.healthchecks { f(name, h) }
 	r.mutex.Unlock()
 }
 
+// Call the given function for each registered histogram.
 func (r *registry) EachHistogram(f func(string, Histogram)) {
 	r.mutex.Lock()
 	for name, h := range r.histograms { f(name, h) }
 	r.mutex.Unlock()
 }
 
+// Call the given function for each registered meter.
 func (r *registry) EachMeter(f func(string, Meter)) {
 	r.mutex.Lock()
 	for name, m := range r.meters { f(name, m) }
 	r.mutex.Unlock()
 }
 
+// Call the given function for each registered timer.
 func (r *registry) EachTimer(f func(string, Timer)) {
 	r.mutex.Lock()
 	for name, t := range r.timers { f(name, t) }
 	r.mutex.Unlock()
 }
 
-func (r *registry) RunHealthchecks() {
-	r.mutex.Lock()
-	for _, h := range r.healthchecks { h.Check() }
-	r.mutex.Unlock()
-}
-
+// Get the Counter by the given name or nil if none is registered.
 func (r *registry) GetCounter(name string) Counter {
 	r.mutex.Lock()
 	c := r.counters[name]
@@ -107,6 +116,7 @@ func (r *registry) GetCounter(name string) Counter {
 	return c
 }
 
+// Get the Gauge by the given name or nil if none is registered.
 func (r *registry) GetGauge(name string) Gauge {
 	r.mutex.Lock()
 	g := r.gauges[name]
@@ -114,6 +124,7 @@ func (r *registry) GetGauge(name string) Gauge {
 	return g
 }
 
+// Get the Healthcheck by the given name or nil if none is registered.
 func (r *registry) GetHealthcheck(name string) Healthcheck {
 	r.mutex.Lock()
 	h := r.healthchecks[name]
@@ -121,6 +132,7 @@ func (r *registry) GetHealthcheck(name string) Healthcheck {
 	return h
 }
 
+// Get the Histogram by the given name or nil if none is registered.
 func (r *registry) GetHistogram(name string) Histogram {
 	r.mutex.Lock()
 	h := r.histograms[name]
@@ -128,6 +140,7 @@ func (r *registry) GetHistogram(name string) Histogram {
 	return h
 }
 
+// Get the Meter by the given name or nil if none is registered.
 func (r *registry) GetMeter(name string) Meter {
 	r.mutex.Lock()
 	m := r.meters[name]
@@ -135,6 +148,7 @@ func (r *registry) GetMeter(name string) Meter {
 	return m
 }
 
+// Get the Timer by the given name or nil if none is registered.
 func (r *registry) GetTimer(name string) Timer {
 	r.mutex.Lock()
 	t := r.timers[name]
@@ -142,72 +156,91 @@ func (r *registry) GetTimer(name string) Timer {
 	return t
 }
 
+// Register the given Counter under the given name.
 func (r *registry) RegisterCounter(name string, c Counter) {
 	r.mutex.Lock()
 	r.counters[name] = c
 	r.mutex.Unlock()
 }
 
+// Register the given Gauge under the given name.
 func (r *registry) RegisterGauge(name string, g Gauge) {
 	r.mutex.Lock()
 	r.gauges[name] = g
 	r.mutex.Unlock()
 }
 
+// Register the given Healthcheck under the given name.
 func (r *registry) RegisterHealthcheck(name string, h Healthcheck) {
 	r.mutex.Lock()
 	r.healthchecks[name] = h
 	r.mutex.Unlock()
 }
 
+// Register the given Histogram under the given name.
 func (r *registry) RegisterHistogram(name string, h Histogram) {
 	r.mutex.Lock()
 	r.histograms[name] = h
 	r.mutex.Unlock()
 }
 
+// Register the given Meter under the given name.
 func (r *registry) RegisterMeter(name string, m Meter) {
 	r.mutex.Lock()
 	r.meters[name] = m
 	r.mutex.Unlock()
 }
 
+// Register the given Timer under the given name.
 func (r *registry) RegisterTimer(name string, t Timer) {
 	r.mutex.Lock()
 	r.timers[name] = t
 	r.mutex.Unlock()
 }
 
+// Run all registered healthchecks.
+func (r *registry) RunHealthchecks() {
+	r.mutex.Lock()
+	for _, h := range r.healthchecks { h.Check() }
+	r.mutex.Unlock()
+}
+
+// Unregister the given Counter with the given name.
 func (r *registry) UnregisterCounter(name string) {
 	r.mutex.Lock()
 	r.counters[name] = nil, false
 	r.mutex.Unlock()
 }
 
+// Unregister the given Gauge with the given name.
 func (r *registry) UnregisterGauge(name string) {
 	r.mutex.Lock()
 	r.gauges[name] = nil, false
 	r.mutex.Unlock()
 }
 
+// Unregister the given Healthcheck with the given name.
 func (r *registry) UnregisterHealthcheck(name string) {
 	r.mutex.Lock()
 	r.healthchecks[name] = nil, false
 	r.mutex.Unlock()
 }
 
+// Unregister the given Histogram with the given name.
 func (r *registry) UnregisterHistogram(name string) {
 	r.mutex.Lock()
 	r.histograms[name] = nil, false
 	r.mutex.Unlock()
 }
 
+// Unregister the given Meter with the given name.
 func (r *registry) UnregisterMeter(name string) {
 	r.mutex.Lock()
 	r.meters[name] = nil, false
 	r.mutex.Unlock()
 }
 
+// Unregister the given Timer with the given name.
 func (r *registry) UnregisterTimer(name string) {
 	r.mutex.Lock()
 	r.timers[name] = nil, false

+ 29 - 0
sample.go

@@ -8,6 +8,11 @@ import (
 
 const rescaleThreshold = 1e9 * 60 * 60
 
+// Samples maintain a statistically-significant selection of values from
+// a stream.
+//
+// This is an interface so as to encourage other structs to implement
+// the Sample API as appropriate.
 type Sample interface {
 	Clear()
 	Size() int
@@ -15,6 +20,11 @@ type Sample interface {
 	Values() []int64
 }
 
+// An exponentially-decaying sample using a forward-decaying priority
+// reservoir.  See Cormode et al's "Forward Decay: A Practical Time Decay
+// Model for Streaming Systems".
+//
+// <http://www.research.att.com/people/Cormode_Graham/library/publications/CormodeShkapenyukSrivastavaXu09.pdf>
 type expDecaySample struct {
 	reservoirSize int
 	alpha float64
@@ -23,6 +33,8 @@ type expDecaySample struct {
 	reset chan bool
 }
 
+// Create a new exponentially-decaying sample with the given reservoir size
+// and alpha.
 func NewExpDecaySample(reservoirSize int, alpha float64) Sample {
 	s := &expDecaySample{
 		reservoirSize,
@@ -35,22 +47,29 @@ func NewExpDecaySample(reservoirSize int, alpha float64) Sample {
 	return s
 }
 
+// Clear all samples.
 func (s *expDecaySample) Clear() {
 	s.reset <- true
 }
 
+// Return the size of the sample, which is at most the reservoir size.
 func (s *expDecaySample) Size() int {
 	return len(<-s.out)
 }
 
+// Update the sample with a new value.
 func (s *expDecaySample) Update(v int64) {
 	s.in <- v
 }
 
+// Return all the values in the sample.
 func (s *expDecaySample) Values() []int64 {
 	return <-s.out
 }
 
+// Receive inputs and send outputs.  Count and save each input value,
+// rescaling the sample if enough time has elapsed since the last rescaling.
+// Send a copy of the values as output.
 func (s *expDecaySample) arbiter() {
 	count := 0
 	values := make(map[float64]int64)
@@ -102,6 +121,9 @@ func (s *expDecaySample) arbiter() {
 	}
 }
 
+// A uniform sample using Vitter's Algorithm R.
+//
+// <http://www.cs.umd.edu/~samir/498/vitter.pdf>
 type uniformSample struct {
 	reservoirSize int
 	in chan int64
@@ -109,6 +131,7 @@ type uniformSample struct {
 	reset chan bool
 }
 
+// Create a new uniform sample with the given reservoir size.
 func NewUniformSample(reservoirSize int) Sample {
 	s := &uniformSample{
 		reservoirSize,
@@ -120,22 +143,28 @@ func NewUniformSample(reservoirSize int) Sample {
 	return s
 }
 
+// Clear all samples.
 func (s *uniformSample) Clear() {
 	s.reset <- true
 }
 
+// Return the size of the sample, which is at most the reservoir size.
 func (s *uniformSample) Size() int {
 	return len(<-s.out)
 }
 
+// Update the sample with a new value.
 func (s *uniformSample) Update(v int64) {
 	s.in <- v
 }
 
+// Return all the values in the sample.
 func (s *uniformSample) Values() []int64 {
 	return <-s.out
 }
 
+// Receive inputs and send outputs.  Count and save each input value at a
+// random index.  Send a copy of the values as output.
 func (s *uniformSample) arbiter() {
 	count := 0
 	values := make([]int64, s.reservoirSize)

+ 2 - 0
syslog.go

@@ -6,6 +6,8 @@ import (
 	"time"
 )
 
+// Output each metric in the given registry to syslog periodically using
+// the given syslogger.  The interval is to be given in seconds.
 func Syslog(r Registry, interval int, w *syslog.Writer) {
 	for {
 		r.EachCounter(func(name string, c Counter) {

+ 22 - 0
timer.go

@@ -2,6 +2,10 @@ package metrics
 
 import "time"
 
+// Timers capture the duration and rate of events.
+//
+// This is an interface so as to encourage other structs to implement
+// the Histogram API as appropriate.
 type Timer interface {
 	Count() int64
 	Max() int64
@@ -18,69 +22,87 @@ type Timer interface {
 	Update(uint64)
 }
 
+// The standard implementation of a Timer uses a Histogram and Meter directly.
 type timer struct {
 	h Histogram
 	m Meter
 }
 
+// Create a new timer with the given Histogram and Meter.
 func NewCustomTimer(h Histogram, m Meter) Timer {
 	return &timer{h, m}
 }
 
+// Create a new timer with a standard histogram and meter.  The histogram
+// will use an exponentially-decaying sample with the same reservoir size
+// and alpha as UNIX load averages.
 func NewTimer() Timer {
 	return &timer{NewHistogram(NewExpDecaySample(1028, 0.015)), NewMeter()}
 }
 
+// Return the count of inputs.
 func (t *timer) Count() int64 {
 	return t.h.Count()
 }
 
+// Return the maximal value seen.
 func (t *timer) Max() int64 {
 	return t.h.Max()
 }
 
+// Return the mean of all values seen.
 func (t *timer) Mean() float64 {
 	return t.h.Mean()
 }
 
+// Return the minimal value seen.
 func (t *timer) Min() int64 {
 	return t.h.Min()
 }
 
+// Return an arbitrary percentile of all values seen.
 func (t *timer) Percentile(p float64) float64 {
 	return t.h.Percentile(p)
 }
 
+// Return a slice of arbitrary percentiles of all values seen.
 func (t *timer) Percentiles(ps []float64) []float64 {
 	return t.h.Percentiles(ps)
 }
 
+// Return the meter's one-minute moving average rate of events.
 func (t *timer) Rate1() float64 {
 	return t.m.Rate1()
 }
 
+// Return the meter's five-minute moving average rate of events.
 func (t *timer) Rate5() float64 {
 	return t.m.Rate5()
 }
 
+// Return the meter's fifteen-minute moving average rate of events.
 func (t *timer) Rate15() float64 {
 	return t.m.Rate15()
 }
 
+// Return the meter's mean rate of events.
 func (t *timer) RateMean() float64 {
 	return t.m.RateMean()
 }
 
+// Return the standard deviation of all values seen.
 func (t *timer) StdDev() float64 {
 	return t.h.StdDev()
 }
 
+// Record the duration of the execution of the given function.
 func (t *timer) Time(f func()) {
 	ts := time.Nanoseconds()
 	f()
 	t.Update(uint64(time.Nanoseconds() - ts))
 }
 
+// Record the duration of an event.
 func (t *timer) Update(duration uint64) {
 	t.h.Update(int64(duration))
 	t.m.Mark(1)