metrics: remove Counter interfaces

This commit is contained in:
Martin Holst Swende 2024-11-26 18:53:07 +01:00
parent 915248cd6b
commit d2a3d9a775
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
13 changed files with 40 additions and 94 deletions

View file

@ -4,109 +4,56 @@ import (
"sync/atomic"
)
type CounterSnapshot interface {
Count() int64
}
// Counter hold an int64 value that can be incremented and decremented.
type Counter interface {
Clear()
Dec(int64)
Inc(int64)
Snapshot() CounterSnapshot
}
// GetOrRegisterCounter returns an existing Counter or constructs and registers
// a new StandardCounter.
func GetOrRegisterCounter(name string, r Registry) Counter {
if nil == r {
// a new Counter.
func GetOrRegisterCounter(name string, r Registry) *Counter {
if r == nil {
r = DefaultRegistry
}
return r.GetOrRegister(name, NewCounter).(Counter)
return r.GetOrRegister(name, NewCounter).(*Counter)
}
// GetOrRegisterCounterForced returns an existing Counter or constructs and registers a
// new Counter no matter the global switch is enabled or not.
// Be sure to unregister the counter from the registry once it is of no use to
// allow for garbage collection.
func GetOrRegisterCounterForced(name string, r Registry) Counter {
if nil == r {
r = DefaultRegistry
}
return r.GetOrRegister(name, NewCounterForced).(Counter)
// NewCounter constructs a new Counter.
func NewCounter() *Counter {
return new(Counter)
}
// NewCounter constructs a new StandardCounter.
func NewCounter() Counter {
if !Enabled {
return NilCounter{}
}
return new(StandardCounter)
}
// NewCounterForced constructs a new StandardCounter and returns it no matter if
// the global switch is enabled or not.
func NewCounterForced() Counter {
return new(StandardCounter)
}
// NewRegisteredCounter constructs and registers a new StandardCounter.
func NewRegisteredCounter(name string, r Registry) Counter {
// NewRegisteredCounter constructs and registers a new Counter.
func NewRegisteredCounter(name string, r Registry) *Counter {
c := NewCounter()
if nil == r {
if r == nil {
r = DefaultRegistry
}
r.Register(name, c)
return c
}
// NewRegisteredCounterForced constructs and registers a new StandardCounter
// and launches a goroutine no matter the global switch is enabled or not.
// Be sure to unregister the counter from the registry once it is of no use to
// allow for garbage collection.
func NewRegisteredCounterForced(name string, r Registry) Counter {
c := NewCounterForced()
if nil == r {
r = DefaultRegistry
}
r.Register(name, c)
return c
}
// counterSnapshot is a read-only copy of another Counter.
type counterSnapshot int64
// CounterSnapshot is a read-only copy of a Counter.
type CounterSnapshot int64
// Count returns the count at the time the snapshot was taken.
func (c counterSnapshot) Count() int64 { return int64(c) }
func (c CounterSnapshot) Count() int64 { return int64(c) }
// NilCounter is a no-op Counter.
type NilCounter struct{}
func (NilCounter) Clear() {}
func (NilCounter) Dec(i int64) {}
func (NilCounter) Inc(i int64) {}
func (NilCounter) Snapshot() CounterSnapshot { return (*emptySnapshot)(nil) }
// StandardCounter is the standard implementation of a Counter and uses the
// Counter is the standard implementation of a Counter and uses the
// sync/atomic package to manage a single int64 value.
type StandardCounter atomic.Int64
type Counter atomic.Int64
// Clear sets the counter to zero.
func (c *StandardCounter) Clear() {
func (c *Counter) Clear() {
(*atomic.Int64)(c).Store(0)
}
// Dec decrements the counter by the given amount.
func (c *StandardCounter) Dec(i int64) {
func (c *Counter) Dec(i int64) {
(*atomic.Int64)(c).Add(-i)
}
// Inc increments the counter by the given amount.
func (c *StandardCounter) Inc(i int64) {
func (c *Counter) Inc(i int64) {
(*atomic.Int64)(c).Add(i)
}
// Snapshot returns a read-only copy of the counter.
func (c *StandardCounter) Snapshot() CounterSnapshot {
return counterSnapshot((*atomic.Int64)(c).Load())
func (c *Counter) Snapshot() CounterSnapshot {
return CounterSnapshot((*atomic.Int64)(c).Load())
}

View file

@ -188,7 +188,7 @@ func (exp *exp) publishResettingTimer(name string, metric metrics.ResettingTimer
func (exp *exp) syncToExpvar() {
exp.registry.Each(func(name string, i interface{}) {
switch i := i.(type) {
case metrics.Counter:
case *metrics.Counter:
exp.publishCounter(name, i.Snapshot())
case metrics.CounterFloat64:
exp.publishCounterFloat64(name, i.Snapshot())

View file

@ -65,7 +65,7 @@ func graphite(c *GraphiteConfig) error {
w := bufio.NewWriter(conn)
c.Registry.Each(func(name string, i interface{}) {
switch metric := i.(type) {
case Counter:
case *Counter:
fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, metric.Snapshot().Count(), now)
case CounterFloat64:
fmt.Fprintf(w, "%s.%s.count %f %d\n", c.Prefix, name, metric.Snapshot().Count(), now)

View file

@ -20,7 +20,6 @@ package metrics
var (
_ SampleSnapshot = (*emptySnapshot)(nil)
_ HistogramSnapshot = (*emptySnapshot)(nil)
_ CounterSnapshot = (*emptySnapshot)(nil)
_ GaugeSnapshot = (*emptySnapshot)(nil)
_ MeterSnapshot = (*emptySnapshot)(nil)
_ EWMASnapshot = (*emptySnapshot)(nil)

View file

@ -8,7 +8,7 @@ import (
func readMeter(namespace, name string, i interface{}) (string, map[string]interface{}) {
switch metric := i.(type) {
case metrics.Counter:
case *metrics.Counter:
measurement := fmt.Sprintf("%s%s.count", namespace, name)
fields := map[string]interface{}{
"value": metric.Snapshot().Count(),

View file

@ -21,7 +21,7 @@ func LogScaled(r Registry, freq time.Duration, scale time.Duration, l Logger) {
for range time.Tick(freq) {
r.Each(func(name string, i interface{}) {
switch metric := i.(type) {
case Counter:
case *Counter:
l.Printf("counter %s\n", name)
l.Printf(" count: %9d\n", metric.Snapshot().Count())
case CounterFloat64:

View file

@ -64,7 +64,7 @@ func (c *OpenTSDBConfig) writeRegistry(w io.Writer, now int64, shortHostname str
c.Registry.Each(func(name string, i interface{}) {
switch metric := i.(type) {
case Counter:
case *Counter:
fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, metric.Snapshot().Count(), shortHostname)
case CounterFloat64:
fmt.Fprintf(w, "put %s.%s.count %d %f host=%s\n", c.Prefix, name, now, metric.Snapshot().Count(), shortHostname)

View file

@ -51,7 +51,7 @@ func newCollector() *collector {
// metric type is not supported/known.
func (c *collector) Add(name string, i any) error {
switch m := i.(type) {
case metrics.Counter:
case *metrics.Counter:
c.addCounter(name, m.Snapshot())
case metrics.CounterFloat64:
c.addCounterFloat64(name, m.Snapshot())

View file

@ -149,7 +149,7 @@ func (r *StandardRegistry) GetAll() map[string]map[string]interface{} {
r.Each(func(name string, i interface{}) {
values := make(map[string]interface{})
switch metric := i.(type) {
case Counter:
case *Counter:
values["count"] = metric.Snapshot().Count()
case CounterFloat64:
values["count"] = metric.Snapshot().Count()
@ -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
}

View file

@ -47,7 +47,7 @@ func TestRegistry(t *testing.T) {
if name != "foo" {
t.Fatal(name)
}
if _, ok := iface.(Counter); !ok {
if _, ok := iface.(*Counter); !ok {
t.Fatal(iface)
}
})
@ -73,7 +73,7 @@ func TestRegistryDuplicate(t *testing.T) {
i := 0
r.Each(func(name string, iface interface{}) {
i++
if _, ok := iface.(Counter); !ok {
if _, ok := iface.(*Counter); !ok {
t.Fatal(iface)
}
})
@ -85,11 +85,11 @@ func TestRegistryDuplicate(t *testing.T) {
func TestRegistryGet(t *testing.T) {
r := NewRegistry()
r.Register("foo", NewCounter())
if count := r.Get("foo").(Counter).Snapshot().Count(); count != 0 {
if count := r.Get("foo").(*Counter).Snapshot().Count(); count != 0 {
t.Fatal(count)
}
r.Get("foo").(Counter).Inc(1)
if count := r.Get("foo").(Counter).Snapshot().Count(); count != 1 {
r.Get("foo").(*Counter).Inc(1)
if count := r.Get("foo").(*Counter).Snapshot().Count(); count != 1 {
t.Fatal(count)
}
}
@ -100,7 +100,7 @@ func TestRegistryGetOrRegister(t *testing.T) {
// First metric wins with GetOrRegister
_ = r.GetOrRegister("foo", NewCounter())
m := r.GetOrRegister("foo", NewGauge())
if _, ok := m.(Counter); !ok {
if _, ok := m.(*Counter); !ok {
t.Fatal(m)
}
@ -110,7 +110,7 @@ func TestRegistryGetOrRegister(t *testing.T) {
if name != "foo" {
t.Fatal(name)
}
if _, ok := iface.(Counter); !ok {
if _, ok := iface.(*Counter); !ok {
t.Fatal(iface)
}
})
@ -125,7 +125,7 @@ func TestRegistryGetOrRegisterWithLazyInstantiation(t *testing.T) {
// First metric wins with GetOrRegister
_ = r.GetOrRegister("foo", NewCounter)
m := r.GetOrRegister("foo", NewGauge)
if _, ok := m.(Counter); !ok {
if _, ok := m.(*Counter); !ok {
t.Fatal(m)
}
@ -135,7 +135,7 @@ func TestRegistryGetOrRegisterWithLazyInstantiation(t *testing.T) {
if name != "foo" {
t.Fatal(name)
}
if _, ok := iface.(Counter); !ok {
if _, ok := iface.(*Counter); !ok {
t.Fatal(iface)
}
})

View file

@ -15,7 +15,7 @@ func Syslog(r Registry, d time.Duration, w *syslog.Writer) {
for range time.Tick(d) {
r.Each(func(name string, i interface{}) {
switch metric := i.(type) {
case Counter:
case *Counter:
w.Info(fmt.Sprintf("counter %s: count: %d", name, metric.Snapshot().Count()))
case CounterFloat64:
w.Info(fmt.Sprintf("counter %s: count: %f", name, metric.Snapshot().Count()))

View file

@ -26,7 +26,7 @@ func WriteOnce(r Registry, w io.Writer) {
slices.SortFunc(namedMetrics, namedMetric.cmp)
for _, namedMetric := range namedMetrics {
switch metric := namedMetric.m.(type) {
case Counter:
case *Counter:
fmt.Fprintf(w, "counter %s\n", namedMetric.name)
fmt.Fprintf(w, " count: %9d\n", metric.Snapshot().Count())
case CounterFloat64:

View file

@ -34,7 +34,7 @@ const (
)
var (
bucketsCounter []metrics.Counter
bucketsCounter []*metrics.Counter
ingressTrafficMeter = metrics.NewRegisteredMeter(ingressMeterName, nil)
egressTrafficMeter = metrics.NewRegisteredMeter(egressMeterName, nil)
)