浏览代码

Merge branch 'feature/GaugeFloat64' of git://github.com/daniel-garcia/go-metrics into GaugeFloat64

Richard Crowley 11 年之前
父节点
当前提交
49285193aa
共有 14 个文件被更改,包括 177 次插入1 次删除
  1. 1 0
      cmd/metrics-bench/metrics-bench.go
  2. 17 0
      cmd/metrics-example/metrics-example.go
  3. 91 0
      gauge_float64.go
  4. 39 0
      gauge_float64_test.go
  5. 2 0
      graphite.go
  6. 8 0
      influxdb/influxdb.go
  7. 2 0
      json.go
  8. 4 0
      librato/librato.go
  9. 3 0
      log.go
  10. 2 0
      metrics_test.go
  11. 1 1
      registry.go
  12. 2 0
      stathat/stathat.go
  13. 2 0
      syslog.go
  14. 3 0
      writer.go

+ 1 - 0
cmd/metrics-bench/metrics-bench.go

@@ -11,6 +11,7 @@ func main() {
 	for i := 0; i < 10000; i++ {
 		r.Register(fmt.Sprintf("counter-%d", i), metrics.NewCounter())
 		r.Register(fmt.Sprintf("gauge-%d", i), metrics.NewGauge())
+		r.Register(fmt.Sprintf("gaugefloat64-%d", i), metrics.NewGaugeFloat64())
 		r.Register(fmt.Sprintf("histogram-uniform-%d", i), metrics.NewHistogram(metrics.NewUniformSample(1028)))
 		r.Register(fmt.Sprintf("histogram-exp-%d", i), metrics.NewHistogram(metrics.NewExpDecaySample(1028, 0.015)))
 		r.Register(fmt.Sprintf("meter-%d", i), metrics.NewMeter())

+ 17 - 0
cmd/metrics-example/metrics-example.go

@@ -51,6 +51,23 @@ func main() {
 		}()
 	}
 
+	gf := metrics.NewGaugeFloat64()
+	r.Register("barfloat64", gf)
+	for i := 0; i < fanout; i++ {
+		go func() {
+			for {
+				g.Update(19.0)
+				time.Sleep(300e6)
+			}
+		}()
+		go func() {
+			for {
+				g.Update(47.0)
+				time.Sleep(400e6)
+			}
+		}()
+	}
+
 	hc := metrics.NewHealthcheck(func(h metrics.Healthcheck) {
 		if 0 < rand.Intn(2) {
 			h.Healthy()

+ 91 - 0
gauge_float64.go

@@ -0,0 +1,91 @@
+package metrics
+
+import "sync"
+
+// GaugeFloat64s hold a float64 value that can be set arbitrarily.
+type GaugeFloat64 interface {
+	Snapshot() GaugeFloat64
+	Update(float64)
+	Value() float64
+}
+
+// GetOrRegisterGaugeFloat64 returns an existing GaugeFloat64 or constructs and registers a
+// new StandardGaugeFloat64.
+func GetOrRegisterGaugeFloat64(name string, r Registry) GaugeFloat64 {
+	if nil == r {
+		r = DefaultRegistry
+	}
+	return r.GetOrRegister(name, NewGaugeFloat64()).(GaugeFloat64)
+}
+
+// NewGaugeFloat64 constructs a new StandardGaugeFloat64.
+func NewGaugeFloat64() GaugeFloat64 {
+	if UseNilMetrics {
+		return NilGaugeFloat64{}
+	}
+	return &StandardGaugeFloat64{
+		value: 0.0,
+	}
+}
+
+// NewRegisteredGaugeFloat64 constructs and registers a new StandardGaugeFloat64.
+func NewRegisteredGaugeFloat64(name string, r Registry) GaugeFloat64 {
+	c := NewGaugeFloat64()
+	if nil == r {
+		r = DefaultRegistry
+	}
+	r.Register(name, c)
+	return c
+}
+
+// GaugeSnapshotFloat64 is a read-only copy of another GaugeFloat64.
+type GaugeSnapshotFloat64 float64
+
+// Snapshot returns the snapshot.
+func (g GaugeSnapshotFloat64) Snapshot() GaugeFloat64 { return g }
+
+// Update panics.
+func (GaugeSnapshotFloat64) Update(float64) {
+	panic("Update called on a GaugeSnapshotFloat64")
+}
+
+// Value returns the value at the time the snapshot was taken.
+func (g GaugeSnapshotFloat64) Value() float64 { return float64(g) }
+
+// NilGauge is a no-op Gauge.
+type NilGaugeFloat64 struct{}
+
+// Snapshot is a no-op.
+func (NilGaugeFloat64) Snapshot() GaugeFloat64 { return NilGaugeFloat64{} }
+
+// Update is a no-op.
+func (NilGaugeFloat64) Update(v float64) {}
+
+// Value is a no-op.
+func (NilGaugeFloat64) Value() float64 { return 0.0 }
+
+// StandardGaugeFloat64 is the standard implementation of a GaugeFloat64 and uses
+// sync.Mutex to manage a single float64 value.
+type StandardGaugeFloat64 struct {
+	value float64
+	sync.Mutex
+}
+
+// Snapshot returns a read-only copy of the gauge.
+func (g *StandardGaugeFloat64) Snapshot() GaugeFloat64 {
+	return GaugeSnapshotFloat64(g.Value())
+}
+
+// Update updates the gauge's value.
+func (g *StandardGaugeFloat64) Update(v float64) {
+	g.Lock()
+	defer g.Unlock()
+	g.value = v
+}
+
+// Value returns the gauge's current value.
+func (g *StandardGaugeFloat64) Value() float64 {
+	g.Lock()
+	defer g.Unlock()
+	return g.value
+}

+ 39 - 0
gauge_float64_test.go

@@ -0,0 +1,39 @@
+package metrics
+
+import "testing"
+
+
+func BenchmarkGuageFloat64(b *testing.B) {
+	g := NewGaugeFloat64()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		g.Update(float64(i))
+	}
+}
+
+func TestGaugeFloat64(t *testing.T) {
+	g := NewGaugeFloat64()
+	g.Update(float64(47.0))
+	if v := g.Value(); float64(47.0) != v {
+		t.Errorf("g.Value(): 47.0 != %v\n", v)
+	}
+}
+
+func TestGaugeFloat64Snapshot(t *testing.T) {
+	g := NewGaugeFloat64()
+	g.Update(float64(47.0))
+	snapshot := g.Snapshot()
+	g.Update(float64(0))
+	if v := snapshot.Value(); float64(47.0) != v {
+		t.Errorf("g.Value(): 47.0 != %v\n", v)
+	}
+}
+
+func TestGetOrRegisterGaugeFloat64(t *testing.T) {
+	r := NewRegistry()
+	NewRegisteredGaugeFloat64("foo", r).Update(float64(47.0))
+	t.Logf("registry: %v", r)
+	if g := GetOrRegisterGaugeFloat64("foo", r); float64(47.0) != g.Value() {
+		t.Fatal(g)
+	}
+}

+ 2 - 0
graphite.go

@@ -56,6 +56,8 @@ func graphite(c *GraphiteConfig) error {
 			fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, metric.Count(), now)
 		case Gauge:
 			fmt.Fprintf(w, "%s.%s.value %d %d\n", c.Prefix, name, metric.Value(), now)
+		case GaugeFloat64:
+			fmt.Fprintf(w, "%s.%s.value %f %d\n", c.Prefix, name, metric.Value(), now)
 		case Histogram:
 			h := metric.Snapshot()
 			ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})

+ 8 - 0
influxdb/influxdb.go

@@ -56,6 +56,14 @@ func send(r metrics.Registry, client *influxClient.Client) error {
 					{now, metric.Value()},
 				},
 			})
