diff --git a/.gitignore b/.gitignore index 0bfa83c..1306df1 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,6 @@ bin/ # Go workspace file go.work + +#tmp folder which contains .yaml files +tmp/ \ No newline at end of file diff --git a/api/types/metric.go b/api/types/metric.go index d6eb2c1..f5ad2ed 100644 --- a/api/types/metric.go +++ b/api/types/metric.go @@ -6,8 +6,8 @@ import "time" type ResponseStats struct { // Total represents total number of requests. Total int - // Failures represents number of failure request. - Failures int + // List of failures + FailureList []error // Duration means the time of benchmark. Duration time.Duration // PercentileLatencies represents the latency distribution in seconds. diff --git a/cmd/kperf/commands/runner/runner.go b/cmd/kperf/commands/runner/runner.go index 0acea61..0745433 100644 --- a/cmd/kperf/commands/runner/runner.go +++ b/cmd/kperf/commands/runner/runner.go @@ -115,7 +115,10 @@ func loadConfig(cliCtx *cli.Context) (*types.LoadProfile, error) { func printResponseStats(stats *types.ResponseStats) { fmt.Println("Response stat:") fmt.Printf(" Total: %v\n", stats.Total) - fmt.Printf(" Failures: %v\n", stats.Failures) + fmt.Printf(" Total Failures: %v\n", len(stats.FailureList)) + for _, v := range stats.FailureList { + fmt.Printf(" Failure: %v\n", v) + } fmt.Printf(" Duration: %v\n", stats.Duration) fmt.Printf(" Requests/sec: %.2f\n", float64(stats.Total)/stats.Duration.Seconds()) diff --git a/metrics/request.go b/metrics/request.go index 374c929..80d7712 100644 --- a/metrics/request.go +++ b/metrics/request.go @@ -5,7 +5,6 @@ import ( "math" "sort" "sync" - "sync/atomic" ) // ResponseMetric is a measurement related to http response. @@ -13,20 +12,22 @@ type ResponseMetric interface { // ObserveLatency observes latency. ObserveLatency(seconds float64) // ObserveFailure observes failure response. - ObserveFailure() + ObserveFailure(err error) // Gather returns the summary. - Gather() (latencies []float64, percentileLatencies map[float64]float64, failure int) + Gather() (latencies []float64, percentileLatencies map[float64]float64, failureList []error) } type responseMetricImpl struct { - mu sync.Mutex - failureCount int64 - latencies *list.List + mu sync.Mutex + failureList []error + latencies *list.List } func NewResponseMetric() ResponseMetric { + errList := make([]error, 0, 1024) return &responseMetricImpl{ - latencies: list.New(), + latencies: list.New(), + failureList: errList, } } @@ -38,15 +39,16 @@ func (m *responseMetricImpl) ObserveLatency(seconds float64) { } // ObserveFailure implements ResponseMetric. -func (m *responseMetricImpl) ObserveFailure() { - atomic.AddInt64(&m.failureCount, 1) +func (m *responseMetricImpl) ObserveFailure(err error) { + m.mu.Lock() + defer m.mu.Unlock() + m.failureList = append(m.failureList, err) } // Gather implements ResponseMetric. -func (m *responseMetricImpl) Gather() ([]float64, map[float64]float64, int) { +func (m *responseMetricImpl) Gather() ([]float64, map[float64]float64, []error) { latencies := m.dumpLatencies() - - return latencies, buildPercentileLatencies(latencies), int(atomic.LoadInt64(&m.failureCount)) + return latencies, buildPercentileLatencies(latencies), m.failureList } func (m *responseMetricImpl) dumpLatencies() []float64 { diff --git a/request/schedule.go b/request/schedule.go index 246fcc1..7a2a83d 100644 --- a/request/schedule.go +++ b/request/schedule.go @@ -64,8 +64,9 @@ func Schedule(ctx context.Context, spec *types.LoadProfileSpec, restCli []rest.I // we don't need that unmarshal object. _, err = io.Copy(io.Discard, respBody) } + if err != nil { - respMetric.ObserveFailure() + respMetric.ObserveFailure(err) } }() } @@ -80,10 +81,10 @@ func Schedule(ctx context.Context, spec *types.LoadProfileSpec, restCli []rest.I totalDuration := time.Since(start) - _, percentileLatencies, failures := respMetric.Gather() + _, percentileLatencies, failureList := respMetric.Gather() return &types.ResponseStats{ Total: spec.Total, - Failures: failures, + FailureList: failureList, Duration: totalDuration, PercentileLatencies: percentileLatencies, }, nil