meter.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. package metrics
  2. import (
  3. "sync"
  4. "time"
  5. )
  6. // Meters count events to produce exponentially-weighted moving average rates
  7. // at one-, five-, and fifteen-minutes and a mean rate.
  8. type Meter interface {
  9. Count() int64
  10. Mark(int64)
  11. Rate1() float64
  12. Rate5() float64
  13. Rate15() float64
  14. RateMean() float64
  15. Snapshot() Meter
  16. }
  17. // GetOrRegisterMeter returns an existing Meter or constructs and registers a
  18. // new StandardMeter.
  19. func GetOrRegisterMeter(name string, r Registry) Meter {
  20. if nil == r {
  21. r = DefaultRegistry
  22. }
  23. return r.GetOrRegister(name, NewMeter).(Meter)
  24. }
  25. // NewMeter constructs a new StandardMeter and launches a goroutine.
  26. func NewMeter() Meter {
  27. if UseNilMetrics {
  28. return NilMeter{}
  29. }
  30. m := newStandardMeter()
  31. arbiter.Lock()
  32. defer arbiter.Unlock()
  33. arbiter.meters = append(arbiter.meters, m)
  34. if !arbiter.started {
  35. arbiter.started = true
  36. go arbiter.tick()
  37. }
  38. return m
  39. }
  40. // NewMeter constructs and registers a new StandardMeter and launches a
  41. // goroutine.
  42. func NewRegisteredMeter(name string, r Registry) Meter {
  43. c := NewMeter()
  44. if nil == r {
  45. r = DefaultRegistry
  46. }
  47. r.Register(name, c)
  48. return c
  49. }
  50. // MeterSnapshot is a read-only copy of another Meter.
  51. type MeterSnapshot struct {
  52. count int64
  53. rate1, rate5, rate15, rateMean float64
  54. }
  55. // Count returns the count of events at the time the snapshot was taken.
  56. func (m *MeterSnapshot) Count() int64 { return m.count }
  57. // Mark panics.
  58. func (*MeterSnapshot) Mark(n int64) {
  59. panic("Mark called on a MeterSnapshot")
  60. }
  61. // Rate1 returns the one-minute moving average rate of events per second at the
  62. // time the snapshot was taken.
  63. func (m *MeterSnapshot) Rate1() float64 { return m.rate1 }
  64. // Rate5 returns the five-minute moving average rate of events per second at
  65. // the time the snapshot was taken.
  66. func (m *MeterSnapshot) Rate5() float64 { return m.rate5 }
  67. // Rate15 returns the fifteen-minute moving average rate of events per second
  68. // at the time the snapshot was taken.
  69. func (m *MeterSnapshot) Rate15() float64 { return m.rate15 }
  70. // RateMean returns the meter's mean rate of events per second at the time the
  71. // snapshot was taken.
  72. func (m *MeterSnapshot) RateMean() float64 { return m.rateMean }
  73. // Snapshot returns the snapshot.
  74. func (m *MeterSnapshot) Snapshot() Meter { return m }
  75. // NilMeter is a no-op Meter.
  76. type NilMeter struct{}
  77. // Count is a no-op.
  78. func (NilMeter) Count() int64 { return 0 }
  79. // Mark is a no-op.
  80. func (NilMeter) Mark(n int64) {}
  81. // Rate1 is a no-op.
  82. func (NilMeter) Rate1() float64 { return 0.0 }
  83. // Rate5 is a no-op.
  84. func (NilMeter) Rate5() float64 { return 0.0 }
  85. // Rate15is a no-op.
  86. func (NilMeter) Rate15() float64 { return 0.0 }
  87. // RateMean is a no-op.
  88. func (NilMeter) RateMean() float64 { return 0.0 }
  89. // Snapshot is a no-op.
  90. func (NilMeter) Snapshot() Meter { return NilMeter{} }
  91. // StandardMeter is the standard implementation of a Meter.
  92. type StandardMeter struct {
  93. lock sync.RWMutex
  94. snapshot *MeterSnapshot
  95. a1, a5, a15 EWMA
  96. startTime time.Time
  97. }
  98. func newStandardMeter() *StandardMeter {
  99. return &StandardMeter{
  100. snapshot: &MeterSnapshot{},
  101. a1: NewEWMA1(),
  102. a5: NewEWMA5(),
  103. a15: NewEWMA15(),
  104. startTime: time.Now(),
  105. }
  106. }
  107. // Count returns the number of events recorded.
  108. func (m *StandardMeter) Count() int64 {
  109. m.lock.RLock()
  110. count := m.snapshot.count
  111. m.lock.RUnlock()
  112. return count
  113. }
  114. // Mark records the occurance of n events.
  115. func (m *StandardMeter) Mark(n int64) {
  116. m.lock.Lock()
  117. defer m.lock.Unlock()
  118. m.snapshot.count += n
  119. m.a1.Update(n)
  120. m.a5.Update(n)
  121. m.a15.Update(n)
  122. m.updateSnapshot()
  123. }
  124. // Rate1 returns the one-minute moving average rate of events per second.
  125. func (m *StandardMeter) Rate1() float64 {
  126. m.lock.RLock()
  127. rate1 := m.snapshot.rate1
  128. m.lock.RUnlock()
  129. return rate1
  130. }
  131. // Rate5 returns the five-minute moving average rate of events per second.
  132. func (m *StandardMeter) Rate5() float64 {
  133. m.lock.RLock()
  134. rate5 := m.snapshot.rate5
  135. m.lock.RUnlock()
  136. return rate5
  137. }
  138. // Rate15 returns the fifteen-minute moving average rate of events per second.
  139. func (m *StandardMeter) Rate15() float64 {
  140. m.lock.RLock()
  141. rate15 := m.snapshot.rate15
  142. m.lock.RUnlock()
  143. return rate15
  144. }
  145. // RateMean returns the meter's mean rate of events per second.
  146. func (m *StandardMeter) RateMean() float64 {
  147. m.lock.RLock()
  148. rateMean := m.snapshot.rateMean
  149. m.lock.RUnlock()
  150. return rateMean
  151. }
  152. // Snapshot returns a read-only copy of the meter.
  153. func (m *StandardMeter) Snapshot() Meter {
  154. m.lock.RLock()
  155. snapshot := *m.snapshot
  156. m.lock.RUnlock()
  157. return &snapshot
  158. }
  159. func (m *StandardMeter) updateSnapshot() {
  160. // should run with write lock held on m.lock
  161. snapshot := m.snapshot
  162. snapshot.rate1 = m.a1.Rate()
  163. snapshot.rate5 = m.a5.Rate()
  164. snapshot.rate15 = m.a15.Rate()
  165. snapshot.rateMean = float64(snapshot.count) / time.Since(m.startTime).Seconds()
  166. }
  167. func (m *StandardMeter) tick() {
  168. m.lock.Lock()
  169. defer m.lock.Unlock()
  170. m.a1.Tick()
  171. m.a5.Tick()
  172. m.a15.Tick()
  173. m.updateSnapshot()
  174. }
  175. type meterArbiter struct {
  176. sync.RWMutex
  177. started bool
  178. meters []*StandardMeter
  179. ticker *time.Ticker
  180. }
  181. var arbiter = meterArbiter{ticker: time.NewTicker(5e9)}
  182. // Ticks meters on the scheduled interval
  183. func (ma *meterArbiter) tick() {
  184. for {
  185. select {
  186. case <-ma.ticker.C:
  187. ma.tickMeters()
  188. }
  189. }
  190. }
  191. func (ma *meterArbiter) tickMeters() {
  192. ma.RLock()
  193. defer ma.RUnlock()
  194. for _, meter := range ma.meters {
  195. meter.tick()
  196. }
  197. }