Explorar o código

Consolidate metrics in the registry.

This brings type-switches into play in Log and Syslog, which bugs me superficially because all the metrics are lumped into the same identifier (m).  A nice side-effect is that collisions between metrics of different types are disallowed.
Richard Crowley %!s(int64=14) %!d(string=hai) anos
pai
achega
256a37b51b
Modificáronse 6 ficheiros con 196 adicións e 376 borrados
  1. 5 5
      cmd/metrics-bench/metrics-bench.go
  2. 6 6
      cmd/metrics-example/metrics-example.go
  3. 50 52
      log.go
  4. 27 203
      registry.go
  5. 52 52
      runtime.go
  6. 56 58
      syslog.go

+ 5 - 5
cmd/metrics-bench/metrics-bench.go

@@ -9,11 +9,11 @@ import (
 func main() {
 	r := metrics.NewRegistry()
 	for i := 0; i < 10000; i++ {
-//		r.RegisterCounter(fmt.Sprintf("%d", i), metrics.NewCounter())
-//		r.RegisterGauge(fmt.Sprintf("%d", i), metrics.NewGauge())
-//		r.RegisterHistogram(fmt.Sprintf("%d", i), metrics.NewHistogram(metrics.NewUniformSample(1028)))
-//		r.RegisterHistogram(fmt.Sprintf("%d", i), metrics.NewHistogram(metrics.NewExpDecaySample(1028, 0.015)))
-		r.RegisterMeter(fmt.Sprintf("%d", i), metrics.NewMeter())
+//		r.Register(fmt.Sprintf("%d", i), metrics.NewCounter())
+//		r.Register(fmt.Sprintf("%d", i), metrics.NewGauge())
+//		r.Register(fmt.Sprintf("%d", i), metrics.NewHistogram(metrics.NewUniformSample(1028)))
+//		r.Register(fmt.Sprintf("%d", i), metrics.NewHistogram(metrics.NewExpDecaySample(1028, 0.015)))
+		r.Register(fmt.Sprintf("%d", i), metrics.NewMeter())
 	}
 	time.Sleep(600e9)
 }

+ 6 - 6
cmd/metrics-example/metrics-example.go

@@ -16,7 +16,7 @@ func main() {
 	r := metrics.NewRegistry()
 
 	c := metrics.NewCounter()
-	r.RegisterCounter("foo", c)
+	r.Register("foo", c)
 	for i := 0; i < fanout; i++ {
 		go func() {
 			for {
@@ -33,7 +33,7 @@ func main() {
 	}
 
 	g := metrics.NewGauge()
-	r.RegisterGauge("bar", g)
+	r.Register("bar", g)
 	for i := 0; i < fanout; i++ {
 		go func() {
 			for {
@@ -56,12 +56,12 @@ func main() {
 			h.Unhealthy(os.NewError("baz"))
 		}
 	})
-	r.RegisterHealthcheck("baz", hc)
+	r.Register("baz", hc)
 
 	s := metrics.NewExpDecaySample(1028, 0.015)
 //	s := metrics.NewUniformSample(1028)
 	h := metrics.NewHistogram(s)
-	r.RegisterHistogram("bang", h)
+	r.Register("bang", h)
 	for i := 0; i < fanout; i++ {
 		go func() {
 			for {
@@ -78,7 +78,7 @@ func main() {
 	}
 
 	m := metrics.NewMeter()
-	r.RegisterMeter("quux", m)
+	r.Register("quux", m)
 	for i := 0; i < fanout; i++ {
 		go func() {
 			for {
@@ -95,7 +95,7 @@ func main() {
 	}
 
 	t := metrics.NewTimer()
-	r.RegisterTimer("hooah", t)
+	r.Register("hooah", t)
 	for i := 0; i < fanout; i++ {
 		go func() {
 			for {

+ 50 - 52
log.go

@@ -9,58 +9,56 @@ import (
 // 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) {
-			l.Printf("counter %s\n", name)
-			l.Printf("  count:       %9d\n", c.Count())
-		})
-		r.EachGauge(func(name string, g Gauge) {
-			l.Printf("gauge %s\n", name)
-			l.Printf("  value:       %9d\n", g.Value())
-		})
-		r.RunHealthchecks()
-		r.EachHealthcheck(func(name string, h Healthcheck) {
-			l.Printf("healthcheck %s\n", name)
-			l.Printf("  error:       %v\n", h.Error())
-		})
-		r.EachHistogram(func(name string, h Histogram) {
-			ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
-			l.Printf("histogram %s\n", name)
-			l.Printf("  count:       %9d\n", h.Count())
-			l.Printf("  min:         %9d\n", h.Min())
-			l.Printf("  max:         %9d\n", h.Max())
-			l.Printf("  mean:        %12.2f\n", h.Mean())
-			l.Printf("  stddev:      %12.2f\n", h.StdDev())
-			l.Printf("  median:      %12.2f\n", ps[0])
-			l.Printf("  75%%:         %12.2f\n", ps[1])
-			l.Printf("  95%%:         %12.2f\n", ps[2])
-			l.Printf("  99%%:         %12.2f\n", ps[3])
-			l.Printf("  99.9%%:       %12.2f\n", ps[4])
-		})
-		r.EachMeter(func(name string, m Meter) {
-			l.Printf("meter %s\n", name)
-			l.Printf("  count:       %9d\n", m.Count())
-			l.Printf("  1-min rate:  %12.2f\n", m.Rate1())
-			l.Printf("  5-min rate:  %12.2f\n", m.Rate5())
-			l.Printf("  15-min rate: %12.2f\n", m.Rate15())
-			l.Printf("  mean rate:   %12.2f\n", m.RateMean())
-		})
-		r.EachTimer(func(name string, t Timer) {
-			ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
-			l.Printf("timer %s\n", name)
-			l.Printf("  count:       %9d\n", t.Count())
-			l.Printf("  min:         %9d\n", t.Min())
-			l.Printf("  max:         %9d\n", t.Max())
-			l.Printf("  mean:        %12.2f\n", t.Mean())
-			l.Printf("  stddev:      %12.2f\n", t.StdDev())
-			l.Printf("  median:      %12.2f\n", ps[0])
-			l.Printf("  75%%:         %12.2f\n", ps[1])
-			l.Printf("  95%%:         %12.2f\n", ps[2])
-			l.Printf("  99%%:         %12.2f\n", ps[3])
-			l.Printf("  99.9%%:       %12.2f\n", ps[4])
-			l.Printf("  1-min rate:  %12.2f\n", t.Rate1())
-			l.Printf("  5-min rate:  %12.2f\n", t.Rate5())
-			l.Printf("  15-min rate: %12.2f\n", t.Rate15())
-			l.Printf("  mean rate:   %12.2f\n", t.RateMean())
+		r.Each(func(name string, i interface{}) {
+			switch m := i.(type) {
+			case Counter:
+				l.Printf("counter %s\n", name)
+				l.Printf("  count:       %9d\n", m.Count())
+			case Gauge:
+				l.Printf("gauge %s\n", name)
+				l.Printf("  value:       %9d\n", m.Value())
+			case Healthcheck:
+				m.Check()
+				l.Printf("healthcheck %s\n", name)
+				l.Printf("  error:       %v\n", m.Error())
+			case Histogram:
+				ps := m.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
+				l.Printf("histogram %s\n", name)
+				l.Printf("  count:       %9d\n", m.Count())
+				l.Printf("  min:         %9d\n", m.Min())
+				l.Printf("  max:         %9d\n", m.Max())
+				l.Printf("  mean:        %12.2f\n", m.Mean())
+				l.Printf("  stddev:      %12.2f\n", m.StdDev())
+				l.Printf("  median:      %12.2f\n", ps[0])
+				l.Printf("  75%%:         %12.2f\n", ps[1])
+				l.Printf("  95%%:         %12.2f\n", ps[2])
+				l.Printf("  99%%:         %12.2f\n", ps[3])
+				l.Printf("  99.9%%:       %12.2f\n", ps[4])
+			case Meter:
+				l.Printf("meter %s\n", name)
+				l.Printf("  count:       %9d\n", m.Count())
+				l.Printf("  1-min rate:  %12.2f\n", m.Rate1())
+				l.Printf("  5-min rate:  %12.2f\n", m.Rate5())
+				l.Printf("  15-min rate: %12.2f\n", m.Rate15())
+				l.Printf("  mean rate:   %12.2f\n", m.RateMean())
+			case Timer:
+				ps := m.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
+				l.Printf("timer %s\n", name)
+				l.Printf("  count:       %9d\n", m.Count())
+				l.Printf("  min:         %9d\n", m.Min())
+				l.Printf("  max:         %9d\n", m.Max())
+				l.Printf("  mean:        %12.2f\n", m.Mean())
+				l.Printf("  stddev:      %12.2f\n", m.StdDev())
+				l.Printf("  median:      %12.2f\n", ps[0])
+				l.Printf("  75%%:         %12.2f\n", ps[1])
+				l.Printf("  95%%:         %12.2f\n", ps[2])
+				l.Printf("  99%%:         %12.2f\n", ps[3])
+				l.Printf("  99.9%%:       %12.2f\n", ps[4])
+				l.Printf("  1-min rate:  %12.2f\n", m.Rate1())
+				l.Printf("  5-min rate:  %12.2f\n", m.Rate5())
+				l.Printf("  15-min rate: %12.2f\n", m.Rate15())
+				l.Printf("  mean rate:   %12.2f\n", m.RateMean())
+			}
 		})
 		time.Sleep(int64(1e9) * int64(interval))
 	}

+ 27 - 203
registry.go

@@ -8,241 +8,65 @@ import "sync"
 // 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))
-	EachHealthcheck(func(string, Healthcheck))
-	EachHistogram(func(string, Histogram))
-	EachMeter(func(string, Meter))
-	EachTimer(func(string, Timer))
-
-	GetCounter(string) Counter
-	GetGauge(string) Gauge
-	GetHealthcheck(string) Healthcheck
-	GetHistogram(string) Histogram
-	GetMeter(string) Meter
-	GetTimer(string) Timer
-
-	RegisterCounter(string, Counter)
-	RegisterGauge(string, Gauge)
-	RegisterHealthcheck(string, Healthcheck)
-	RegisterHistogram(string, Histogram)
-	RegisterMeter(string, Meter)
-	RegisterTimer(string, Timer)
-
+	Each(func(string, interface{}))
+	Get(string) interface{}
+	Register(string, interface{})
 	RunHealthchecks()
-
-	UnregisterCounter(string)
-	UnregisterGauge(string)
-	UnregisterHealthcheck(string)
-	UnregisterHistogram(string)
-	UnregisterMeter(string)
-	UnregisterTimer(string)
-
+	Unregister(string)
 }
 
 // The standard implementation of a Registry is a set of mutex-protected
 // maps of names to metrics.
 type StandardRegistry struct {
 	mutex *sync.Mutex
-	counters map[string]Counter
-	gauges map[string]Gauge
-	healthchecks map[string]Healthcheck
-	histograms map[string]Histogram
-	meters map[string]Meter
-	timers map[string]Timer
+	metrics map[string]interface{}
 }
 
 // Create a new registry.
 func NewRegistry() *StandardRegistry {
 	return &StandardRegistry {
 		&sync.Mutex{},
-		make(map[string]Counter),
-		make(map[string]Gauge),
-		make(map[string]Healthcheck),
-		make(map[string]Histogram),
-		make(map[string]Meter),
-		make(map[string]Timer),
+		make(map[string]interface{}),
 	}
 }
 
-// Call the given function for each registered counter.
-func (r *StandardRegistry) 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 *StandardRegistry) 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 *StandardRegistry) 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 *StandardRegistry) 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 *StandardRegistry) 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 *StandardRegistry) EachTimer(f func(string, Timer)) {
-	r.mutex.Lock()
-	for name, t := range r.timers { f(name, t) }
-	r.mutex.Unlock()
-}
-
-// Get the Counter by the given name or nil if none is registered.
-func (r *StandardRegistry) GetCounter(name string) Counter {
-	r.mutex.Lock()
-	c := r.counters[name]
-	r.mutex.Unlock()
-	return c
-}
-
-// Get the Gauge by the given name or nil if none is registered.
-func (r *StandardRegistry) GetGauge(name string) Gauge {
-	r.mutex.Lock()
-	g := r.gauges[name]
-	r.mutex.Unlock()
-	return g
-}
-
-// Get the Healthcheck by the given name or nil if none is registered.
-func (r *StandardRegistry) GetHealthcheck(name string) Healthcheck {
-	r.mutex.Lock()
-	h := r.healthchecks[name]
-	r.mutex.Unlock()
-	return h
-}
-
-// Get the Histogram by the given name or nil if none is registered.
-func (r *StandardRegistry) GetHistogram(name string) Histogram {
-	r.mutex.Lock()
-	h := r.histograms[name]
-	r.mutex.Unlock()
-	return h
-}
-
-// Get the Meter by the given name or nil if none is registered.
-func (r *StandardRegistry) GetMeter(name string) Meter {
-	r.mutex.Lock()
-	m := r.meters[name]
-	r.mutex.Unlock()
-	return m
-}
-
-// Get the Timer by the given name or nil if none is registered.
-func (r *StandardRegistry) GetTimer(name string) Timer {
-	r.mutex.Lock()
-	t := r.timers[name]
-	r.mutex.Unlock()
-	return t
-}
-
-// Register the given Counter under the given name.
-func (r *StandardRegistry) RegisterCounter(name string, c Counter) {
+// Call the given function for each registered metric.
+func (r *StandardRegistry) Each(f func(string, interface{})) {
 	r.mutex.Lock()
-	r.counters[name] = c
+	for name, i := range r.metrics { f(name, i) }
 	r.mutex.Unlock()
 }
 
-// Register the given Gauge under the given name.
-func (r *StandardRegistry) RegisterGauge(name string, g Gauge) {
+// Get the metric by the given name or nil if none is registered.
+func (r *StandardRegistry) Get(name string) interface{} {
 	r.mutex.Lock()
-	r.gauges[name] = g
+	i := r.metrics[name]
 	r.mutex.Unlock()
+	return i
 }
 
-// Register the given Healthcheck under the given name.
-func (r *StandardRegistry) 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 *StandardRegistry) 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 *StandardRegistry) 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 *StandardRegistry) RegisterTimer(name string, t Timer) {
-	r.mutex.Lock()
-	r.timers[name] = t
-	r.mutex.Unlock()
+// Register the given metric under the given name.
+func (r *StandardRegistry) Register(name string, i interface{}) {
+	switch i.(type) {
+	case Counter, Gauge, Healthcheck, Histogram, Meter, Timer:
+		r.mutex.Lock()
+		r.metrics[name] = i
+		r.mutex.Unlock()
+	}
 }
 
 // Run all registered healthchecks.
 func (r *StandardRegistry) RunHealthchecks() {
 	r.mutex.Lock()
-	for _, h := range r.healthchecks { h.Check() }
-	r.mutex.Unlock()
-}
-
-// Unregister the given Counter with the given name.
-func (r *StandardRegistry) UnregisterCounter(name string) {
-	r.mutex.Lock()
-	r.counters[name] = nil, false
-	r.mutex.Unlock()
-}
-
-// Unregister the given Gauge with the given name.
-func (r *StandardRegistry) UnregisterGauge(name string) {
-	r.mutex.Lock()
-	r.gauges[name] = nil, false
-	r.mutex.Unlock()
-}
-
-// Unregister the given Healthcheck with the given name.
-func (r *StandardRegistry) UnregisterHealthcheck(name string) {
-	r.mutex.Lock()
-	r.healthchecks[name] = nil, false
-	r.mutex.Unlock()
-}
-
-// Unregister the given Histogram with the given name.
-func (r *StandardRegistry) UnregisterHistogram(name string) {
-	r.mutex.Lock()
-	r.histograms[name] = nil, false
-	r.mutex.Unlock()
-}
-
-// Unregister the given Meter with the given name.
-func (r *StandardRegistry) UnregisterMeter(name string) {
-	r.mutex.Lock()
-	r.meters[name] = nil, false
+	for _, i := range r.metrics {
+		if h, ok := i.(Healthcheck); ok { h.Check() }
+	}
 	r.mutex.Unlock()
 }
 
-// Unregister the given Timer with the given name.
-func (r *StandardRegistry) UnregisterTimer(name string) {
+// Unregister the metric with the given name.
+func (r *StandardRegistry) Unregister(name string) {
 	r.mutex.Lock()
-	r.timers[name] = nil, false
+	r.metrics[name] = nil, false
 	r.mutex.Unlock()
 }

+ 52 - 52
runtime.go

@@ -9,36 +9,36 @@ import "runtime"
 // as runtime.Goroutines.
 func RegisterRuntimeMemStats(r Registry) {
 
-	r.RegisterGauge("runtime.Goroutines", NewGauge())
+	r.Register("runtime.Goroutines", NewGauge())
 
-	r.RegisterGauge("runtime.MemStats.Alloc", NewGauge())
-	r.RegisterGauge("runtime.MemStats.TotalAlloc", NewGauge())
-	r.RegisterGauge("runtime.MemStats.Sys", NewGauge())
-	r.RegisterGauge("runtime.MemStats.Lookups", NewGauge())
-	r.RegisterGauge("runtime.MemStats.Mallocs", NewGauge())
-	r.RegisterGauge("runtime.MemStats.Frees", NewGauge())
+	r.Register("runtime.MemStats.Alloc", NewGauge())
+	r.Register("runtime.MemStats.TotalAlloc", NewGauge())
+	r.Register("runtime.MemStats.Sys", NewGauge())
+	r.Register("runtime.MemStats.Lookups", NewGauge())
+	r.Register("runtime.MemStats.Mallocs", NewGauge())
+	r.Register("runtime.MemStats.Frees", NewGauge())
 
-	r.RegisterGauge("runtime.MemStats.HeapAlloc", NewGauge())
-	r.RegisterGauge("runtime.MemStats.HeapSys", NewGauge())
-	r.RegisterGauge("runtime.MemStats.HeapIdle", NewGauge())
-	r.RegisterGauge("runtime.MemStats.HeapInuse", NewGauge())
-	r.RegisterGauge("runtime.MemStats.HeapObjects", NewGauge())
+	r.Register("runtime.MemStats.HeapAlloc", NewGauge())
+	r.Register("runtime.MemStats.HeapSys", NewGauge())
+	r.Register("runtime.MemStats.HeapIdle", NewGauge())
+	r.Register("runtime.MemStats.HeapInuse", NewGauge())
+	r.Register("runtime.MemStats.HeapObjects", NewGauge())
 
-	r.RegisterGauge("runtime.MemStats.StackInuse", NewGauge())
-	r.RegisterGauge("runtime.MemStats.StackSys", NewGauge())
-	r.RegisterGauge("runtime.MemStats.MSpanInuse", NewGauge())
-	r.RegisterGauge("runtime.MemStats.MSpanSys", NewGauge())
-	r.RegisterGauge("runtime.MemStats.MCacheInuse", NewGauge())
-	r.RegisterGauge("runtime.MemStats.MCacheSys", NewGauge())
-	r.RegisterGauge("runtime.MemStats.BuckHashSys", NewGauge())
+	r.Register("runtime.MemStats.StackInuse", NewGauge())
+	r.Register("runtime.MemStats.StackSys", NewGauge())
+	r.Register("runtime.MemStats.MSpanInuse", NewGauge())
+	r.Register("runtime.MemStats.MSpanSys", NewGauge())
+	r.Register("runtime.MemStats.MCacheInuse", NewGauge())
+	r.Register("runtime.MemStats.MCacheSys", NewGauge())
+	r.Register("runtime.MemStats.BuckHashSys", NewGauge())
 
-	r.RegisterGauge("runtime.MemStats.NextGC", NewGauge())
-	r.RegisterGauge("runtime.MemStats.PauseTotalNs", NewGauge())
-	r.RegisterHistogram("runtime.MemStats.PauseNs",
+	r.Register("runtime.MemStats.NextGC", NewGauge())
+	r.Register("runtime.MemStats.PauseTotalNs", NewGauge())
+	r.Register("runtime.MemStats.PauseNs",
 		NewHistogram(NewExpDecaySample(1028, 0.015)))
-	r.RegisterGauge("runtime.MemStats.NumGC", NewGauge())
-	r.RegisterGauge("runtime.MemStats.EnableGC", NewGauge())
-	r.RegisterGauge("runtime.MemStats.DebugGC", NewGauge())
+	r.Register("runtime.MemStats.NumGC", NewGauge())
+	r.Register("runtime.MemStats.EnableGC", NewGauge())
+	r.Register("runtime.MemStats.DebugGC", NewGauge())
 
 }
 
@@ -53,64 +53,64 @@ func CaptureRuntimeMemStats(r Registry, updateMemStats bool) {
 		runtime.UpdateMemStats()
 	}
 
-	r.GetGauge("runtime.Goroutines").Update(int64(runtime.Goroutines()))
+	r.Get("runtime.Goroutines").(Gauge).Update(int64(runtime.Goroutines()))
 
-	r.GetGauge("runtime.MemStats.Alloc").Update(
+	r.Get("runtime.MemStats.Alloc").(Gauge).Update(
 		int64(runtime.MemStats.Alloc))
-	r.GetGauge("runtime.MemStats.TotalAlloc").Update(
+	r.Get("runtime.MemStats.TotalAlloc").(Gauge).Update(
 		int64(runtime.MemStats.TotalAlloc))
-	r.GetGauge("runtime.MemStats.Sys").Update(
+	r.Get("runtime.MemStats.Sys").(Gauge).Update(
 		int64(runtime.MemStats.Sys))
-	r.GetGauge("runtime.MemStats.Lookups").Update(
+	r.Get("runtime.MemStats.Lookups").(Gauge).Update(
 		int64(runtime.MemStats.Lookups))
-	r.GetGauge("runtime.MemStats.Mallocs").Update(
+	r.Get("runtime.MemStats.Mallocs").(Gauge).Update(
 		int64(runtime.MemStats.Mallocs))
-	r.GetGauge("runtime.MemStats.Frees").Update(
+	r.Get("runtime.MemStats.Frees").(Gauge).Update(
 		int64(runtime.MemStats.Frees))
 
-	r.GetGauge("runtime.MemStats.HeapAlloc").Update(
+	r.Get("runtime.MemStats.HeapAlloc").(Gauge).Update(
 		int64(runtime.MemStats.HeapAlloc))
-	r.GetGauge("runtime.MemStats.HeapSys").Update(
+	r.Get("runtime.MemStats.HeapSys").(Gauge).Update(
 		int64(runtime.MemStats.HeapSys))
-	r.GetGauge("runtime.MemStats.HeapIdle").Update(
+	r.Get("runtime.MemStats.HeapIdle").(Gauge).Update(
 		int64(runtime.MemStats.HeapIdle))
-	r.GetGauge("runtime.MemStats.HeapInuse").Update(
+	r.Get("runtime.MemStats.HeapInuse").(Gauge).Update(
 		int64(runtime.MemStats.HeapInuse))
-	r.GetGauge("runtime.MemStats.HeapObjects").Update(
+	r.Get("runtime.MemStats.HeapObjects").(Gauge).Update(
 		int64(runtime.MemStats.HeapObjects))
 
-	r.GetGauge("runtime.MemStats.StackInuse").Update(
+	r.Get("runtime.MemStats.StackInuse").(Gauge).Update(
 		int64(runtime.MemStats.StackInuse))
-	r.GetGauge("runtime.MemStats.StackSys").Update(
+	r.Get("runtime.MemStats.StackSys").(Gauge).Update(
 		int64(runtime.MemStats.StackSys))
-	r.GetGauge("runtime.MemStats.MSpanInuse").Update(
+	r.Get("runtime.MemStats.MSpanInuse").(Gauge).Update(
 		int64(runtime.MemStats.MSpanInuse))
-	r.GetGauge("runtime.MemStats.MSpanSys").Update(
+	r.Get("runtime.MemStats.MSpanSys").(Gauge).Update(
 		int64(runtime.MemStats.MSpanSys))
-	r.GetGauge("runtime.MemStats.MCacheInuse").Update(
+	r.Get("runtime.MemStats.MCacheInuse").(Gauge).Update(
 		int64(runtime.MemStats.MCacheInuse))
-	r.GetGauge("runtime.MemStats.MCacheSys").Update(
+	r.Get("runtime.MemStats.MCacheSys").(Gauge).Update(
 		int64(runtime.MemStats.MCacheSys))
-	r.GetGauge("runtime.MemStats.BuckHashSys").Update(
+	r.Get("runtime.MemStats.BuckHashSys").(Gauge).Update(
 		int64(runtime.MemStats.BuckHashSys))
 
-	r.GetGauge("runtime.MemStats.NextGC").Update(
+	r.Get("runtime.MemStats.NextGC").(Gauge).Update(
 		int64(runtime.MemStats.NextGC))
-	r.GetGauge("runtime.MemStats.PauseTotalNs").Update(
+	r.Get("runtime.MemStats.PauseTotalNs").(Gauge).Update(
 		int64(runtime.MemStats.PauseTotalNs))
-	r.GetHistogram("runtime.MemStats.PauseNs").Update(
+	r.Get("runtime.MemStats.PauseNs").(Histogram).Update(
 		int64(runtime.MemStats.PauseNs[0]))
-	r.GetGauge("runtime.MemStats.NumGC").Update(
+	r.Get("runtime.MemStats.NumGC").(Gauge).Update(
 		int64(runtime.MemStats.NumGC))
 	if runtime.MemStats.EnableGC {
-		r.GetGauge("runtime.MemStats.EnableGC").Update(1)
+		r.Get("runtime.MemStats.EnableGC").(Gauge).Update(1)
 	} else {
-		r.GetGauge("runtime.MemStats.EnableGC").Update(0)
+		r.Get("runtime.MemStats.EnableGC").(Gauge).Update(0)
 	}
 	if runtime.MemStats.EnableGC {
-		r.GetGauge("runtime.MemStats.DebugGC").Update(1)
+		r.Get("runtime.MemStats.DebugGC").(Gauge).Update(1)
 	} else {
-		r.GetGauge("runtime.MemStats.DebugGC").Update(0)
+		r.Get("runtime.MemStats.DebugGC").(Gauge).Update(0)
 	}
 
 }

+ 56 - 58
syslog.go

@@ -10,64 +10,62 @@ import (
 // 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) {
-			w.Info(fmt.Sprintf("counter %s: count: %d", name, c.Count()))
-		})
-		r.EachGauge(func(name string, g Gauge) {
-			w.Info(fmt.Sprintf("gauge %s: value: %d", name, g.Value()))
-		})
-		r.RunHealthchecks()
-		r.EachHealthcheck(func(name string, h Healthcheck) {
-			w.Info(fmt.Sprintf("healthcheck %s: error: %v", name, h.Error()))
-		})
-		r.EachHistogram(func(name string, h Histogram) {
-			ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
-			w.Info(fmt.Sprintf(
-				"histogram %s: count: %d min: %d max: %d mean: %.2f stddev: %.2f median: %.2f 75%%: %.2f 95%%: %.2f 99%%: %.2f 99.9%%: %.2f",
-				name,
-				h.Count(),
-				h.Min(),
-				h.Max(),
-				h.Mean(),
-				h.StdDev(),
-				ps[0],
-				ps[1],
-				ps[2],
-				ps[3],
-				ps[4],
-			))
-		})
-		r.EachMeter(func(name string, m Meter) {
-			w.Info(fmt.Sprintf(
-				"meter %s: count: %d 1-min: %.2f 5-min: %.2f 15-min: %.2f mean: %.2f",
-				name,
-				m.Count(),
-				m.Rate1(),
-				m.Rate5(),
-				m.Rate15(),
-				m.RateMean(),
-			))
-		})
-		r.EachTimer(func(name string, t Timer) {
-			ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
-			w.Info(fmt.Sprintf(
-				"timer %s: count: %d min: %d max: %d mean: %.2f stddev: %.2f median: %.2f 75%%: %.2f 95%%: %.2f 99%%: %.2f 99.9%%: %.2f 1-min: %.2f 5-min: %.2f 15-min: %.2f mean: %.2f",
-				name,
-				t.Count(),
-				t.Min(),
-				t.Max(),
-				t.Mean(),
-				t.StdDev(),
-				ps[0],
-				ps[1],
-				ps[2],
-				ps[3],
-				ps[4],
-				t.Rate1(),
-				t.Rate5(),
-				t.Rate15(),
-				t.RateMean(),
-			))
+		r.Each(func(name string, i interface{}) {
+			switch m := i.(type) {
+			case Counter:
+				w.Info(fmt.Sprintf("counter %s: count: %d", name, m.Count()))
+			case Gauge:
+				w.Info(fmt.Sprintf("gauge %s: value: %d", name, m.Value()))
+			case Healthcheck:
+				m.Check()
+				w.Info(fmt.Sprintf("healthcheck %s: error: %v", name, m.Error()))
+			case Histogram:
+				ps := m.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
+				w.Info(fmt.Sprintf(
+					"histogram %s: count: %d min: %d max: %d mean: %.2f stddev: %.2f median: %.2f 75%%: %.2f 95%%: %.2f 99%%: %.2f 99.9%%: %.2f",
+					name,
+					m.Count(),
+					m.Min(),
+					m.Max(),
+					m.Mean(),
+					m.StdDev(),
+					ps[0],
+					ps[1],
+					ps[2],
+					ps[3],
+					ps[4],
+				))
+			case Meter:
+				w.Info(fmt.Sprintf(
+					"meter %s: count: %d 1-min: %.2f 5-min: %.2f 15-min: %.2f mean: %.2f",
+					name,
+					m.Count(),
+					m.Rate1(),
+					m.Rate5(),
+					m.Rate15(),
+					m.RateMean(),
+				))
+			case Timer:
+				ps := m.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
+				w.Info(fmt.Sprintf(
+					"timer %s: count: %d min: %d max: %d mean: %.2f stddev: %.2f median: %.2f 75%%: %.2f 95%%: %.2f 99%%: %.2f 99.9%%: %.2f 1-min: %.2f 5-min: %.2f 15-min: %.2f mean: %.2f",
+					name,
+					m.Count(),
+					m.Min(),
+					m.Max(),
+					m.Mean(),
+					m.StdDev(),
+					ps[0],
+					ps[1],
+					ps[2],
+					ps[3],
+					ps[4],
+					m.Rate1(),
+					m.Rate5(),
+					m.Rate15(),
+					m.RateMean(),
+				))
+			}
 		})
 		time.Sleep(int64(1e9) * int64(interval))
 	}