func BenchmarkWindowedHistogramRecordAndRotate(b *testing.B) { w := hdrhistogram.NewWindowed(3, 1, 10000000, 3) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { if err := w.Current.RecordValue(100); err != nil { b.Fatal(err) } if i%100000 == 1 { w.Rotate() } } }
func TestWindowedHistogram(t *testing.T) { w := hdrhistogram.NewWindowed(2, 1, 1000, 3) for i := 0; i < 100; i++ { w.Current.RecordValue(int64(i)) } w.Rotate() for i := 100; i < 200; i++ { w.Current.RecordValue(int64(i)) } w.Rotate() for i := 200; i < 300; i++ { w.Current.RecordValue(int64(i)) } if v, want := w.Merge().ValueAtQuantile(50), int64(199); v != want { t.Errorf("Median was %v, but expected %v", v, want) } }
// NewHistogram returns a windowed HDR histogram which drops data older than // five minutes. The returned histogram is safe to use from multiple goroutines. // // Use a histogram to track the distribution of a stream of values (e.g., the // latency associated with HTTP requests). func NewHistogram(name string, minValue, maxValue int64, sigfigs int) *Histogram { hm.Lock() defer hm.Unlock() if _, ok := histograms[name]; ok { panic(name + " already exists") } hist := &Histogram{ name: name, hist: hdrhistogram.NewWindowed(5, minValue, maxValue, sigfigs), } histograms[name] = hist Gauge(name+".P50").SetBatchFunc(hname(name), hist.merge, hist.valueAt(50)) Gauge(name+".P75").SetBatchFunc(hname(name), hist.merge, hist.valueAt(75)) Gauge(name+".P90").SetBatchFunc(hname(name), hist.merge, hist.valueAt(90)) Gauge(name+".P95").SetBatchFunc(hname(name), hist.merge, hist.valueAt(95)) Gauge(name+".P99").SetBatchFunc(hname(name), hist.merge, hist.valueAt(99)) Gauge(name+".P999").SetBatchFunc(hname(name), hist.merge, hist.valueAt(99.9)) return hist }