1package metrics 2 3import ( 4 "fmt" 5 "sort" 6) 7 8type Registry struct { 9 descriptors []*groupDesc 10 groups []groupRegistry 11} 12 13const ( 14 // DefaultGroup is the identifier for the default group. 15 DefaultGroup = GID(0) 16) 17 18// NewRegistry creates a new Registry with a single group identified by DefaultGroup. 19func NewRegistry() *Registry { 20 var r Registry 21 r.MustRegisterGroup("global") 22 return &r 23} 24 25func (r *Registry) register(gd *groupDesc) error { 26 p := sort.Search(len(r.descriptors), func(i int) bool { 27 return r.descriptors[i].Name == gd.Name 28 }) 29 30 if p != len(r.descriptors) { 31 return fmt.Errorf("group name '%s' already in use", gd.Name) 32 } 33 34 r.descriptors = append(r.descriptors, gd) 35 sort.Slice(r.descriptors, func(i, j int) bool { 36 return r.descriptors[i].Name < r.descriptors[j].Name 37 }) 38 39 gd.id = GID(len(r.groups)) 40 r.groups = append(r.groups, groupRegistry{desc: gd}) 41 42 return nil 43} 44 45func (r *Registry) mustRegister(gd *groupDesc) { 46 if err := r.register(gd); err != nil { 47 panic(err.Error()) 48 } 49} 50 51// MustRegisterGroup registers a new group and panics if a group already exists with the same name. 52// 53// MustRegisterGroup is not safe to call from concurrent goroutines. 54func (r *Registry) MustRegisterGroup(name string) GID { 55 gd := &groupDesc{Name: name} 56 r.mustRegister(gd) 57 return gd.id 58} 59 60func (r *Registry) mustGetGroupRegistry(id GID) *groupRegistry { 61 if int(id) >= len(r.groups) { 62 panic(fmt.Sprintf("invalid group ID")) 63 } 64 return &r.groups[id] 65} 66 67// MustRegisterCounter registers a new counter metric using the provided descriptor. 68// If the metric name is not unique within the group, MustRegisterCounter will panic. 69// 70// MustRegisterCounter is not safe to call from concurrent goroutines. 71func (r *Registry) MustRegisterCounter(name string, opts ...descOption) ID { 72 desc := newDesc(name, opts...) 73 return r.mustGetGroupRegistry(desc.gid).mustRegisterCounter(desc) 74} 75 76// MustRegisterTimer registers a new timer metric using the provided descriptor. 77// If the metric name is not unique within the group, MustRegisterTimer will panic. 78// 79// MustRegisterTimer is not safe to call from concurrent goroutines. 80func (r *Registry) MustRegisterTimer(name string, opts ...descOption) ID { 81 desc := newDesc(name, opts...) 82 return r.mustGetGroupRegistry(desc.gid).mustRegisterTimer(desc) 83} 84 85func (r *Registry) NewGroup(gid GID) *Group { 86 return r.mustGetGroupRegistry(gid).newGroup() 87} 88