diff --git a/worker.go b/worker.go index 8562df3..a20f8b2 100644 --- a/worker.go +++ b/worker.go @@ -79,6 +79,8 @@ type output struct { errors int med time.Duration // median of durations; calculated on first call to median() + pct90 time.Duration // max 9th decile durations; calculated on first call to percentile90() + max time.Duration // max of durations; calculated on first call to maximum() } func (o *output) median() time.Duration { @@ -90,7 +92,29 @@ func (o *output) median() time.Duration { o.med = o.durations[len(o.durations)/2] } return o.med +} + +func (o *output) maximum() time.Duration { + if o.max == 0 { + // Sort durations and pick the middle one. + sort.Slice(o.durations, func(i, j int) bool { + return o.durations[i] < o.durations[j] + }) + o.max = o.durations[len(o.durations)-1] + } + return o.max +} + +func (o *output) percentile90() time.Duration { + if o.pct90 == 0 { + // Sort durations and pick the middle one. + sort.Slice(o.durations, func(i, j int) bool { + return o.durations[i] < o.durations[j] + }) + o.pct90 = o.durations[len(o.durations)*9/10] + } + return o.pct90 } type worker struct { @@ -147,7 +171,7 @@ func (w *worker) reportAll(em map[string]config.Endpoint) { sorted := w.sortOutput(em) tr := tabwriter.NewWriter(os.Stdout, 3, 2, 2, ' ', 0) for i, a := range sorted { - fmt.Fprintf(tr, "%2d.\t[%v]\t%v", i+1, a.region, a.median()) + fmt.Fprintf(tr, "%2d.\t[%v]\t%v\t%v\t%v", i+1, a.region, a.median(), a.percentile90(), a.maximum()) if a.errors > 0 { fmt.Fprintf(tr, "\t(%d errors)", a.errors) } @@ -167,9 +191,9 @@ func (w *worker) reportCSV(em map[string]config.Endpoint) { close(w.inputs) sorted := w.sortOutput(em) - fmt.Println("region,latency_ns,errors") + fmt.Println("region,latency_ns,latency_pct90_ns,latency_max_ns,errors") for _, a := range sorted { - fmt.Printf("%v,%v,%v\n", a.region, a.median().Nanoseconds(), a.errors) + fmt.Printf("%v,%v,%v,%v,%v\n", a.region, a.median().Nanoseconds(), a.percentile90().Nanoseconds(), a.maximum().Nanoseconds(), a.errors) } }