From f27df5c6a5b6b3c8e90ce901c2d63840a6d5adfc Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Tue, 26 Nov 2024 20:59:11 +0100 Subject: [PATCH] metrics: fix float64 gauge --- metrics/exp/exp.go | 2 +- metrics/gauge_float64.go | 65 +++++++++++---------------------- metrics/graphite.go | 2 +- metrics/influxdb/influxdb.go | 2 +- metrics/log.go | 2 +- metrics/opentsdb.go | 2 +- metrics/prometheus/collector.go | 2 +- metrics/registry.go | 4 +- metrics/syslog.go | 2 +- metrics/writer.go | 2 +- 10 files changed, 31 insertions(+), 54 deletions(-) diff --git a/metrics/exp/exp.go b/metrics/exp/exp.go index e49056c3a2..4847638f49 100644 --- a/metrics/exp/exp.go +++ b/metrics/exp/exp.go @@ -194,7 +194,7 @@ func (exp *exp) syncToExpvar() { exp.publishCounterFloat64(name, i.Snapshot()) case *metrics.Gauge: exp.publishGauge(name, i.Snapshot()) - case metrics.GaugeFloat64: + case *metrics.GaugeFloat64: exp.publishGaugeFloat64(name, i.Snapshot()) case metrics.GaugeInfo: exp.publishGaugeInfo(name, i.Snapshot()) diff --git a/metrics/gauge_float64.go b/metrics/gauge_float64.go index c1c3c6b6e6..94d6ab7784 100644 --- a/metrics/gauge_float64.go +++ b/metrics/gauge_float64.go @@ -5,35 +5,28 @@ import ( "sync/atomic" ) -type GaugeFloat64Snapshot interface { - Value() float64 -} - -// GaugeFloat64 hold a float64 value that can be set arbitrarily. -type GaugeFloat64 interface { - Snapshot() GaugeFloat64Snapshot - Update(float64) -} - // GetOrRegisterGaugeFloat64 returns an existing GaugeFloat64 or constructs and registers a -// new StandardGaugeFloat64. -func GetOrRegisterGaugeFloat64(name string, r Registry) GaugeFloat64 { +// new GaugeFloat64. +func GetOrRegisterGaugeFloat64(name string, r Registry) *GaugeFloat64 { if nil == r { r = DefaultRegistry } - return r.GetOrRegister(name, NewGaugeFloat64()).(GaugeFloat64) + return r.GetOrRegister(name, NewGaugeFloat64()).(*GaugeFloat64) } -// NewGaugeFloat64 constructs a new StandardGaugeFloat64. -func NewGaugeFloat64() GaugeFloat64 { - if !Enabled { - return NilGaugeFloat64{} - } - return &StandardGaugeFloat64{} +// GaugeFloat64Snapshot is a read-only copy of a GaugeFloat64. +type GaugeFloat64Snapshot float64 + +// Value returns the value at the time the snapshot was taken. +func (g GaugeFloat64Snapshot) Value() float64 { return float64(g) } + +// NewGaugeFloat64 constructs a new GaugeFloat64. +func NewGaugeFloat64() *GaugeFloat64 { + return new(GaugeFloat64) } -// NewRegisteredGaugeFloat64 constructs and registers a new StandardGaugeFloat64. -func NewRegisteredGaugeFloat64(name string, r Registry) GaugeFloat64 { +// NewRegisteredGaugeFloat64 constructs and registers a new GaugeFloat64. +func NewRegisteredGaugeFloat64(name string, r Registry) *GaugeFloat64 { c := NewGaugeFloat64() if nil == r { r = DefaultRegistry @@ -42,32 +35,16 @@ func NewRegisteredGaugeFloat64(name string, r Registry) GaugeFloat64 { return c } -// gaugeFloat64Snapshot is a read-only copy of another GaugeFloat64. -type gaugeFloat64Snapshot float64 - -// Value returns the value at the time the snapshot was taken. -func (g gaugeFloat64Snapshot) Value() float64 { return float64(g) } - -// NilGaugeFloat64 is a no-op Gauge. -type NilGaugeFloat64 struct{} - -func (NilGaugeFloat64) Snapshot() GaugeFloat64Snapshot { return NilGaugeFloat64{} } -func (NilGaugeFloat64) Update(v float64) {} -func (NilGaugeFloat64) Value() float64 { return 0.0 } - -// StandardGaugeFloat64 is the standard implementation of a GaugeFloat64 and uses -// atomic to manage a single float64 value. -type StandardGaugeFloat64 struct { - floatBits atomic.Uint64 -} +// GaugeFloat64 and uses atomic to manage a single float64 value. +type GaugeFloat64 atomic.Uint64 // Snapshot returns a read-only copy of the gauge. -func (g *StandardGaugeFloat64) Snapshot() GaugeFloat64Snapshot { - v := math.Float64frombits(g.floatBits.Load()) - return gaugeFloat64Snapshot(v) +func (g *GaugeFloat64) Snapshot() GaugeFloat64Snapshot { + v := math.Float64frombits((*atomic.Uint64)(g).Load()) + return GaugeFloat64Snapshot(v) } // Update updates the gauge's value. -func (g *StandardGaugeFloat64) Update(v float64) { - g.floatBits.Store(math.Float64bits(v)) +func (g *GaugeFloat64) Update(v float64) { + (*atomic.Uint64)(g).Store(math.Float64bits(v)) } diff --git a/metrics/graphite.go b/metrics/graphite.go index c8b27a35ef..307fbe7ded 100644 --- a/metrics/graphite.go +++ b/metrics/graphite.go @@ -71,7 +71,7 @@ func graphite(c *GraphiteConfig) error { fmt.Fprintf(w, "%s.%s.count %f %d\n", c.Prefix, name, metric.Snapshot().Count(), now) case *Gauge: fmt.Fprintf(w, "%s.%s.value %d %d\n", c.Prefix, name, metric.Snapshot().Value(), now) - case GaugeFloat64: + case *GaugeFloat64: fmt.Fprintf(w, "%s.%s.value %f %d\n", c.Prefix, name, metric.Snapshot().Value(), now) case GaugeInfo: fmt.Fprintf(w, "%s.%s.value %s %d\n", c.Prefix, name, metric.Snapshot().Value().String(), now) diff --git a/metrics/influxdb/influxdb.go b/metrics/influxdb/influxdb.go index bf78165fc4..fd5ca56fda 100644 --- a/metrics/influxdb/influxdb.go +++ b/metrics/influxdb/influxdb.go @@ -26,7 +26,7 @@ func readMeter(namespace, name string, i interface{}) (string, map[string]interf "value": metric.Snapshot().Value(), } return measurement, fields - case metrics.GaugeFloat64: + case *metrics.GaugeFloat64: measurement := fmt.Sprintf("%s%s.gauge", namespace, name) fields := map[string]interface{}{ "value": metric.Snapshot().Value(), diff --git a/metrics/log.go b/metrics/log.go index 88fc00097e..99e775c805 100644 --- a/metrics/log.go +++ b/metrics/log.go @@ -30,7 +30,7 @@ func LogScaled(r Registry, freq time.Duration, scale time.Duration, l Logger) { case *Gauge: l.Printf("gauge %s\n", name) l.Printf(" value: %9d\n", metric.Snapshot().Value()) - case GaugeFloat64: + case *GaugeFloat64: l.Printf("gauge %s\n", name) l.Printf(" value: %f\n", metric.Snapshot().Value()) case GaugeInfo: diff --git a/metrics/opentsdb.go b/metrics/opentsdb.go index d352e03875..03b8b06283 100644 --- a/metrics/opentsdb.go +++ b/metrics/opentsdb.go @@ -70,7 +70,7 @@ func (c *OpenTSDBConfig) writeRegistry(w io.Writer, now int64, shortHostname str fmt.Fprintf(w, "put %s.%s.count %d %f host=%s\n", c.Prefix, name, now, metric.Snapshot().Count(), shortHostname) case *Gauge: fmt.Fprintf(w, "put %s.%s.value %d %d host=%s\n", c.Prefix, name, now, metric.Snapshot().Value(), shortHostname) - case GaugeFloat64: + case *GaugeFloat64: fmt.Fprintf(w, "put %s.%s.value %d %f host=%s\n", c.Prefix, name, now, metric.Snapshot().Value(), shortHostname) case GaugeInfo: fmt.Fprintf(w, "put %s.%s.value %d %s host=%s\n", c.Prefix, name, now, metric.Snapshot().Value().String(), shortHostname) diff --git a/metrics/prometheus/collector.go b/metrics/prometheus/collector.go index 7115c2ddd3..8fa46499e6 100644 --- a/metrics/prometheus/collector.go +++ b/metrics/prometheus/collector.go @@ -57,7 +57,7 @@ func (c *collector) Add(name string, i any) error { c.addCounterFloat64(name, m.Snapshot()) case *metrics.Gauge: c.addGauge(name, m.Snapshot()) - case metrics.GaugeFloat64: + case *metrics.GaugeFloat64: c.addGaugeFloat64(name, m.Snapshot()) case metrics.GaugeInfo: c.addGaugeInfo(name, m.Snapshot()) diff --git a/metrics/registry.go b/metrics/registry.go index d63d3369b9..05367c4c71 100644 --- a/metrics/registry.go +++ b/metrics/registry.go @@ -155,7 +155,7 @@ func (r *StandardRegistry) GetAll() map[string]map[string]interface{} { values["count"] = metric.Snapshot().Count() case *Gauge: values["value"] = metric.Snapshot().Value() - case GaugeFloat64: + case *GaugeFloat64: values["value"] = metric.Snapshot().Value() case Healthcheck: values["error"] = nil @@ -214,7 +214,7 @@ func (r *StandardRegistry) Unregister(name string) { func (r *StandardRegistry) loadOrRegister(name string, i interface{}) (interface{}, bool, bool) { switch i.(type) { - case *Counter, *CounterFloat64, *Gauge, GaugeFloat64, GaugeInfo, Healthcheck, Histogram, Meter, Timer, ResettingTimer: + case *Counter, *CounterFloat64, *Gauge, *GaugeFloat64, GaugeInfo, Healthcheck, Histogram, Meter, Timer, ResettingTimer: default: return nil, false, false } diff --git a/metrics/syslog.go b/metrics/syslog.go index d235e69917..ffcd9735bc 100644 --- a/metrics/syslog.go +++ b/metrics/syslog.go @@ -21,7 +21,7 @@ func Syslog(r Registry, d time.Duration, w *syslog.Writer) { w.Info(fmt.Sprintf("counter %s: count: %f", name, metric.Snapshot().Count())) case *Gauge: w.Info(fmt.Sprintf("gauge %s: value: %d", name, metric.Snapshot().Value())) - case GaugeFloat64: + case *GaugeFloat64: w.Info(fmt.Sprintf("gauge %s: value: %f", name, metric.Snapshot().Value())) case GaugeInfo: w.Info(fmt.Sprintf("gauge %s: value: %s", name, metric.Snapshot().Value())) diff --git a/metrics/writer.go b/metrics/writer.go index bde860af83..0d6ca85708 100644 --- a/metrics/writer.go +++ b/metrics/writer.go @@ -35,7 +35,7 @@ func WriteOnce(r Registry, w io.Writer) { case *Gauge: fmt.Fprintf(w, "gauge %s\n", namedMetric.name) fmt.Fprintf(w, " value: %9d\n", metric.Snapshot().Value()) - case GaugeFloat64: + case *GaugeFloat64: fmt.Fprintf(w, "gauge %s\n", namedMetric.name) fmt.Fprintf(w, " value: %f\n", metric.Snapshot().Value()) case GaugeInfo: