registry.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package metrics
  2. import (
  3. "reflect"
  4. "sync"
  5. )
  6. // A Registry holds references to a set of metrics by name and can iterate
  7. // over them, calling callback functions provided by the user.
  8. //
  9. // This is an interface so as to encourage other structs to implement
  10. // the Registry API as appropriate.
  11. type Registry interface {
  12. // Call the given function for each registered metric.
  13. Each(func(string, interface{}))
  14. // Get the metric by the given name or nil if none is registered.
  15. Get(string) interface{}
  16. // Gets an existing metric or registers the given one.
  17. // The interface can be the metric to register if not found in registry,
  18. // or a function returning the metric for lazy instantiation.
  19. GetOrRegister(string, interface{}) interface{}
  20. // Register the given metric under the given name.
  21. Register(string, interface{})
  22. // Run all registered healthchecks.
  23. RunHealthchecks()
  24. // Unregister the metric with the given name.
  25. Unregister(string)
  26. }
  27. // The standard implementation of a Registry is a mutex-protected map
  28. // of names to metrics.
  29. type StandardRegistry struct {
  30. metrics map[string]interface{}
  31. mutex sync.Mutex
  32. }
  33. // Create a new registry.
  34. func NewRegistry() Registry {
  35. return &StandardRegistry{metrics: make(map[string]interface{})}
  36. }
  37. // Call the given function for each registered metric.
  38. func (r *StandardRegistry) Each(f func(string, interface{})) {
  39. for name, i := range r.registered() {
  40. f(name, i)
  41. }
  42. }
  43. // Get the metric by the given name or nil if none is registered.
  44. func (r *StandardRegistry) Get(name string) interface{} {
  45. r.mutex.Lock()
  46. defer r.mutex.Unlock()
  47. return r.metrics[name]
  48. }
  49. // Gets an existing metric or creates and registers a new one. Threadsafe
  50. // alternative to calling Get and Register on failure.
  51. // The interface can be the metric to register if not found in registry,
  52. // or a function returning the metric for lazy instantiation.
  53. func (r *StandardRegistry) GetOrRegister(name string, i interface{}) interface{} {
  54. r.mutex.Lock()
  55. defer r.mutex.Unlock()
  56. if metric, ok := r.metrics[name]; ok {
  57. return metric
  58. }
  59. if v := reflect.ValueOf(i); v.Kind() == reflect.Func {
  60. i = v.Call(nil)[0].Interface()
  61. }
  62. r.register(name, i)
  63. return i
  64. }
  65. // Register the given metric under the given name.
  66. func (r *StandardRegistry) Register(name string, i interface{}) {
  67. r.mutex.Lock()
  68. defer r.mutex.Unlock()
  69. r.register(name, i)
  70. }
  71. // Run all registered healthchecks.
  72. func (r *StandardRegistry) RunHealthchecks() {
  73. r.mutex.Lock()
  74. defer r.mutex.Unlock()
  75. for _, i := range r.metrics {
  76. if h, ok := i.(Healthcheck); ok {
  77. h.Check()
  78. }
  79. }
  80. }
  81. // Unregister the metric with the given name.
  82. func (r *StandardRegistry) Unregister(name string) {
  83. r.mutex.Lock()
  84. defer r.mutex.Unlock()
  85. delete(r.metrics, name)
  86. }
  87. func (r *StandardRegistry) register(name string, i interface{}) {
  88. switch i.(type) {
  89. case Counter, Gauge, GaugeFloat64, Healthcheck, Histogram, Meter, Timer:
  90. r.metrics[name] = i
  91. }
  92. }
  93. func (r *StandardRegistry) registered() map[string]interface{} {
  94. metrics := make(map[string]interface{}, len(r.metrics))
  95. r.mutex.Lock()
  96. defer r.mutex.Unlock()
  97. for name, i := range r.metrics {
  98. metrics[name] = i
  99. }
  100. return metrics
  101. }
  102. var DefaultRegistry Registry = NewRegistry()
  103. // Call the given function for each registered metric.
  104. func Each(f func(string, interface{})) {
  105. DefaultRegistry.Each(f)
  106. }
  107. // Get the metric by the given name or nil if none is registered.
  108. func Get(name string) interface{} {
  109. return DefaultRegistry.Get(name)
  110. }
  111. // Gets an existing metric or creates and registers a new one. Threadsafe
  112. // alternative to calling Get and Register on failure.
  113. func GetOrRegister(name string, i interface{}) interface{} {
  114. return DefaultRegistry.GetOrRegister(name, i)
  115. }
  116. // Register the given metric under the given name.
  117. func Register(name string, i interface{}) {
  118. DefaultRegistry.Register(name, i)
  119. }
  120. // Run all registered healthchecks.
  121. func RunHealthchecks() {
  122. DefaultRegistry.RunHealthchecks()
  123. }
  124. // Unregister the metric with the given name.
  125. func Unregister(name string) {
  126. DefaultRegistry.Unregister(name)
  127. }