mirror of
https://github.com/LBRYFoundation/tracker.git
synced 2025-08-23 17:47:29 +00:00
Add response time stats
This commit is contained in:
parent
0a4c290ecb
commit
7fce8c9ad4
3 changed files with 47 additions and 3 deletions
|
@ -38,13 +38,16 @@ func makeHandler(handler ResponseHandler) httprouter.Handle {
|
||||||
http.Error(w, err.Error(), httpCode)
|
http.Error(w, err.Error(), httpCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
duration := time.Since(start)
|
||||||
|
stats.RecordTiming(stats.ResponseTime, duration)
|
||||||
|
|
||||||
if glog.V(2) {
|
if glog.V(2) {
|
||||||
glog.Infof(
|
glog.Infof(
|
||||||
"Completed %v %s %s in %v",
|
"Completed %v %s %s in %v",
|
||||||
httpCode,
|
httpCode,
|
||||||
http.StatusText(httpCode),
|
http.StatusText(httpCode),
|
||||||
r.URL.Path,
|
r.URL.Path,
|
||||||
time.Since(start),
|
duration,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package stats
|
package stats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
@ -78,6 +79,10 @@ func (p *Percentile) index() int64 {
|
||||||
return idx
|
return idx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Percentile) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(p.Value())
|
||||||
|
}
|
||||||
|
|
||||||
func round(value float64) int64 {
|
func round(value float64) int64 {
|
||||||
if value < 0.0 {
|
if value < 0.0 {
|
||||||
value -= 0.5
|
value -= 0.5
|
||||||
|
|
|
@ -37,6 +37,8 @@ const (
|
||||||
|
|
||||||
HandledRequest
|
HandledRequest
|
||||||
ErroredRequest
|
ErroredRequest
|
||||||
|
|
||||||
|
ResponseTime
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultStats is a default instance of stats tracking that uses an unbuffered
|
// DefaultStats is a default instance of stats tracking that uses an unbuffered
|
||||||
|
@ -60,6 +62,12 @@ type PeerStats struct {
|
||||||
SeedsReaped uint64 `json:"seeds_reaped"`
|
SeedsReaped uint64 `json:"seeds_reaped"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PercentileTimes struct {
|
||||||
|
P50 *Percentile
|
||||||
|
P90 *Percentile
|
||||||
|
P95 *Percentile
|
||||||
|
}
|
||||||
|
|
||||||
type Stats struct {
|
type Stats struct {
|
||||||
Start time.Time `json:"start_time"`
|
Start time.Time `json:"start_time"`
|
||||||
|
|
||||||
|
@ -80,16 +88,27 @@ type Stats struct {
|
||||||
RequestsHandled uint64 `json:"requests_handled"`
|
RequestsHandled uint64 `json:"requests_handled"`
|
||||||
RequestsErrored uint64 `json:"requests_errored"`
|
RequestsErrored uint64 `json:"requests_errored"`
|
||||||
|
|
||||||
|
ResponseTime PercentileTimes `json:"response_time"`
|
||||||
|
|
||||||
events chan int
|
events chan int
|
||||||
|
responseTimeEvents chan time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(chanSize int) *Stats {
|
func New(chanSize int) *Stats {
|
||||||
s := &Stats{
|
s := &Stats{
|
||||||
Start: time.Now(),
|
Start: time.Now(),
|
||||||
events: make(chan int, chanSize),
|
events: make(chan int, chanSize),
|
||||||
|
|
||||||
|
responseTimeEvents: make(chan time.Duration, chanSize),
|
||||||
|
ResponseTime: PercentileTimes{
|
||||||
|
P50: NewPercentile(0.5, 128),
|
||||||
|
P90: NewPercentile(0.9, 128),
|
||||||
|
P95: NewPercentile(0.95, 128),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
go s.handleEvents()
|
go s.handleEvents()
|
||||||
|
go s.handleTimings()
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
@ -107,7 +126,12 @@ func (s *Stats) RecordEvent(event int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Stats) RecordTiming(event int, duration time.Duration) {
|
func (s *Stats) RecordTiming(event int, duration time.Duration) {
|
||||||
// s.timingEvents <- event
|
switch event {
|
||||||
|
case ResponseTime:
|
||||||
|
s.responseTimeEvents <- duration
|
||||||
|
default:
|
||||||
|
panic("stats: RecordTiming called with an unknown event")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Stats) handleEvents() {
|
func (s *Stats) handleEvents() {
|
||||||
|
@ -182,6 +206,18 @@ func (s *Stats) handleEvents() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Stats) handleTimings() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case duration := <-s.responseTimeEvents:
|
||||||
|
f := float64(duration) / float64(time.Millisecond)
|
||||||
|
s.ResponseTime.P50.AddSample(f)
|
||||||
|
s.ResponseTime.P90.AddSample(f)
|
||||||
|
s.ResponseTime.P95.AddSample(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// RecordEvent broadcasts an event to the default stats queue.
|
// RecordEvent broadcasts an event to the default stats queue.
|
||||||
func RecordEvent(event int) {
|
func RecordEvent(event int) {
|
||||||
DefaultStats.RecordEvent(event)
|
DefaultStats.RecordEvent(event)
|
||||||
|
|
Loading…
Add table
Reference in a new issue