mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
	
	
		
			103 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
		
		
			
		
	
	
			103 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
| 
								 | 
							
								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
							 | 
						||
| 
								 | 
							
								}
							 |