| 
									
										
										
										
											2015-06-22 12:00:55 +03:00
										 |  |  | package metrics | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-16 09:22:51 -05:00
										 |  |  | import ( | 
					
						
							|  |  |  | 	"sync/atomic" | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2015-06-22 12:00:55 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Counters hold an int64 value that can be incremented and decremented. | 
					
						
							|  |  |  | type Counter interface { | 
					
						
							|  |  |  | 	Clear() | 
					
						
							|  |  |  | 	Count() int64 | 
					
						
							|  |  |  | 	Dec(int64) | 
					
						
							|  |  |  | 	Inc(int64) | 
					
						
							|  |  |  | 	Snapshot() Counter | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // GetOrRegisterCounter returns an existing Counter or constructs and registers | 
					
						
							|  |  |  | // a new StandardCounter. | 
					
						
							|  |  |  | func GetOrRegisterCounter(name string, r Registry) Counter { | 
					
						
							|  |  |  | 	if nil == r { | 
					
						
							|  |  |  | 		r = DefaultRegistry | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return r.GetOrRegister(name, NewCounter).(Counter) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-16 09:22:51 -05:00
										 |  |  | // GetOrRegisterCounterForced returns an existing Counter or constructs and registers a | 
					
						
							|  |  |  | // new Counter no matter the global switch is enabled or not. | 
					
						
							|  |  |  | // Be sure to unregister the counter from the registry once it is of no use to | 
					
						
							|  |  |  | // allow for garbage collection. | 
					
						
							|  |  |  | func GetOrRegisterCounterForced(name string, r Registry) Counter { | 
					
						
							|  |  |  | 	if nil == r { | 
					
						
							|  |  |  | 		r = DefaultRegistry | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return r.GetOrRegister(name, NewCounterForced).(Counter) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-22 12:00:55 +03:00
										 |  |  | // NewCounter constructs a new StandardCounter. | 
					
						
							|  |  |  | func NewCounter() Counter { | 
					
						
							| 
									
										
										
										
											2018-02-23 10:56:08 +01:00
										 |  |  | 	if !Enabled { | 
					
						
							| 
									
										
										
										
											2015-06-22 12:00:55 +03:00
										 |  |  | 		return NilCounter{} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return &StandardCounter{0} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-16 09:22:51 -05:00
										 |  |  | // NewCounterForced constructs a new StandardCounter and returns it no matter if | 
					
						
							|  |  |  | // the global switch is enabled or not. | 
					
						
							|  |  |  | func NewCounterForced() Counter { | 
					
						
							|  |  |  | 	return &StandardCounter{0} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-22 12:00:55 +03:00
										 |  |  | // NewRegisteredCounter constructs and registers a new StandardCounter. | 
					
						
							|  |  |  | func NewRegisteredCounter(name string, r Registry) Counter { | 
					
						
							|  |  |  | 	c := NewCounter() | 
					
						
							|  |  |  | 	if nil == r { | 
					
						
							|  |  |  | 		r = DefaultRegistry | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	r.Register(name, c) | 
					
						
							|  |  |  | 	return c | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-16 09:22:51 -05:00
										 |  |  | // NewRegisteredCounterForced constructs and registers a new StandardCounter | 
					
						
							|  |  |  | // and launches a goroutine no matter the global switch is enabled or not. | 
					
						
							|  |  |  | // Be sure to unregister the counter from the registry once it is of no use to | 
					
						
							|  |  |  | // allow for garbage collection. | 
					
						
							|  |  |  | func NewRegisteredCounterForced(name string, r Registry) Counter { | 
					
						
							|  |  |  | 	c := NewCounterForced() | 
					
						
							|  |  |  | 	if nil == r { | 
					
						
							|  |  |  | 		r = DefaultRegistry | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	r.Register(name, c) | 
					
						
							|  |  |  | 	return c | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-22 12:00:55 +03:00
										 |  |  | // CounterSnapshot is a read-only copy of another Counter. | 
					
						
							|  |  |  | type CounterSnapshot int64 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Clear panics. | 
					
						
							|  |  |  | func (CounterSnapshot) Clear() { | 
					
						
							|  |  |  | 	panic("Clear called on a CounterSnapshot") | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Count returns the count at the time the snapshot was taken. | 
					
						
							|  |  |  | func (c CounterSnapshot) Count() int64 { return int64(c) } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Dec panics. | 
					
						
							|  |  |  | func (CounterSnapshot) Dec(int64) { | 
					
						
							|  |  |  | 	panic("Dec called on a CounterSnapshot") | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Inc panics. | 
					
						
							|  |  |  | func (CounterSnapshot) Inc(int64) { | 
					
						
							|  |  |  | 	panic("Inc called on a CounterSnapshot") | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Snapshot returns the snapshot. | 
					
						
							|  |  |  | func (c CounterSnapshot) Snapshot() Counter { return c } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // NilCounter is a no-op Counter. | 
					
						
							|  |  |  | type NilCounter struct{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Clear is a no-op. | 
					
						
							|  |  |  | func (NilCounter) Clear() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Count is a no-op. | 
					
						
							|  |  |  | func (NilCounter) Count() int64 { return 0 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Dec is a no-op. | 
					
						
							|  |  |  | func (NilCounter) Dec(i int64) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Inc is a no-op. | 
					
						
							|  |  |  | func (NilCounter) Inc(i int64) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Snapshot is a no-op. | 
					
						
							|  |  |  | func (NilCounter) Snapshot() Counter { return NilCounter{} } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // StandardCounter is the standard implementation of a Counter and uses the | 
					
						
							|  |  |  | // sync/atomic package to manage a single int64 value. | 
					
						
							|  |  |  | type StandardCounter struct { | 
					
						
							|  |  |  | 	count int64 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Clear sets the counter to zero. | 
					
						
							|  |  |  | func (c *StandardCounter) Clear() { | 
					
						
							|  |  |  | 	atomic.StoreInt64(&c.count, 0) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Count returns the current count. | 
					
						
							|  |  |  | func (c *StandardCounter) Count() int64 { | 
					
						
							|  |  |  | 	return atomic.LoadInt64(&c.count) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Dec decrements the counter by the given amount. | 
					
						
							|  |  |  | func (c *StandardCounter) Dec(i int64) { | 
					
						
							|  |  |  | 	atomic.AddInt64(&c.count, -i) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Inc increments the counter by the given amount. | 
					
						
							|  |  |  | func (c *StandardCounter) Inc(i int64) { | 
					
						
							|  |  |  | 	atomic.AddInt64(&c.count, i) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Snapshot returns a read-only copy of the counter. | 
					
						
							|  |  |  | func (c *StandardCounter) Snapshot() Counter { | 
					
						
							|  |  |  | 	return CounterSnapshot(c.Count()) | 
					
						
							|  |  |  | } |