// NewHistogram creates a new windowed HDRHistogram with the given parameters. // Data is kept in the active window for approximately the given duration. // See the the documentation for hdrhistogram.WindowedHistogram for details. func NewHistogram(duration time.Duration, maxVal int64, sigFigs int) *Histogram { h := &Histogram{} h.maxVal = int64(maxVal) h.interval = duration / histWrapNum h.nextT = now() h.windowed = hdrhistogram.NewWindowed(histWrapNum, 0, h.maxVal, sigFigs) return h }
func newWindowedHistogram(name string, minValue, maxValue int64, sigfigs int, quantiles map[int]metrics.Gauge, logger log.Logger) *windowedHistogram { h := &windowedHistogram{ hist: hdrhistogram.NewWindowed(5, minValue, maxValue, sigfigs), name: name, gauges: quantiles, logger: logger, } go h.rotateLoop(1 * time.Minute) return h }
// newSlidingHistogram creates a new windowed HDRHistogram with the given // parameters. Data is kept in the active window for approximately the given // duration. See the documentation for hdrhistogram.WindowedHistogram for // details. func newSlidingHistogram(duration time.Duration, maxVal int64, sigFigs int) *slidingHistogram { if duration <= 0 { panic("cannot create a sliding histogram with nonpositive duration") } return &slidingHistogram{ nextT: now(), duration: duration, windowed: hdrhistogram.NewWindowed(histWrapNum, 0, maxVal, sigFigs), } }
// NewHistogram creates a new windowed HDRHistogram with the given parameters. // Data is kept in the active window for approximately the given duration. // See the documentation for hdrhistogram.WindowedHistogram for details. func NewHistogram(metadata Metadata, duration time.Duration, maxVal int64, sigFigs int) *Histogram { return &Histogram{ Metadata: metadata, maxVal: maxVal, nextT: now(), duration: duration, windowed: hdrhistogram.NewWindowed(histWrapNum, 0, maxVal, sigFigs), } }
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() } } }
// NewHistogram is taken from http://github.com/codahale/metrics. It returns a // windowed HDR histogram which drops data older than five minutes. // // The histogram exposes metrics for each passed quantile as gauges. Quantiles // should be integers in the range 1..99. The gauge names are assigned by // using the passed name as a prefix and appending "_pNN" e.g. "_p50". func NewHistogram(name string, minValue, maxValue int64, sigfigs int, quantiles ...int) metrics.Histogram { gauges := map[int]metrics.Gauge{} for _, quantile := range quantiles { if quantile <= 0 || quantile >= 100 { panic(fmt.Sprintf("invalid quantile %d", quantile)) } gauges[quantile] = NewGauge(fmt.Sprintf("%s_p%02d", name, quantile)) } h := &histogram{ hist: hdrhistogram.NewWindowed(5, minValue, maxValue, sigfigs), name: name, gauges: gauges, } go h.rotateLoop(1 * time.Minute) return h }
// NewHistogramTick is the same as NewHistoGram, but allows to pass a custom reportTicker. func NewHistogramTick(client stdinflux.Client, bp stdinflux.BatchPoints, key string, tags []metrics.Field, reportTicker <-chan time.Time, minValue, maxValue int64, sigfigs int, quantiles ...int) metrics.Histogram { gauges := map[int]metrics.Gauge{} for _, quantile := range quantiles { if quantile <= 0 || quantile >= 100 { panic(fmt.Sprintf("invalid quantile %d", quantile)) } gauges[quantile] = NewGaugeTick(client, bp, fmt.Sprintf("%s_p%02d", key, quantile), tags, reportTicker) } h := &histogram{ hist: hdrhistogram.NewWindowed(5, minValue, maxValue, sigfigs), key: key, gauges: gauges, } go h.rotateLoop(1 * time.Minute) return h }
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 }