func NewRates(name string, countTracker CountTracker, samples int, interval time.Duration) *Rates {
	if interval < 1*time.Second && interval != -1*time.Second {
		panic("interval too small")
	}
	rt := &Rates{
		timeStamps:            NewRingInt64(samples + 1),
		counts:                make(map[string]*RingInt64),
		countTracker:          countTracker,
		samples:               samples + 1,
		interval:              interval,
		timestampLastSampling: timeNow(),
		closed:                make(chan bool),
	}
	if name != "" {
		publish(name, rt)
	}
	if interval > 0 {
		rt.wg.Add(1)
		go rt.track()
	}
	return rt
}
NewRates reports rolling rate information for countTracker. samples specifies
the number of samples to report, and interval specifies the time interval
between samples. The minimum interval is 1 second.
If passing the special value of -1s as interval, we don't snapshot.
(use this for tests).
package stats
import (
	"encoding/json"
	"math"
	"sync"
	"time"
)
var timeNow = time.Now
type CountTracker interface {
	Counts() map[string]int64
}
type Rates struct {
	mu           sync.Mutex
	timeStamps   *RingInt64
	counts       map[string]*RingInt64
	countTracker CountTracker
	samples      int
	interval     time.Duration
	previousTotalCount int64
	timestampLastSampling time.Time
	totalRate float64
	closed    chan bool
	wg        sync.WaitGroup
}