| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- package metrics
- import (
- "fmt"
- "reflect"
- "sync"
- )
- // DuplicateMetric is the error returned by Registry.Register when a metric
- // already exists. If you mean to Register that metric you must first
- // Unregister the existing metric.
- type DuplicateMetric string
- func (err DuplicateMetric) Error() string {
- return fmt.Sprintf("duplicate metric: %s", string(err))
- }
- type Registry interface {
- // Call the given function for each registered metric.
- Each(func(string, interface{}))
- // Get the metric by the given name or nil if none is registered.
- Get(string) interface{}
- // Gets an existing metric or registers the given one.
- // The interface can be the metric to register if not found in registry,
- // or a function returning the metric for lazy instantiation.
- GetOrRegister(string, interface{}) interface{}
- // Register the given metric under the given name.
- Register(string, interface{}) error
- }
- // The standard implementation of a Registry is a mutex-protected map
- // of names to metrics.
- type StandardRegistry struct {
- metrics map[string]interface{}
- mutex sync.Mutex
- }
- // Create a new registry.
- func NewRegistry() Registry {
- return &StandardRegistry{metrics: make(map[string]interface{})}
- }
- // Call the given function for each registered metric.
- func (r *StandardRegistry) Each(f func(string, interface{})) {
- for name, i := range r.registered() {
- f(name, i)
- }
- }
- // Get the metric by the given name or nil if none is registered.
- func (r *StandardRegistry) Get(name string) interface{} {
- r.mutex.Lock()
- defer r.mutex.Unlock()
- return r.metrics[name]
- }
- // Gets an existing metric or creates and registers a new one. Threadsafe
- // alternative to calling Get and Register on failure.
- // The interface can be the metric to register if not found in registry,
- // or a function returning the metric for lazy instantiation.
- func (r *StandardRegistry) GetOrRegister(name string, i interface{}) interface{} {
- r.mutex.Lock()
- defer r.mutex.Unlock()
- if metric, ok := r.metrics[name]; ok {
- return metric
- }
- if v := reflect.ValueOf(i); v.Kind() == reflect.Func {
- i = v.Call(nil)[0].Interface()
- }
- r.register(name, i)
- return i
- }
- // Register the given metric under the given name. Returns a DuplicateMetric
- // if a metric by the given name is already registered.
- func (r *StandardRegistry) Register(name string, i interface{}) error {
- r.mutex.Lock()
- defer r.mutex.Unlock()
- return r.register(name, i)
- }
- func (r *StandardRegistry) register(name string, i interface{}) error {
- if _, ok := r.metrics[name]; ok {
- return DuplicateMetric(name)
- }
- r.metrics[name] = i
- return nil
- }
- func (r *StandardRegistry) registered() map[string]interface{} {
- metrics := make(map[string]interface{}, len(r.metrics))
- r.mutex.Lock()
- defer r.mutex.Unlock()
- for name, i := range r.metrics {
- metrics[name] = i
- }
- return metrics
- }
|