func newLatencyTracker() *latencyTracker { return &latencyTracker{ estimator: quantile.New( quantile.Unknown(0.01), quantile.Known(0.50, 0.01), quantile.Known(0.95, 0.001), quantile.Known(0.99, 0.0005), quantile.Known(1.0, 0.0005), ), started: time.Now(), } }
// Add implements the Add method of the Report interface by adding the given // Result to Metrics. func (m *Metrics) Add(r *Result) { if m.StatusCodes == nil { m.StatusCodes = map[string]int{} } if m.errors == nil { m.Errors = []string{} m.errors = map[string]struct{}{} } if m.latencies == nil { m.latencies = quantile.New( quantile.Known(0.50, 0.01), quantile.Known(0.95, 0.001), quantile.Known(0.99, 0.0005), ) } m.Requests++ m.StatusCodes[strconv.Itoa(int(r.Code))]++ m.Latencies.Total += r.Latency m.BytesOut.Total += r.BytesOut m.BytesIn.Total += r.BytesIn m.latencies.Add(float64(r.Latency)) if m.Earliest.IsZero() || m.Earliest.After(r.Timestamp) { m.Earliest = r.Timestamp } if r.Timestamp.After(m.Latest) { m.Latest = r.Timestamp } if end := r.End(); end.After(m.End) { m.End = end } if r.Latency > m.Latencies.Max { m.Latencies.Max = r.Latency } if r.Code >= 200 && r.Code < 400 { m.success++ } if r.Error != "" { if _, ok := m.errors[r.Error]; !ok { m.errors[r.Error] = struct{}{} m.Errors = append(m.Errors, r.Error) } } }
func (m *Metrics) init() { if m.StatusCodes == nil { m.StatusCodes = map[string]int{} } if m.errors == nil { m.errors = map[string]struct{}{} } if m.latencies == nil { m.latencies = quantile.New( quantile.Known(0.50, 0.01), quantile.Known(0.95, 0.001), quantile.Known(0.99, 0.0005), ) } }
func main() { f := flag.String("f", "", "file to read") zwn := flag.Int("zwn", 0, "number of entries") rand.Seed(time.Now().UnixNano()) flag.Parse() ch := make(chan int) var r io.Reader if *f == "" { r = os.Stdin } else { var err error r, err = os.Open(*f) if err != nil { log.Fatal(err) } } go sendInts(r, ch) var stream []int bmq := bquantile.NewBiased() gk := fastq.NewGK() sq := squantile.New(squantile.Unknown(0.1)) vvh := gohistogram.NewHistogram(80) zw := fastq.New(*zwn) for v := range ch { stream = append(stream, v) bmq.Insert(float64(v)) gk.Insert(float64(v)) sq.Add(float64(v)) vvh.Add(float64(v)) zw.Update(float64(v)) } fmt.Println("bq:") for i := 1; i <= 10; i++ { fmt.Printf(" % 4g", bmq.Query(float64(i)*0.1)) } fmt.Println() fmt.Println("sq:") for i := 1; i <= 10; i++ { fmt.Printf(" % 4g", sq.Get(float64(i)*0.1)) } fmt.Println() fmt.Println("gk:") for i := 1; i <= 10; i++ { fmt.Printf(" % 4g", gk.Query(float64(i)*0.1)) } fmt.Println() fmt.Println("vv:") for i := 1; i <= 10; i++ { fmt.Printf(" % 4d", int(vvh.Quantile(float64(i)*0.1))) } fmt.Println() fmt.Println("zw: ") zw.Finish() for i := 1; i <= 10; i++ { fmt.Printf(" % 4g", zw.Query(float64(i)*0.1)) } fmt.Println() sort.Ints(stream) fmt.Println("ex: ") for i := 1; i <= 10; i++ { fmt.Printf(" % 4d", stream[int(float64(len(stream))*float64(i)*0.1)-1]) } fmt.Println() }
func main() { cpuprofile := flag.String("cpuprofile", "", "write cpu profile to file") f := flag.String("f", "", "file to read") rand.Seed(time.Now().UnixNano()) flag.Parse() if *cpuprofile != "" { f, err := os.Create(*cpuprofile) if err != nil { log.Fatal(err) } pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } ch := make(chan int) var r io.Reader if *f == "" { r = os.Stdin } else { var err error r, err = os.Open(*f) if err != nil { log.Fatal(err) } } go sendInts(r, ch) var stream []int bmq := bquantile.NewBiased() gk := gogk.New(0.0001) sq := squantile.New(squantile.Unknown(0.0001)) vvh := gohistogram.NewHistogram(80) td := tdigest.New(100) kl := kll.New(1024) for v := range ch { stream = append(stream, v) bmq.Insert(float64(v)) gk.Insert(float64(v)) sq.Add(float64(v)) vvh.Add(float64(v)) td.Add(float64(v), 1) kl.Update(float64(v)) } qq := []float64{0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 0.999, 0.9999, 0.99999} fmt.Println("bq:") for _, q := range qq { fmt.Printf(" % 4g", bmq.Query(q)) } fmt.Println() fmt.Println("sq:") for _, q := range qq { fmt.Printf(" % 4g", sq.Get(q)) } fmt.Println() fmt.Println("gk:") for _, q := range qq { fmt.Printf(" % 4g", gk.Query(q)) } fmt.Println() fmt.Println("vv:") for _, q := range qq { fmt.Printf(" % 4d", int(vvh.Quantile(q))) } fmt.Println() fmt.Println("td: ") for _, q := range qq { fmt.Printf(" % 4d", int(td.Quantile(q))) } fmt.Println() klcdf := kl.CDF() fmt.Println("kl: ") for _, q := range qq { fmt.Printf(" % 4d", int(klcdf.Query(q))) } fmt.Println() sort.Ints(stream) fmt.Println("ex: ") for _, q := range qq { fmt.Printf(" % 4d", stream[int(float64(len(stream))*q)]) } fmt.Println() }