github.com/theQRL/go-zond@v0.1.1/metrics/counter.go (about) 1 package metrics 2 3 import ( 4 "sync/atomic" 5 ) 6 7 type CounterSnapshot interface { 8 Count() int64 9 } 10 11 // Counters hold an int64 value that can be incremented and decremented. 12 type Counter interface { 13 Clear() 14 Dec(int64) 15 Inc(int64) 16 Snapshot() CounterSnapshot 17 } 18 19 // GetOrRegisterCounter returns an existing Counter or constructs and registers 20 // a new StandardCounter. 21 func GetOrRegisterCounter(name string, r Registry) Counter { 22 if nil == r { 23 r = DefaultRegistry 24 } 25 return r.GetOrRegister(name, NewCounter).(Counter) 26 } 27 28 // GetOrRegisterCounterForced returns an existing Counter or constructs and registers a 29 // new Counter no matter the global switch is enabled or not. 30 // Be sure to unregister the counter from the registry once it is of no use to 31 // allow for garbage collection. 32 func GetOrRegisterCounterForced(name string, r Registry) Counter { 33 if nil == r { 34 r = DefaultRegistry 35 } 36 return r.GetOrRegister(name, NewCounterForced).(Counter) 37 } 38 39 // NewCounter constructs a new StandardCounter. 40 func NewCounter() Counter { 41 if !Enabled { 42 return NilCounter{} 43 } 44 return new(StandardCounter) 45 } 46 47 // NewCounterForced constructs a new StandardCounter and returns it no matter if 48 // the global switch is enabled or not. 49 func NewCounterForced() Counter { 50 return new(StandardCounter) 51 } 52 53 // NewRegisteredCounter constructs and registers a new StandardCounter. 54 func NewRegisteredCounter(name string, r Registry) Counter { 55 c := NewCounter() 56 if nil == r { 57 r = DefaultRegistry 58 } 59 r.Register(name, c) 60 return c 61 } 62 63 // NewRegisteredCounterForced constructs and registers a new StandardCounter 64 // and launches a goroutine no matter the global switch is enabled or not. 65 // Be sure to unregister the counter from the registry once it is of no use to 66 // allow for garbage collection. 67 func NewRegisteredCounterForced(name string, r Registry) Counter { 68 c := NewCounterForced() 69 if nil == r { 70 r = DefaultRegistry 71 } 72 r.Register(name, c) 73 return c 74 } 75 76 // counterSnapshot is a read-only copy of another Counter. 77 type counterSnapshot int64 78 79 // Count returns the count at the time the snapshot was taken. 80 func (c counterSnapshot) Count() int64 { return int64(c) } 81 82 // NilCounter is a no-op Counter. 83 type NilCounter struct{} 84 85 func (NilCounter) Clear() {} 86 func (NilCounter) Dec(i int64) {} 87 func (NilCounter) Inc(i int64) {} 88 func (NilCounter) Snapshot() CounterSnapshot { return (*emptySnapshot)(nil) } 89 90 // StandardCounter is the standard implementation of a Counter and uses the 91 // sync/atomic package to manage a single int64 value. 92 type StandardCounter atomic.Int64 93 94 // Clear sets the counter to zero. 95 func (c *StandardCounter) Clear() { 96 (*atomic.Int64)(c).Store(0) 97 } 98 99 // Dec decrements the counter by the given amount. 100 func (c *StandardCounter) Dec(i int64) { 101 (*atomic.Int64)(c).Add(-i) 102 } 103 104 // Inc increments the counter by the given amount. 105 func (c *StandardCounter) Inc(i int64) { 106 (*atomic.Int64)(c).Add(i) 107 } 108 109 // Snapshot returns a read-only copy of the counter. 110 func (c *StandardCounter) Snapshot() CounterSnapshot { 111 return counterSnapshot((*atomic.Int64)(c).Load()) 112 }