From a9657e266060ffb0f3bd8378b596cd9087e37e9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Senart?= Date: Tue, 29 Oct 2013 13:48:37 +0100 Subject: [PATCH] Duration on Metrics and depenendent Reporters This is real duration, calculated by subtracting the last Result's timestamp with the first Result's timestamp. Garbage collection and go routine scheduling delays can affect this number. Fixes #29 --- README.md | 2 ++ lib/metrics.go | 2 ++ lib/metrics_test.go | 7 ++++--- lib/reporters.go | 1 + 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4d7ada1..dd94769 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,7 @@ Specifies the kind of report to be generated. It defaults to text. ##### text ``` Requests [total] 1200 +Duration [total] 1.998307684s Latencies [mean, 95, 99, max] 223.340085ms, 326.913687ms, 416.537743ms, 7.788103259s Bytes In [total, mean] 3714690, 3095.57 Bytes Out [total, mean] 0, 0.00 @@ -149,6 +150,7 @@ Get http://localhost:6060: http: can't write HTTP request on broken connection "total": 0, "mean": 0 }, + "duration": 1998307684, "requests": 1200, "success": 0.11666666666666667, "status_codes": { diff --git a/lib/metrics.go b/lib/metrics.go index 3df37e1..f0d0877 100644 --- a/lib/metrics.go +++ b/lib/metrics.go @@ -27,6 +27,7 @@ type Metrics struct { Mean float64 `json:"mean"` } `json:"bytes_out"` + Duration time.Duration `json:"duration"` Requests uint64 `json:"requests"` Success float64 `json:"success"` StatusCodes map[string]int `json:"status_codes"` @@ -60,6 +61,7 @@ func NewMetrics(results []Result) *Metrics { } } + m.Duration = results[len(results)-1].Timestamp.Sub(results[0].Timestamp) 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)) diff --git a/lib/metrics_test.go b/lib/metrics_test.go index a66b1ae..32a1c17 100644 --- a/lib/metrics_test.go +++ b/lib/metrics_test.go @@ -7,9 +7,9 @@ import ( func TestNewMetrics(t *testing.T) { m := NewMetrics([]Result{ - Result{500, time.Now(), 100 * time.Millisecond, 10, 30, "Internal server error"}, - Result{200, time.Now(), 20 * time.Millisecond, 20, 20, ""}, - Result{200, time.Now(), 30 * time.Millisecond, 30, 10, ""}, + Result{500, time.Unix(0, 0), 100 * time.Millisecond, 10, 30, "Internal server error"}, + Result{200, time.Unix(1, 0), 20 * time.Millisecond, 20, 20, ""}, + Result{200, time.Unix(2, 0), 30 * time.Millisecond, 30, 10, ""}, }) for field, values := range map[string][]float64{ @@ -27,6 +27,7 @@ func TestNewMetrics(t *testing.T) { "Latencies.Mean": []time.Duration{m.Latencies.Mean, 50 * time.Millisecond}, "Latencies.P95": []time.Duration{m.Latencies.P95, 30 * time.Millisecond}, "Latencies.P99": []time.Duration{m.Latencies.P99, 30 * time.Millisecond}, + "Duration": []time.Duration{m.Duration, 2 * time.Second}, } { if values[0] != values[1] { t.Errorf("%s: want: %s, got: %s", field, values[1], values[0]) diff --git a/lib/reporters.go b/lib/reporters.go index 0fe829a..482ce61 100644 --- a/lib/reporters.go +++ b/lib/reporters.go @@ -19,6 +19,7 @@ func ReportText(results []Result) ([]byte, error) { w := tabwriter.NewWriter(out, 0, 8, 2, '\t', tabwriter.StripEscape) fmt.Fprintf(w, "Requests\t[total]\t%d\n", m.Requests) + fmt.Fprintf(w, "Duration\t[total]\t%s\n", m.Duration) fmt.Fprintf(w, "Latencies\t[mean, 95, 99, max]\t%s, %s, %s, %s\n", m.Latencies.Mean, m.Latencies.P95, m.Latencies.P99, m.Latencies.Max) fmt.Fprintf(w, "Bytes In\t[total, mean]\t%d, %.2f\n", m.BytesIn.Total, m.BytesIn.Mean)