Переглянути джерело

Added Log and Syslog functions that print metrics.

The formats are pretty shitty but the APIs are pretty nice.
Richard Crowley 14 роки тому
батько
коміт
0f101b213d
5 змінених файлів з 181 додано та 35 видалено
  1. 2 0
      Makefile
  2. 17 35
      cmd/metrics/metrics.go
  3. 69 0
      log.go
  4. 40 0
      registry.go
  5. 53 0
      syslog.go

+ 2 - 0
Makefile

@@ -7,10 +7,12 @@ GOFILES=\
 	gauge.go\
 	healthcheck.go\
 	histogram.go\
+	log.go\
 	meter.go\
 	metrics.go\
 	registry.go\
 	sample.go\
+	syslog.go\
 	timer.go\
 
 include $(GOROOT)/src/Make.pkg

+ 17 - 35
cmd/metrics/metrics.go

@@ -1,19 +1,22 @@
 package main
 
 import (
-	"fmt"
+	"log"
 	"metrics"
+//	"os"
+	"syslog"
 	"time"
 )
 
+const fanout = 10
+
 func main() {
 
 	r := metrics.NewRegistry()
 
-/*
 	c := metrics.NewCounter()
 	r.RegisterCounter("foo", c)
-	for i := 0; i < 1000; i++ {
+	for i := 0; i < fanout; i++ {
 		go func() {
 			for {
 				c.Dec(19)
@@ -27,16 +30,10 @@ func main() {
 			}
 		}()
 	}
-	for {
-		fmt.Printf("c.Count(): %v\n", c.Count())
-		time.Sleep(500e6)
-	}
-*/
 
-/*
 	g := metrics.NewGauge()
 	r.RegisterGauge("bar", g)
-	for i := 0; i < 1000; i++ {
+	for i := 0; i < fanout; i++ {
 		go func() {
 			for {
 				g.Update(19)
@@ -50,18 +47,12 @@ func main() {
 			}
 		}()
 	}
-	for {
-		fmt.Printf("g.Value(): %v\n", g.Value())
-		time.Sleep(500e6)
-	}
-*/
 
-/*
 	s := metrics.NewExpDecaySample(1028, 0.015)
 //	s := metrics.NewUniformSample(1028)
 	h := metrics.NewHistogram(s)
 	r.RegisterHistogram("baz", h)
-	for i := 0; i < 1000; i++ {
+	for i := 0; i < fanout; i++ {
 		go func() {
 			for {
 				h.Update(19)
@@ -75,20 +66,10 @@ func main() {
 			}
 		}()
 	}
-	for {
-		fmt.Printf(
-			"h: %v %v %v %v %v %v %v %v %v\n",
-			h.Count(), h.Sum(), h.Min(), h.Max(),
-			h.Percentile(95.0), h.Percentile(99.0), h.Percentile(99.9),
-			h.StdDev(), h.Variance(),
-		)
-		time.Sleep(500e6)
-	}
-*/
 
 	m := metrics.NewMeter()
 	r.RegisterMeter("bang", m)
-	for i := 0; i < 1000; i++ {
+	for i := 0; i < fanout; i++ {
 		go func() {
 			for {
 				m.Mark(19)
@@ -102,12 +83,13 @@ func main() {
 			}
 		}()
 	}
-	for {
-		fmt.Printf(
-			"m: %v %v %v %v %v\n",
-			m.Count(), m.Rate1(), m.Rate5(), m.Rate15(), m.RateMean(),
-		)
-		time.Sleep(500e6)
-	}
+
+//	metrics.Log(r, 60, log.New(os.Stderr, "metrics: ", log.Lmicroseconds))
+
+/*
+	w, err := syslog.Dial("unixgram", "/dev/log", syslog.LOG_INFO, "metrics")
+	if nil != err { log.Fatalln(err) }
+	metrics.Syslog(r, 60, w)
+*/
 
 }

+ 69 - 0
log.go

@@ -0,0 +1,69 @@
+package metrics
+
+import (
+	"log"
+	"time"
+)
+
+func Log(r Registry, interval int, l *log.Logger) {
+	for {
+		for name, c := range r.Counters() {
+			l.Printf("counter %s\n\tcount:\t%9d\n", name, c.Count())
+		}
+		for name, g := range r.Gauges() {
+			l.Printf("gauge %s\n\tvalue:\t%9d\n", name, g.Value())
+		}
+		for name, h := range r.Healthchecks() {
+			l.Printf("healthcheck %s TODO\n", name, h)
+		}
+		for name, h := range r.Histograms() {
+			ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
+			l.Printf(
+				`histogram %s
+	count:	%9d
+	min:	%9d
+	max:	%9d
+	mean:	%12.2f
+	stddev:	%12.2f
+	median:	%12.2f
+	75%%:	%12.2f
+	95%%:	%12.2f
+	99%%:	%12.2f
+	99.9%%:	%12.2f
+`,
+				name,
+				h.Count(),
+				h.Min(),
+				h.Max(),
+				h.Mean(),
+				h.StdDev(),
+				ps[0],
+				ps[1],
+				ps[2],
+				ps[3],
+				ps[4],
+			)
+		}
+		for name, m := range r.Meters() {
+			l.Printf(
+				`meter %s
+	count:	%9d
+	1-min:	%12.2f
+	5-min:	%12.2f
+	15-min:	%12.2f
+	mean:	%12.2f
+`,
+				name,
+				m.Count(),
+				m.Rate1(),
+				m.Rate5(),
+				m.Rate15(),
+				m.RateMean(),
+			)
+		}
+		for name, t := range r.Timers() {
+			l.Printf("timer %s TODO\n", name, t)
+		}
+		time.Sleep(int64(1e9) * int64(interval))
+	}
+}

+ 40 - 0
registry.go

@@ -1,12 +1,28 @@
 package metrics
 
 type Registry interface{
+
+	Counters() map[string]Counter
+	Gauges() map[string]Gauge
+	Healthchecks() map[string]Healthcheck
+	Histograms() map[string]Histogram
+	Meters() map[string]Meter
+	Timers() map[string]Timer
+
+	GetCounter(string) (Counter, bool)
+	GetGauge(string) (Gauge, bool)
+	GetHealthcheck(string) (Healthcheck, bool)
+	GetHistogram(string) (Histogram, bool)
+	GetMeter(string) (Meter, bool)
+	GetTimer(string) (Timer, bool)
+
 	RegisterCounter(string, Counter)
 	RegisterGauge(string, Gauge)
 	RegisterHealthcheck(string, Healthcheck)
 	RegisterHistogram(string, Histogram)
 	RegisterMeter(string, Meter)
 	RegisterTimer(string, Timer)
+
 }
 
 type registry struct {
@@ -29,6 +45,30 @@ func NewRegistry() Registry {
 	}
 }
 
+func (r *registry) Counters() map[string]Counter {
+	return r.counters
+}
+
+func (r *registry) Gauges() map[string]Gauge {
+	return r.gauges
+}
+
+func (r *registry) Healthchecks() map[string]Healthcheck {
+	return r.healthchecks
+}
+
+func (r *registry) Histograms() map[string]Histogram {
+	return r.histograms
+}
+
+func (r *registry) Meters() map[string]Meter {
+	return r.meters
+}
+
+func (r *registry) Timers() map[string]Timer {
+	return r.timers
+}
+
 func (r *registry) GetCounter(name string) (Counter, bool) {
 	c, ok := r.counters[name]
 	return c, ok

+ 53 - 0
syslog.go

@@ -0,0 +1,53 @@
+package metrics
+
+import (
+	"fmt"
+	"syslog"
+	"time"
+)
+
+func Syslog(r Registry, interval int, w *syslog.Writer) {
+	for {
+		for name, c := range r.Counters() {
+			w.Info(fmt.Sprintf("counter %s: count: %d", name, c.Count()))
+		}
+		for name, g := range r.Gauges() {
+			w.Info(fmt.Sprintf("gauge %s: value: %d", name, g.Value()))
+		}
+		for name, h := range r.Healthchecks() {
+			w.Info(fmt.Sprintf("healthcheck %s: TODO", name, h))
+		}
+		for name, h := range r.Histograms() {
+			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],
+			))
+		}
+		for name, m := range r.Meters() {
+			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(),
+			))
+		}
+		for name, t := range r.Timers() {
+			w.Info(fmt.Sprintf("timer %s: TODO", name, t))
+		}
+		time.Sleep(int64(1e9) * int64(interval))
+	}
+}