mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-14 03:56:36 +00:00
metrics: remove use of reflect in metrics registration code (#31962)
Co-authored-by: Marius van der Wijden <m.vanderwijden@live.de>
This commit is contained in:
parent
999f09f8af
commit
ece4b48d84
12 changed files with 37 additions and 74 deletions
|
|
@ -7,10 +7,7 @@ import (
|
||||||
// GetOrRegisterCounter returns an existing Counter or constructs and registers
|
// GetOrRegisterCounter returns an existing Counter or constructs and registers
|
||||||
// a new Counter.
|
// a new Counter.
|
||||||
func GetOrRegisterCounter(name string, r Registry) *Counter {
|
func GetOrRegisterCounter(name string, r Registry) *Counter {
|
||||||
if r == nil {
|
return getOrRegister(name, NewCounter, r)
|
||||||
r = DefaultRegistry
|
|
||||||
}
|
|
||||||
return r.GetOrRegister(name, NewCounter).(*Counter)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCounter constructs a new Counter.
|
// NewCounter constructs a new Counter.
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,7 @@ import (
|
||||||
// GetOrRegisterCounterFloat64 returns an existing *CounterFloat64 or constructs and registers
|
// GetOrRegisterCounterFloat64 returns an existing *CounterFloat64 or constructs and registers
|
||||||
// a new CounterFloat64.
|
// a new CounterFloat64.
|
||||||
func GetOrRegisterCounterFloat64(name string, r Registry) *CounterFloat64 {
|
func GetOrRegisterCounterFloat64(name string, r Registry) *CounterFloat64 {
|
||||||
if nil == r {
|
return getOrRegister(name, NewCounterFloat64, r)
|
||||||
r = DefaultRegistry
|
|
||||||
}
|
|
||||||
return r.GetOrRegister(name, NewCounterFloat64).(*CounterFloat64)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCounterFloat64 constructs a new CounterFloat64.
|
// NewCounterFloat64 constructs a new CounterFloat64.
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,7 @@ func (g GaugeSnapshot) Value() int64 { return int64(g) }
|
||||||
// GetOrRegisterGauge returns an existing Gauge or constructs and registers a
|
// GetOrRegisterGauge returns an existing Gauge or constructs and registers a
|
||||||
// new Gauge.
|
// new Gauge.
|
||||||
func GetOrRegisterGauge(name string, r Registry) *Gauge {
|
func GetOrRegisterGauge(name string, r Registry) *Gauge {
|
||||||
if r == nil {
|
return getOrRegister(name, NewGauge, r)
|
||||||
r = DefaultRegistry
|
|
||||||
}
|
|
||||||
return r.GetOrRegister(name, NewGauge).(*Gauge)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGauge constructs a new Gauge.
|
// NewGauge constructs a new Gauge.
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,7 @@ import (
|
||||||
// GetOrRegisterGaugeFloat64 returns an existing GaugeFloat64 or constructs and registers a
|
// GetOrRegisterGaugeFloat64 returns an existing GaugeFloat64 or constructs and registers a
|
||||||
// new GaugeFloat64.
|
// new GaugeFloat64.
|
||||||
func GetOrRegisterGaugeFloat64(name string, r Registry) *GaugeFloat64 {
|
func GetOrRegisterGaugeFloat64(name string, r Registry) *GaugeFloat64 {
|
||||||
if nil == r {
|
return getOrRegister(name, NewGaugeFloat64, r)
|
||||||
r = DefaultRegistry
|
|
||||||
}
|
|
||||||
return r.GetOrRegister(name, NewGaugeFloat64()).(*GaugeFloat64)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GaugeFloat64Snapshot is a read-only copy of a GaugeFloat64.
|
// GaugeFloat64Snapshot is a read-only copy of a GaugeFloat64.
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,7 @@ func (val GaugeInfoValue) String() string {
|
||||||
// GetOrRegisterGaugeInfo returns an existing GaugeInfo or constructs and registers a
|
// GetOrRegisterGaugeInfo returns an existing GaugeInfo or constructs and registers a
|
||||||
// new GaugeInfo.
|
// new GaugeInfo.
|
||||||
func GetOrRegisterGaugeInfo(name string, r Registry) *GaugeInfo {
|
func GetOrRegisterGaugeInfo(name string, r Registry) *GaugeInfo {
|
||||||
if nil == r {
|
return getOrRegister(name, NewGaugeInfo, r)
|
||||||
r = DefaultRegistry
|
|
||||||
}
|
|
||||||
return r.GetOrRegister(name, NewGaugeInfo()).(*GaugeInfo)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGaugeInfo constructs a new GaugeInfo.
|
// NewGaugeInfo constructs a new GaugeInfo.
|
||||||
|
|
|
||||||
|
|
@ -23,19 +23,13 @@ type Histogram interface {
|
||||||
// GetOrRegisterHistogram returns an existing Histogram or constructs and
|
// GetOrRegisterHistogram returns an existing Histogram or constructs and
|
||||||
// registers a new StandardHistogram.
|
// registers a new StandardHistogram.
|
||||||
func GetOrRegisterHistogram(name string, r Registry, s Sample) Histogram {
|
func GetOrRegisterHistogram(name string, r Registry, s Sample) Histogram {
|
||||||
if nil == r {
|
return getOrRegister(name, func() Histogram { return NewHistogram(s) }, r)
|
||||||
r = DefaultRegistry
|
|
||||||
}
|
|
||||||
return r.GetOrRegister(name, func() Histogram { return NewHistogram(s) }).(Histogram)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOrRegisterHistogramLazy returns an existing Histogram or constructs and
|
// GetOrRegisterHistogramLazy returns an existing Histogram or constructs and
|
||||||
// registers a new StandardHistogram.
|
// registers a new StandardHistogram.
|
||||||
func GetOrRegisterHistogramLazy(name string, r Registry, s func() Sample) Histogram {
|
func GetOrRegisterHistogramLazy(name string, r Registry, s func() Sample) Histogram {
|
||||||
if nil == r {
|
return getOrRegister(name, func() Histogram { return NewHistogram(s()) }, r)
|
||||||
r = DefaultRegistry
|
|
||||||
}
|
|
||||||
return r.GetOrRegister(name, func() Histogram { return NewHistogram(s()) }).(Histogram)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHistogram constructs a new StandardHistogram from a Sample.
|
// NewHistogram constructs a new StandardHistogram from a Sample.
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,7 @@ import (
|
||||||
// Be sure to unregister the meter from the registry once it is of no use to
|
// Be sure to unregister the meter from the registry once it is of no use to
|
||||||
// allow for garbage collection.
|
// allow for garbage collection.
|
||||||
func GetOrRegisterMeter(name string, r Registry) *Meter {
|
func GetOrRegisterMeter(name string, r Registry) *Meter {
|
||||||
if r == nil {
|
return getOrRegister(name, NewMeter, r)
|
||||||
r = DefaultRegistry
|
|
||||||
}
|
|
||||||
return r.GetOrRegister(name, NewMeter).(*Meter)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMeter constructs a new Meter and launches a goroutine.
|
// NewMeter constructs a new Meter and launches a goroutine.
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package metrics
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
@ -30,10 +29,9 @@ type Registry interface {
|
||||||
// GetAll metrics in the Registry.
|
// GetAll metrics in the Registry.
|
||||||
GetAll() map[string]map[string]interface{}
|
GetAll() map[string]map[string]interface{}
|
||||||
|
|
||||||
// GetOrRegister gets an existing metric or registers the given one.
|
// GetOrRegister returns an existing metric or registers the one returned
|
||||||
// The interface can be the metric to register if not found in registry,
|
// by the given constructor.
|
||||||
// or a function returning the metric for lazy instantiation.
|
GetOrRegister(string, func() interface{}) interface{}
|
||||||
GetOrRegister(string, interface{}) interface{}
|
|
||||||
|
|
||||||
// Register the given metric under the given name.
|
// Register the given metric under the given name.
|
||||||
Register(string, interface{}) error
|
Register(string, interface{}) error
|
||||||
|
|
@ -95,19 +93,13 @@ func (r *StandardRegistry) Get(name string) interface{} {
|
||||||
// alternative to calling Get and Register on failure.
|
// alternative to calling Get and Register on failure.
|
||||||
// The interface can be the metric to register if not found in registry,
|
// The interface can be the metric to register if not found in registry,
|
||||||
// or a function returning the metric for lazy instantiation.
|
// or a function returning the metric for lazy instantiation.
|
||||||
func (r *StandardRegistry) GetOrRegister(name string, i interface{}) interface{} {
|
func (r *StandardRegistry) GetOrRegister(name string, ctor func() interface{}) interface{} {
|
||||||
// fast path
|
// fast path
|
||||||
cached, ok := r.metrics.Load(name)
|
cached, ok := r.metrics.Load(name)
|
||||||
if ok {
|
if ok {
|
||||||
return cached
|
return cached
|
||||||
}
|
}
|
||||||
if v := reflect.ValueOf(i); v.Kind() == reflect.Func {
|
item, _, _ := r.loadOrRegister(name, ctor())
|
||||||
i = v.Call(nil)[0].Interface()
|
|
||||||
}
|
|
||||||
item, _, ok := r.loadOrRegister(name, i)
|
|
||||||
if !ok {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,9 +112,6 @@ func (r *StandardRegistry) Register(name string, i interface{}) error {
|
||||||
return fmt.Errorf("%w: %v", ErrDuplicateMetric, name)
|
return fmt.Errorf("%w: %v", ErrDuplicateMetric, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if v := reflect.ValueOf(i); v.Kind() == reflect.Func {
|
|
||||||
i = v.Call(nil)[0].Interface()
|
|
||||||
}
|
|
||||||
_, loaded, _ := r.loadOrRegister(name, i)
|
_, loaded, _ := r.loadOrRegister(name, i)
|
||||||
if loaded {
|
if loaded {
|
||||||
return fmt.Errorf("%w: %v", ErrDuplicateMetric, name)
|
return fmt.Errorf("%w: %v", ErrDuplicateMetric, name)
|
||||||
|
|
@ -295,9 +284,9 @@ func (r *PrefixedRegistry) Get(name string) interface{} {
|
||||||
// GetOrRegister gets an existing metric or registers the given one.
|
// GetOrRegister gets an existing metric or registers the given one.
|
||||||
// The interface can be the metric to register if not found in registry,
|
// The interface can be the metric to register if not found in registry,
|
||||||
// or a function returning the metric for lazy instantiation.
|
// or a function returning the metric for lazy instantiation.
|
||||||
func (r *PrefixedRegistry) GetOrRegister(name string, metric interface{}) interface{} {
|
func (r *PrefixedRegistry) GetOrRegister(name string, ctor func() interface{}) interface{} {
|
||||||
realName := r.prefix + name
|
realName := r.prefix + name
|
||||||
return r.underlying.GetOrRegister(realName, metric)
|
return r.underlying.GetOrRegister(realName, ctor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register the given metric under the given name. The name will be prefixed.
|
// Register the given metric under the given name. The name will be prefixed.
|
||||||
|
|
@ -338,10 +327,17 @@ func Get(name string) interface{} {
|
||||||
|
|
||||||
// GetOrRegister gets an existing metric or creates and registers a new one. Threadsafe
|
// GetOrRegister gets an existing metric or creates and registers a new one. Threadsafe
|
||||||
// alternative to calling Get and Register on failure.
|
// alternative to calling Get and Register on failure.
|
||||||
func GetOrRegister(name string, i interface{}) interface{} {
|
func GetOrRegister(name string, i func() interface{}) interface{} {
|
||||||
return DefaultRegistry.GetOrRegister(name, i)
|
return DefaultRegistry.GetOrRegister(name, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getOrRegister[T any](name string, ctor func() T, r Registry) T {
|
||||||
|
if r == nil {
|
||||||
|
r = DefaultRegistry
|
||||||
|
}
|
||||||
|
return r.GetOrRegister(name, func() any { return ctor() }).(T)
|
||||||
|
}
|
||||||
|
|
||||||
// Register the given metric under the given name. Returns a ErrDuplicateMetric
|
// Register the given metric under the given name. Returns a ErrDuplicateMetric
|
||||||
// if a metric by the given name is already registered.
|
// if a metric by the given name is already registered.
|
||||||
func Register(name string, i interface{}) error {
|
func Register(name string, i interface{}) error {
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ func benchmarkRegistryGetOrRegisterParallel(b *testing.B, amount int) {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
r.GetOrRegister("foo", NewMeter)
|
GetOrRegisterMeter("foo", r)
|
||||||
}
|
}
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
|
|
@ -98,10 +98,10 @@ func TestRegistryGetOrRegister(t *testing.T) {
|
||||||
r := NewRegistry()
|
r := NewRegistry()
|
||||||
|
|
||||||
// First metric wins with GetOrRegister
|
// First metric wins with GetOrRegister
|
||||||
_ = r.GetOrRegister("foo", NewCounter())
|
c1 := GetOrRegisterCounter("foo", r)
|
||||||
m := r.GetOrRegister("foo", NewGauge())
|
c2 := GetOrRegisterCounter("foo", r)
|
||||||
if _, ok := m.(*Counter); !ok {
|
if c1 != c2 {
|
||||||
t.Fatal(m)
|
t.Fatal("counters should've matched")
|
||||||
}
|
}
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
|
|
@ -123,10 +123,10 @@ func TestRegistryGetOrRegisterWithLazyInstantiation(t *testing.T) {
|
||||||
r := NewRegistry()
|
r := NewRegistry()
|
||||||
|
|
||||||
// First metric wins with GetOrRegister
|
// First metric wins with GetOrRegister
|
||||||
_ = r.GetOrRegister("foo", NewCounter)
|
c1 := GetOrRegisterCounter("foo", r)
|
||||||
m := r.GetOrRegister("foo", NewGauge)
|
c2 := GetOrRegisterCounter("foo", r)
|
||||||
if _, ok := m.(*Counter); !ok {
|
if c1 != c2 {
|
||||||
t.Fatal(m)
|
t.Fatal("counters should've matched")
|
||||||
}
|
}
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
|
|
@ -165,7 +165,7 @@ func TestPrefixedChildRegistryGetOrRegister(t *testing.T) {
|
||||||
r := NewRegistry()
|
r := NewRegistry()
|
||||||
pr := NewPrefixedChildRegistry(r, "prefix.")
|
pr := NewPrefixedChildRegistry(r, "prefix.")
|
||||||
|
|
||||||
_ = pr.GetOrRegister("foo", NewCounter())
|
_ = GetOrRegisterCounter("foo", pr)
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
r.Each(func(name string, m interface{}) {
|
r.Each(func(name string, m interface{}) {
|
||||||
|
|
@ -182,7 +182,7 @@ func TestPrefixedChildRegistryGetOrRegister(t *testing.T) {
|
||||||
func TestPrefixedRegistryGetOrRegister(t *testing.T) {
|
func TestPrefixedRegistryGetOrRegister(t *testing.T) {
|
||||||
r := NewPrefixedRegistry("prefix.")
|
r := NewPrefixedRegistry("prefix.")
|
||||||
|
|
||||||
_ = r.GetOrRegister("foo", NewCounter())
|
_ = GetOrRegisterCounter("foo", r)
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
r.Each(func(name string, m interface{}) {
|
r.Each(func(name string, m interface{}) {
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,7 @@ import (
|
||||||
// GetOrRegisterResettingTimer returns an existing ResettingTimer or constructs and registers a
|
// GetOrRegisterResettingTimer returns an existing ResettingTimer or constructs and registers a
|
||||||
// new ResettingTimer.
|
// new ResettingTimer.
|
||||||
func GetOrRegisterResettingTimer(name string, r Registry) *ResettingTimer {
|
func GetOrRegisterResettingTimer(name string, r Registry) *ResettingTimer {
|
||||||
if nil == r {
|
return getOrRegister(name, NewResettingTimer, r)
|
||||||
r = DefaultRegistry
|
|
||||||
}
|
|
||||||
return r.GetOrRegister(name, NewResettingTimer).(*ResettingTimer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRegisteredResettingTimer constructs and registers a new ResettingTimer.
|
// NewRegisteredResettingTimer constructs and registers a new ResettingTimer.
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func getOrRegisterRuntimeHistogram(name string, scale float64, r Registry) *runtimeHistogram {
|
func getOrRegisterRuntimeHistogram(name string, scale float64, r Registry) *runtimeHistogram {
|
||||||
if r == nil {
|
|
||||||
r = DefaultRegistry
|
|
||||||
}
|
|
||||||
constructor := func() Histogram { return newRuntimeHistogram(scale) }
|
constructor := func() Histogram { return newRuntimeHistogram(scale) }
|
||||||
return r.GetOrRegister(name, constructor).(*runtimeHistogram)
|
return getOrRegister(name, constructor, r).(*runtimeHistogram)
|
||||||
}
|
}
|
||||||
|
|
||||||
// runtimeHistogram wraps a runtime/metrics histogram.
|
// runtimeHistogram wraps a runtime/metrics histogram.
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,7 @@ import (
|
||||||
// Be sure to unregister the meter from the registry once it is of no use to
|
// Be sure to unregister the meter from the registry once it is of no use to
|
||||||
// allow for garbage collection.
|
// allow for garbage collection.
|
||||||
func GetOrRegisterTimer(name string, r Registry) *Timer {
|
func GetOrRegisterTimer(name string, r Registry) *Timer {
|
||||||
if nil == r {
|
return getOrRegister(name, NewTimer, r)
|
||||||
r = DefaultRegistry
|
|
||||||
}
|
|
||||||
return r.GetOrRegister(name, NewTimer).(*Timer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCustomTimer constructs a new Timer from a Histogram and a Meter.
|
// NewCustomTimer constructs a new Timer from a Histogram and a Meter.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue