43 lines
890 B
Go
43 lines
890 B
Go
package main
|
|
|
|
import (
|
|
"sort"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// latency collects request durations and reports percentiles. It is safe for
|
|
// concurrent recording.
|
|
type latency struct {
|
|
mu sync.Mutex
|
|
samples []time.Duration
|
|
}
|
|
|
|
func (l *latency) record(d time.Duration) {
|
|
l.mu.Lock()
|
|
l.samples = append(l.samples, d)
|
|
l.mu.Unlock()
|
|
}
|
|
|
|
func (l *latency) count() int {
|
|
l.mu.Lock()
|
|
defer l.mu.Unlock()
|
|
return len(l.samples)
|
|
}
|
|
|
|
// percentiles returns p50/p90/p99 and the max. Returns zeros when empty.
|
|
func (l *latency) percentiles() (p50, p90, p99, max time.Duration) {
|
|
l.mu.Lock()
|
|
s := append([]time.Duration(nil), l.samples...)
|
|
l.mu.Unlock()
|
|
if len(s) == 0 {
|
|
return 0, 0, 0, 0
|
|
}
|
|
sort.Slice(s, func(i, j int) bool { return s[i] < s[j] })
|
|
at := func(q float64) time.Duration {
|
|
idx := int(q * float64(len(s)-1))
|
|
return s[idx]
|
|
}
|
|
return at(0.50), at(0.90), at(0.99), s[len(s)-1]
|
|
}
|