diff --git a/cli/analyze.go b/cli/analyze.go index 073b286..1954251 100644 --- a/cli/analyze.go +++ b/cli/analyze.go @@ -417,7 +417,7 @@ func writeSegs(ctx *cli.Context, wrSegs io.Writer, ops bench.Operations, allThre } segs.SortByTime() - err := segs.CSV(wrSegs) + err := segs.CSV(wrSegs, "") errorIf(probe.NewError(err), "Error writing analysis") start := segs[0].Start wantSegs := len(segs) @@ -425,7 +425,7 @@ func writeSegs(ctx *cli.Context, wrSegs io.Writer, ops bench.Operations, allThre // Write segments per endpoint eps := ops.SortSplitByEndpoint() if len(eps) == 1 { - cl := ops.SortSplitByClient() + cl := ops.SortSplitByClient("client_") if len(cl) > 1 { eps = cl } @@ -452,7 +452,7 @@ func writeSegs(ctx *cli.Context, wrSegs io.Writer, ops bench.Operations, allThre segs.SortByObjsPerSec() } segs.SortByTime() - err := segs.CSV(wrSegs) + err := segs.CSV(wrSegs, ep) errorIf(probe.NewError(err), "Error writing analysis") } } diff --git a/pkg/aggregate/aggregate.go b/pkg/aggregate/aggregate.go index 53e79b6..7bf96e8 100644 --- a/pkg/aggregate/aggregate.go +++ b/pkg/aggregate/aggregate.go @@ -25,6 +25,9 @@ import ( "github.com/minio/warp/pkg/bench" ) +// Prefix used, when all host names are the same, but multiple clients were used. +var clientAsHostPrefix = "Client_" + // Aggregated contains aggregated data for a single benchmark run. type Aggregated struct { // MixedServerStats and MixedThroughputByHost is populated only when data is mixed. @@ -135,7 +138,7 @@ func Aggregate(o bench.Operations, opts Options) Aggregated { eps := o.SortSplitByEndpoint() if len(eps) == 1 { - cl := ops.SortSplitByClient() + cl := ops.SortSplitByClient(clientAsHostPrefix) if len(cl) > 1 { eps = cl } @@ -236,8 +239,9 @@ func Aggregate(o bench.Operations, opts Options) Aggregated { eps := allOps.SortSplitByEndpoint() if len(eps) == 1 { - cl := ops.SortSplitByClient() + cl := ops.SortSplitByClient(clientAsHostPrefix) if len(cl) > 1 { + a.HostNames = ops.ClientIDs(clientAsHostPrefix) eps = cl } } diff --git a/pkg/aggregate/requests.go b/pkg/aggregate/requests.go index bddfb7a..45549dc 100644 --- a/pkg/aggregate/requests.go +++ b/pkg/aggregate/requests.go @@ -234,7 +234,7 @@ func RequestAnalysisSingleSized(o bench.Operations, allThreads bool) *SingleSize res.HostNames = o.Endpoints() res.ByHost = RequestAnalysisHostsSingleSized(o) if len(res.HostNames) != len(res.ByHost) { - res.HostNames = o.ClientIDs() + res.HostNames = o.ClientIDs(clientAsHostPrefix) } return &res } @@ -243,10 +243,13 @@ func RequestAnalysisSingleSized(o bench.Operations, allThreads bool) *SingleSize func RequestAnalysisHostsSingleSized(o bench.Operations) map[string]SingleSizedRequests { eps := o.SortSplitByEndpoint() if len(eps) == 1 { - cl := o.SortSplitByClient() + cl := o.SortSplitByClient(clientAsHostPrefix) if len(cl) > 1 { eps = cl } + if len(eps) == 1 { + return nil + } } res := make(map[string]SingleSizedRequests, len(eps)) var wg sync.WaitGroup @@ -284,8 +287,8 @@ func RequestAnalysisMultiSized(o bench.Operations, allThreads bool) *MultiSizedR res.fill(active) res.ByHost = RequestAnalysisHostsMultiSized(active) res.HostNames = active.Endpoints() - if len(res.HostNames) != len(res.ByHost) { - res.HostNames = o.ClientIDs() + if len(res.HostNames) != len(res.ByHost) && len(res.ByHost) > 0 { + res.HostNames = o.ClientIDs(clientAsHostPrefix) } return &res } @@ -295,11 +298,15 @@ func RequestAnalysisHostsMultiSized(o bench.Operations) map[string]RequestSizeRa start, end := o.TimeRange() eps := o.SortSplitByEndpoint() if len(eps) == 1 { - cl := o.SortSplitByClient() + cl := o.SortSplitByClient(clientAsHostPrefix) if len(cl) > 1 { eps = cl } + if len(eps) == 1 { + return nil + } } + res := make(map[string]RequestSizeRange, len(eps)) var wg sync.WaitGroup var mu sync.Mutex diff --git a/pkg/bench/analyze.go b/pkg/bench/analyze.go index 58abc97..e35eff6 100644 --- a/pkg/bench/analyze.go +++ b/pkg/bench/analyze.go @@ -235,7 +235,7 @@ func (s Segments) Print(w io.Writer) error { } // CSV writes segments to a supplied writer as CSV data. -func (s Segments) CSV(w io.Writer) error { +func (s Segments) CSV(w io.Writer, hostOvr string) error { cw := csv.NewWriter(w) cw.Comma = '\t' err := cw.Write([]string{ @@ -261,7 +261,7 @@ func (s Segments) CSV(w io.Writer) error { return err } for i, seg := range s { - err := seg.CSV(cw, i) + err := seg.CSV(cw, i, hostOvr) if err != nil { return err } @@ -271,12 +271,15 @@ func (s Segments) CSV(w io.Writer) error { } // CSV writes a CSV representation of the segment to the supplied writer. -func (s Segment) CSV(w *csv.Writer, idx int) error { +func (s Segment) CSV(w *csv.Writer, idx int, host string) error { mib, ops, objs := s.SpeedPerSec() + if host == "" { + host = s.Host + } return w.Write([]string{ fmt.Sprint(idx), s.OpType, - s.Host, + host, fmt.Sprint(float64(s.EndsBefore.Sub(s.Start)) / float64(time.Second)), fmt.Sprint(s.ObjsPerOp), fmt.Sprint(s.TotalBytes), diff --git a/pkg/bench/ops.go b/pkg/bench/ops.go index 5eb7891..6f4551b 100644 --- a/pkg/bench/ops.go +++ b/pkg/bench/ops.go @@ -386,7 +386,7 @@ func (o Operations) SortSplitByEndpoint() map[string]Operations { } // SortSplitByClient will sort operations by endpoint and split by host. -func (o Operations) SortSplitByClient() map[string]Operations { +func (o Operations) SortSplitByClient(prefix string) map[string]Operations { clients := o.Clients() o.SortByClient() dst := make(map[string]Operations, clients) @@ -405,6 +405,13 @@ func (o Operations) SortSplitByClient() map[string]Operations { if cl != "" { dst[cl] = o[start:] } + if prefix != "" { + dst2 := make(map[string]Operations, len(dst)) + for k, v := range dst { + dst2[prefix+k] = v + } + return dst2 + } return dst } @@ -891,7 +898,7 @@ func (o Operations) Endpoints() []string { return dst } -func (o Operations) ClientIDs() []string { +func (o Operations) ClientIDs(prefix string) []string { if len(o) == 0 { return nil } @@ -901,7 +908,7 @@ func (o Operations) ClientIDs() []string { } dst := make([]string, 0, len(found)) for k := range found { - dst = append(dst, k) + dst = append(dst, prefix+k) } sort.Strings(dst) return dst