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