Skip to content

Commit

Permalink
Update Kurl API Result type to return all latencies rather than stats…
Browse files Browse the repository at this point in the history
…. Clients can compute stats on their own, or use all data for more advanced plots.
  • Loading branch information
mipnw committed Jan 25, 2020
1 parent 88a2750 commit 34bfc02
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 22 deletions.
23 changes: 5 additions & 18 deletions kurl/do.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ type Result struct {
RequestsCount int
ErrorCount int
OverallDuration time.Duration
ResponseLatencyMin time.Duration
ResponseLatencyAvg time.Duration
ResponseLatencyMax time.Duration
Latencies []time.Duration
StatusCodesFrequency map[int]int
}

Expand Down Expand Up @@ -63,29 +61,16 @@ func aggregateResults(
result := Result{
RequestsCount: settings.ThreadCount * settings.RequestCount,
OverallDuration: elapsed,
ResponseLatencyMin: workerResults[0].latency[0],
ResponseLatencyMax: workerResults[0].latency[0],
StatusCodesFrequency: make(map[int]int),
}

sumLatency := time.Duration(0)
for i := 0; i < settings.ThreadCount; i++ {
result.ErrorCount += workerResults[i].errorCount

for _, latency := range workerResults[i].latency {
sumLatency += latency
if latency < result.ResponseLatencyMin {
result.ResponseLatencyMin = latency
} else if latency > result.ResponseLatencyMax {
result.ResponseLatencyMax = latency
}
}

for statusCode, freq := range workerResults[i].statusCodesCount {
result.StatusCodesFrequency[statusCode] += freq
}
}
result.ResponseLatencyAvg = time.Duration(int64(float64(sumLatency.Milliseconds())/float64(result.RequestsCount))) * time.Millisecond

return result
}

Expand Down Expand Up @@ -121,8 +106,9 @@ func DoManyTest(

// Launch one worker per thread, all blocked on workersBegin signal
workerResults := make([]workerResult, settings.ThreadCount)
latencies := make([]time.Duration, settings.RequestCount*settings.ThreadCount)
for i := 0; i < settings.ThreadCount; i++ {
workerResults[i].latency = make([]time.Duration, settings.RequestCount)
workerResults[i].latency = latencies[i*settings.RequestCount : ((i + 1) * settings.RequestCount)]
workerResults[i].statusCodesCount = make(map[int]int)

workersReady.Add(1)
Expand Down Expand Up @@ -156,5 +142,6 @@ func DoManyTest(

// Aggregate statistics
result := aggregateResults(settings, elapsed, workerResults)
result.Latencies = latencies
return &result, nil
}
37 changes: 33 additions & 4 deletions kurl_cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"fmt"
"github.com/mipnw/kurl/kurl"
"math"
"net/http"
"net/url"
"os"
Expand Down Expand Up @@ -64,6 +65,33 @@ func main() {

result := kurl.Do(settings, *request)

// Compute latency stats
minLatency := result.Latencies[0]
var avgLatency time.Duration
maxLatency := result.Latencies[0]

for i := 0; i < result.RequestsCount; i++ {
avgLatency += result.Latencies[i]

if result.Latencies[i] < minLatency {
minLatency = result.Latencies[i]
} else if result.Latencies[i] > maxLatency {
maxLatency = result.Latencies[i]
}
}
avgLatency = time.Duration(float64(avgLatency.Milliseconds())/float64(result.RequestsCount)) * time.Millisecond

var stdLatency time.Duration
if result.RequestsCount > 1 {
var agg int64
for i := 0; i < result.RequestsCount; i++ {
d := result.Latencies[i] - avgLatency
agg += (d.Microseconds() * d.Microseconds())
}
avg := float64(agg) / float64(result.RequestsCount-1)
stdLatency = time.Duration(math.Sqrt(avg)) * time.Microsecond
}

// Format output
fmt.Printf("total: %d\n", result.RequestsCount)
fmt.Printf("errors: %d\n", result.ErrorCount)
Expand All @@ -75,10 +103,11 @@ func main() {
http.StatusText(statusCode))
}
fmt.Printf("duration: %v\n", result.OverallDuration.Round(time.Millisecond))
fmt.Printf("latency min: %v, avg: %v, max: %v\n",
result.ResponseLatencyMin.Round(time.Millisecond),
result.ResponseLatencyAvg.Round(time.Millisecond),
result.ResponseLatencyMax.Round(time.Millisecond))
fmt.Printf("latency min: %v, avg: %v, max: %v (std:%v)\n",
minLatency.Round(time.Millisecond),
avgLatency.Round(time.Millisecond),
maxLatency.Round(time.Millisecond),
stdLatency.Round(time.Millisecond))
fmt.Printf("rate: %.0f Hz\n", float64(result.RequestsCount)/result.OverallDuration.Seconds())
fmt.Printf("200 rate: %.0f Hz\n ", float64(result.StatusCodesFrequency[200])/result.OverallDuration.Seconds())
}

0 comments on commit 34bfc02

Please sign in to comment.