meter.go 1.2 KB

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