Files
old-vegeta/lib/metrics.go
Tomás Senart 4ba3b431a8 Change percentiles field names as they were misleading
Also removes the total latencies field from Metrics as it is not useful.
2013-10-05 23:15:32 +02:00

77 lines
2.1 KiB
Go

package vegeta
import (
"strconv"
"time"
"github.com/bmizerany/perks/quantile"
)
// Metrics holds the stats computed out of a slice of Results
// that is used for some of the Reporters
type Metrics struct {
Latencies struct {
Mean time.Duration `json:"mean"`
P95 time.Duration `json:"95th"` // P95 is the 95th percentile upper value
P99 time.Duration `json:"99th"` // P99 is the 99th percentile upper value
Max time.Duration `json:"max"`
} `json:"latencies"`
BytesIn struct {
Total uint64 `json:"total"`
Mean float64 `json:"mean"`
} `json:"bytes_in"`
BytesOut struct {
Total uint64 `json:"total"`
Mean float64 `json:"mean"`
} `json:"bytes_out"`
Requests uint64 `json:"requests"`
Success float64 `json:"success"`
StatusCodes map[string]int `json:"status_codes"`
Errors []string `json:"errors"`
}
// NewMetrics computes and returns a Metrics struct out of a slice of Results
func NewMetrics(results []Result) *Metrics {
m := &Metrics{
Requests: uint64(len(results)),
StatusCodes: map[string]int{},
}
errorSet := map[string]struct{}{}
quants := quantile.NewTargeted(0.95, 0.99)
totalSuccess, totalLatencies := 0, time.Duration(0)
for _, result := range results {
quants.Insert(float64(result.Latency))
m.StatusCodes[strconv.Itoa(int(result.Code))]++
totalLatencies += result.Latency
m.BytesOut.Total += result.BytesOut
m.BytesIn.Total += result.BytesIn
if result.Latency > m.Latencies.Max {
m.Latencies.Max = result.Latency
}
if result.Code >= 200 && result.Code < 300 {
totalSuccess++
}
if result.Error != "" {
errorSet[result.Error] = struct{}{}
}
}
m.Latencies.Mean = time.Duration(float64(totalLatencies) / float64(m.Requests))
m.Latencies.P95 = time.Duration(quants.Query(0.95))
m.Latencies.P99 = time.Duration(quants.Query(0.99))
m.BytesIn.Mean = float64(m.BytesIn.Total) / float64(m.Requests)
m.BytesOut.Mean = float64(m.BytesOut.Total) / float64(m.Requests)
m.Success = float64(totalSuccess) / float64(m.Requests)
m.Errors = make([]string, 0, len(errorSet))
for err := range errorSet {
m.Errors = append(m.Errors, err)
}
return m
}