meter.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package metrics
  2. import (
  3. "time"
  4. )
  5. type Meter interface {
  6. Count() int64
  7. Mark(int64)
  8. Rate1() float64
  9. Rate5() float64
  10. Rate15() float64
  11. RateMean() float64
  12. }
  13. type meter struct {
  14. in chan int64
  15. out chan meterV
  16. reset, tick chan bool
  17. }
  18. type meterV struct {
  19. count int64
  20. rate1, rate5, rate15, rateMean float64
  21. }
  22. func NewMeter() Meter {
  23. m := &meter{
  24. make(chan int64),
  25. make(chan meterV),
  26. make(chan bool), make(chan bool),
  27. }
  28. go m.arbiter()
  29. go m.ticker()
  30. return m
  31. }
  32. func (m *meter) Clear() {
  33. m.reset <- true
  34. }
  35. func (m *meter) Count() int64 {
  36. return (<-m.out).count
  37. }
  38. func (m *meter) Mark(n int64) {
  39. m.in <- n
  40. }
  41. func (m *meter) Rate1() float64 {
  42. return (<-m.out).rate1
  43. }
  44. func (m *meter) Rate5() float64 {
  45. return (<-m.out).rate5
  46. }
  47. func (m *meter) Rate15() float64 {
  48. return (<-m.out).rate15
  49. }
  50. func (m *meter) RateMean() float64 {
  51. return (<-m.out).rateMean
  52. }
  53. func (m *meter) arbiter() {
  54. var mv meterV
  55. a1 := NewEWMA1()
  56. a5 := NewEWMA5()
  57. a15 := NewEWMA15()
  58. tsStart := time.Nanoseconds()
  59. for {
  60. select {
  61. case n := <-m.in:
  62. mv.count += n
  63. a1.Update(n); mv.rate1 = a1.Rate()
  64. a5.Update(n); mv.rate5 = a5.Rate()
  65. a15.Update(n); mv.rate15 = a15.Rate()
  66. mv.rateMean = float64(1e9 * mv.count) / float64(
  67. time.Nanoseconds() - tsStart)
  68. case m.out <- mv:
  69. case <-m.reset:
  70. mv = meterV{}
  71. a1.Clear()
  72. a5.Clear()
  73. a15.Clear()
  74. tsStart = time.Nanoseconds()
  75. case <-m.tick:
  76. a1.Tick()
  77. a5.Tick()
  78. a15.Tick()
  79. }
  80. }
  81. }
  82. func (m *meter) ticker() {
  83. for {
  84. time.Sleep(5e9)
  85. m.tick <- true
  86. }
  87. }