mirror of https://github.com/grafana/grafana
feat(instrumentation): lots of refactoring to support tag based backend, #4696
parent
2a9b51d836
commit
e2c794ff31
@ -0,0 +1,53 @@ |
||||
package metrics |
||||
|
||||
import "github.com/grafana/grafana/pkg/log" |
||||
|
||||
type MetricMeta struct { |
||||
tags map[string]string |
||||
name string |
||||
} |
||||
|
||||
func NewMetricMeta(name string, tagStrings []string) *MetricMeta { |
||||
if len(tagStrings)%2 != 0 { |
||||
log.Fatal(3, "Metrics: tags array is missing value for key, %v", tagStrings) |
||||
} |
||||
|
||||
tags := make(map[string]string) |
||||
for i := 0; i < len(tagStrings); i += 2 { |
||||
tags[tagStrings[i]] = tagStrings[i+1] |
||||
} |
||||
|
||||
return &MetricMeta{ |
||||
tags: tags, |
||||
name: name, |
||||
} |
||||
} |
||||
|
||||
func (m *MetricMeta) Name() string { |
||||
return m.name |
||||
} |
||||
|
||||
func (m *MetricMeta) Tags() map[string]string { |
||||
return m.tags |
||||
} |
||||
|
||||
func (m *MetricMeta) StringifyTags() string { |
||||
if len(m.tags) == 0 { |
||||
return "" |
||||
} |
||||
|
||||
str := "" |
||||
for key, value := range m.tags { |
||||
str += "." + key + "_" + value |
||||
} |
||||
|
||||
return str |
||||
} |
||||
|
||||
type Metric interface { |
||||
Name() string |
||||
Tags() map[string]string |
||||
StringifyTags() string |
||||
Snapshot() Metric |
||||
Clear() |
||||
} |
@ -1,102 +1,38 @@ |
||||
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)) |
||||
} |
||||
import "sync" |
||||
|
||||
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 |
||||
GetSnapshots() []Metric |
||||
Register(metric Metric) |
||||
} |
||||
|
||||
// The standard implementation of a Registry is a mutex-protected map
|
||||
// of names to metrics.
|
||||
type StandardRegistry struct { |
||||
metrics map[string]interface{} |
||||
metrics []Metric |
||||
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) |
||||
return &StandardRegistry{ |
||||
metrics: make([]Metric, 0), |
||||
} |
||||
} |
||||
|
||||
// Get the metric by the given name or nil if none is registered.
|
||||
func (r *StandardRegistry) Get(name string) interface{} { |
||||
func (r *StandardRegistry) Register(metric Metric) { |
||||
r.mutex.Lock() |
||||
defer r.mutex.Unlock() |
||||
return r.metrics[name] |
||||
r.metrics = append(r.metrics, metric) |
||||
} |
||||
|
||||
// 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 |
||||
// Call the given function for each registered metric.
|
||||
func (r *StandardRegistry) GetSnapshots() []Metric { |
||||
metrics := make([]Metric, len(r.metrics)) |
||||
for i, metric := range r.metrics { |
||||
metrics[i] = metric.Snapshot() |
||||
metric.Clear() |
||||
} |
||||
return metrics |
||||
} |
||||
|
Loading…
Reference in new issue