counter.go 3.6 KB

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