Skip to content

Commit

Permalink
*: add json tag to RunnerMetricReport
Browse files Browse the repository at this point in the history
* Do not show key/value if value is empty
* Add BuildPercentileLatencies back into metrics pkg
* Render time.Duration into string

Signed-off-by: Wei Fu <weifu@microsoft.com>
  • Loading branch information
fuweid committed Jan 19, 2024
1 parent 39b3e2e commit 4926a5d
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 15 deletions.
14 changes: 6 additions & 8 deletions api/types/metric.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package types

import "time"

// ResponseStats is the report about benchmark result.
type ResponseStats struct {
// List of failures
Expand All @@ -14,15 +12,15 @@ type ResponseStats struct {

type RunnerMetricReport struct {
// Total represents total number of requests.
Total int
Total int `json:"total"`
// List of failures
FailureList []error
FailureList []error `json:"failureList,omitempty"`
// Duration means the time of benchmark.
Duration time.Duration
Duration string `json:"duration"`
// All the observed latencies
Latencies []float64
Latencies []float64 `json:"latencies,omitempty"`
// total bytes read from apiserver
TotalReceivedBytes int64
TotalReceivedBytes int64 `json:"totalReceivedBytes"`
// PercentileLatencies represents the latency distribution in seconds.
PercentileLatencies [][2]float64 // [2]float64{percentile, value}
PercentileLatencies [][2]float64 `json:"percentileLatencies,omitempty"`
}
15 changes: 8 additions & 7 deletions cmd/kperf/commands/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"strconv"

"github.com/Azure/kperf/api/types"
"github.com/Azure/kperf/metrics"
"github.com/Azure/kperf/request"

"github.com/urfave/cli"
Expand Down Expand Up @@ -183,13 +184,15 @@ func loadConfig(cliCtx *cli.Context) (*types.LoadProfile, error) {
return &profileCfg, nil
}

// printResponseStats prints types.RunnerMetricReport into underlying file.
func printResponseStats(f *os.File, rawDataFlagIncluded bool, stats *request.Result) error {
output := types.RunnerMetricReport{
Total: stats.Total,
FailureList: stats.FailureList,
Duration: stats.Duration,
Latencies: stats.Latencies,
TotalReceivedBytes: stats.TotalReceivedBytes,
Total: stats.Total,
FailureList: stats.FailureList,
Duration: stats.Duration.String(),
Latencies: stats.Latencies,
TotalReceivedBytes: stats.TotalReceivedBytes,
PercentileLatencies: metrics.BuildPercentileLatencies(stats.Latencies),
}

encoder := json.NewEncoder(f)
Expand All @@ -203,7 +206,5 @@ func printResponseStats(f *os.File, rawDataFlagIncluded bool, stats *request.Res
if err != nil {
return fmt.Errorf("failed to encode json: %w", err)
}

return nil

}
28 changes: 28 additions & 0 deletions metrics/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package metrics

import (
"math"
"sort"
)

// BuildPercentileLatencies builds percentile latencies.
func BuildPercentileLatencies(latencies []float64) [][2]float64 {
if len(latencies) == 0 {
return nil
}

var percentiles = []float64{0, 0.5, 0.90, 0.95, 0.99, 1}

res := make([][2]float64, len(percentiles))

n := len(latencies)
sort.Float64s(latencies)
for pi, pv := range percentiles {
idx := int(math.Ceil(float64(n) * pv))
if idx > 0 {
idx--
}
res[pi] = [2]float64{pv, latencies[idx]}
}
return res
}
33 changes: 33 additions & 0 deletions metrics/utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package metrics

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestBuildPercentileLatencies(t *testing.T) {
ls := make([]float64, 100)
ls[0] = 50
ls[1] = 49
ls[2] = 1
res := BuildPercentileLatencies(ls)
assert.Equal(t, [2]float64{0, 0}, res[0])
assert.Equal(t, [2]float64{0.5, 0}, res[1])
assert.Equal(t, [2]float64{0.9, 0}, res[2])
assert.Equal(t, [2]float64{0.95, 0}, res[3])
assert.Equal(t, [2]float64{0.99, 49}, res[4])
assert.Equal(t, [2]float64{1, 50}, res[5])

ls = make([]float64, 1000)
ls[0] = 50
ls[1] = 49
ls[2] = -1
res = BuildPercentileLatencies(ls)
assert.Equal(t, [2]float64{0, -1}, res[0])
assert.Equal(t, [2]float64{0.5, 0}, res[1])
assert.Equal(t, [2]float64{0.9, 0}, res[2])
assert.Equal(t, [2]float64{0.95, 0}, res[3])
assert.Equal(t, [2]float64{0.99, 0}, res[4])
assert.Equal(t, [2]float64{1, 50}, res[5])
}

0 comments on commit 4926a5d

Please sign in to comment.