+		case metrics.GaugeFloat64:
+			series = append(series, &influxClient.Series{
+				Name:    fmt.Sprintf("%s.value", name),
+				Columns: []string{"time", "value"},
+				Points: [][]interface{}{
+					{now, metric.Value()},
+				},
+			})
 		case metrics.Histogram:
 			h := metric.Snapshot()
 			ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})

+ 2 - 0
json.go

@@ -13,6 +13,8 @@ func (r StandardRegistry) MarshalJSON() ([]byte, error) {
 			values["count"] = metric.Count()
 		case Gauge:
 			values["value"] = metric.Value()
+		case GaugeFloat64:
+			values["value"] = metric.Value()
 		case Healthcheck:
 			metric.Check()
 			values["error"] = metric.Error().Error()

+ 4 - 0
librato/librato.go

@@ -99,6 +99,10 @@ func (self *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot
 			measurement[Name] = name
 			measurement[Value] = float64(m.Value())
 			snapshot.Gauges = append(snapshot.Gauges, measurement)
+		case metrics.GaugeFloat64:
+			measurement[Name] = name
+			measurement[Value] = float64(m.Value())
+			snapshot.Gauges = append(snapshot.Gauges, measurement)
 		case metrics.Histogram:
 			if m.Count() > 0 {
 				gauges := make([]Measurement, histogramGaugeCount, histogramGaugeCount)

+ 3 - 0
log.go

@@ -17,6 +17,9 @@ func Log(r Registry, d time.Duration, l *log.Logger) {
 			case Gauge:
 				l.Printf("gauge %s\n", name)
 				l.Printf("  value:       %9d\n", metric.Value())
+			case GaugeFloat64:
+				l.Printf("gauge %s\n", name)
+				l.Printf("  value:       %f\n", metric.Value())
 			case Healthcheck:
 				metric.Check()
 				l.Printf("healthcheck %s\n", name)

+ 2 - 0
metrics_test.go

@@ -19,6 +19,7 @@ func BenchmarkMetrics(b *testing.B) {
 	r := NewRegistry()
 	c := NewRegisteredCounter("counter", r)
 	g := NewRegisteredGauge("gauge", r)
+	gf := NewRegisteredGaugeFloat64("gaugefloat64", r)
 	h := NewRegisteredHistogram("histogram", r, NewUniformSample(100))
 	m := NewRegisteredMeter("meter", r)
 	t := NewRegisteredTimer("timer", r)
@@ -90,6 +91,7 @@ func BenchmarkMetrics(b *testing.B) {
 			for i := 0; i < b.N; i++ {
 				c.Inc(1)
 				g.Update(int64(i))
+				gf.Update(float64(i))
 				h.Update(int64(i))
 				m.Mark(1)
 				t.Update(1)

+ 1 - 1
registry.go

@@ -93,7 +93,7 @@ func (r *StandardRegistry) Unregister(name string) {
 
 func (r *StandardRegistry) register(name string, i interface{}) {
 	switch i.(type) {
-	case Counter, Gauge, Healthcheck, Histogram, Meter, Timer:
+	case Counter, Gauge, GaugeFloat64, Healthcheck, Histogram, Meter, Timer:
 		r.metrics[name] = i
 	}
 }

+ 2 - 0
stathat/stathat.go

@@ -24,6 +24,8 @@ func sh(r metrics.Registry, userkey string) error {
 			stathat.PostEZCount(name, userkey, int(metric.Count()))
 		case metrics.Gauge:
 			stathat.PostEZValue(name, userkey, float64(metric.Value()))
+		case metrics.GaugeFloat64:
+			stathat.PostEZValue(name, userkey, float64(metric.Value()))
 		case metrics.Histogram:
 			h := metric.Snapshot()
 			ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})

+ 2 - 0
syslog.go

@@ -18,6 +18,8 @@ func Syslog(r Registry, d time.Duration, w *syslog.Writer) {
 				w.Info(fmt.Sprintf("counter %s: count: %d", name, metric.Count()))
 			case Gauge:
 				w.Info(fmt.Sprintf("gauge %s: value: %d", name, metric.Value()))
+			case GaugeFloat64:
+				w.Info(fmt.Sprintf("gauge %s: value: %f", name, metric.Value()))
 			case Healthcheck:
 				metric.Check()
 				w.Info(fmt.Sprintf("healthcheck %s: error: %v", name, metric.Error()))

+ 3 - 0
writer.go

@@ -24,6 +24,9 @@ func WriteOnce(r Registry, w io.Writer) {
 		case Gauge:
 			fmt.Fprintf(w, "gauge %s\n", name)
 			fmt.Fprintf(w, "  value:       %9d\n", metric.Value())
+		case GaugeFloat64:
+			fmt.Fprintf(w, "gauge %s\n", name)
+			fmt.Fprintf(w, "  value:       %f\n", metric.Value())
 		case Healthcheck:
 			metric.Check()
 			fmt.Fprintf(w, "healthcheck %s\n", name)