123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- package mock
- import (
- "sync"
- "github.com/ydb-platform/ydb/library/go/core/metrics"
- "github.com/ydb-platform/ydb/library/go/core/metrics/internal/pkg/metricsutil"
- "github.com/ydb-platform/ydb/library/go/core/metrics/internal/pkg/registryutil"
- "go.uber.org/atomic"
- )
- var _ metrics.Registry = (*Registry)(nil)
- type Registry struct {
- separator string
- prefix string
- tags map[string]string
- allowLoadRegisteredMetrics bool
- subregistries map[string]*Registry
- m *sync.Mutex
- metrics *sync.Map
- }
- func NewRegistry(opts *RegistryOpts) *Registry {
- r := &Registry{
- separator: ".",
- subregistries: make(map[string]*Registry),
- m: new(sync.Mutex),
- metrics: new(sync.Map),
- }
- if opts != nil {
- r.separator = string(opts.Separator)
- r.prefix = opts.Prefix
- r.tags = opts.Tags
- r.allowLoadRegisteredMetrics = opts.AllowLoadRegisteredMetrics
- }
- return r
- }
- // WithTags creates new sub-scope, where each metric has tags attached to it.
- func (r Registry) WithTags(tags map[string]string) metrics.Registry {
- return r.newSubregistry(r.prefix, registryutil.MergeTags(r.tags, tags))
- }
- // WithPrefix creates new sub-scope, where each metric has prefix added to it name.
- func (r Registry) WithPrefix(prefix string) metrics.Registry {
- return r.newSubregistry(registryutil.BuildFQName(r.separator, r.prefix, prefix), r.tags)
- }
- func (r Registry) ComposeName(parts ...string) string {
- return registryutil.BuildFQName(r.separator, parts...)
- }
- func (r Registry) Counter(name string) metrics.Counter {
- s := &Counter{
- Name: r.newMetricName(name),
- Tags: r.tags,
- Value: new(atomic.Int64),
- }
- key := registryutil.BuildRegistryKey(s.Name, r.tags)
- if val, loaded := r.metrics.LoadOrStore(key, s); loaded {
- if r.allowLoadRegisteredMetrics {
- return val.(*Counter)
- }
- panic("metric with key " + key + " already registered")
- }
- return s
- }
- func (r Registry) FuncCounter(name string, function func() int64) metrics.FuncCounter {
- metricName := r.newMetricName(name)
- key := registryutil.BuildRegistryKey(metricName, r.tags)
- s := FuncCounter{function: function}
- if _, loaded := r.metrics.LoadOrStore(key, s); loaded {
- panic("metric with key " + key + " already registered")
- }
- return s
- }
- func (r Registry) Gauge(name string) metrics.Gauge {
- s := &Gauge{
- Name: r.newMetricName(name),
- Tags: r.tags,
- Value: new(atomic.Float64),
- }
- key := registryutil.BuildRegistryKey(s.Name, r.tags)
- if val, loaded := r.metrics.LoadOrStore(key, s); loaded {
- if r.allowLoadRegisteredMetrics {
- return val.(*Gauge)
- }
- panic("metric with key " + key + " already registered")
- }
- return s
- }
- func (r Registry) FuncGauge(name string, function func() float64) metrics.FuncGauge {
- metricName := r.newMetricName(name)
- key := registryutil.BuildRegistryKey(metricName, r.tags)
- s := FuncGauge{function: function}
- if _, loaded := r.metrics.LoadOrStore(key, s); loaded {
- panic("metric with key " + key + " already registered")
- }
- return s
- }
- func (r *Registry) IntGauge(name string) metrics.IntGauge {
- s := &IntGauge{
- Name: r.newMetricName(name),
- Tags: r.tags,
- Value: new(atomic.Int64),
- }
- key := registryutil.BuildRegistryKey(s.Name, r.tags)
- if val, loaded := r.metrics.LoadOrStore(key, s); loaded {
- if r.allowLoadRegisteredMetrics {
- return val.(*IntGauge)
- }
- panic("metric with key " + key + " already registered")
- }
- return s
- }
- func (r *Registry) FuncIntGauge(name string, function func() int64) metrics.FuncIntGauge {
- metricName := r.newMetricName(name)
- key := registryutil.BuildRegistryKey(metricName, r.tags)
- s := FuncIntGauge{function: function}
- if _, loaded := r.metrics.LoadOrStore(key, s); loaded {
- panic("metric with key " + key + " already registered")
- }
- return s
- }
- func (r Registry) Timer(name string) metrics.Timer {
- s := &Timer{
- Name: r.newMetricName(name),
- Tags: r.tags,
- Value: new(atomic.Duration),
- }
- key := registryutil.BuildRegistryKey(s.Name, r.tags)
- if val, loaded := r.metrics.LoadOrStore(key, s); loaded {
- if r.allowLoadRegisteredMetrics {
- return val.(*Timer)
- }
- panic("metric with key " + key + " already registered")
- }
- return s
- }
- func (r Registry) Histogram(name string, buckets metrics.Buckets) metrics.Histogram {
- s := &Histogram{
- Name: r.newMetricName(name),
- Tags: r.tags,
- BucketBounds: metricsutil.BucketsBounds(buckets),
- BucketValues: make([]int64, buckets.Size()),
- InfValue: new(atomic.Int64),
- }
- key := registryutil.BuildRegistryKey(s.Name, r.tags)
- if val, loaded := r.metrics.LoadOrStore(key, s); loaded {
- if r.allowLoadRegisteredMetrics {
- return val.(*Histogram)
- }
- panic("metric with key " + key + " already registered")
- }
- return s
- }
- func (r Registry) DurationHistogram(name string, buckets metrics.DurationBuckets) metrics.Timer {
- s := &Histogram{
- Name: r.newMetricName(name),
- Tags: r.tags,
- BucketBounds: metricsutil.DurationBucketsBounds(buckets),
- BucketValues: make([]int64, buckets.Size()),
- InfValue: new(atomic.Int64),
- }
- key := registryutil.BuildRegistryKey(s.Name, r.tags)
- if val, loaded := r.metrics.LoadOrStore(key, s); loaded {
- if r.allowLoadRegisteredMetrics {
- return val.(*Histogram)
- }
- panic("metric with key " + key + " already registered")
- }
- return s
- }
- func (r *Registry) newSubregistry(prefix string, tags map[string]string) *Registry {
- registryKey := registryutil.BuildRegistryKey(prefix, tags)
- r.m.Lock()
- defer r.m.Unlock()
- if existing, ok := r.subregistries[registryKey]; ok {
- return existing
- }
- subregistry := &Registry{
- separator: r.separator,
- prefix: prefix,
- tags: tags,
- allowLoadRegisteredMetrics: r.allowLoadRegisteredMetrics,
- subregistries: r.subregistries,
- m: r.m,
- metrics: r.metrics,
- }
- r.subregistries[registryKey] = subregistry
- return subregistry
- }
- func (r *Registry) newMetricName(name string) string {
- return registryutil.BuildFQName(r.separator, r.prefix, name)
- }
|