Skip to content

Commit

Permalink
Add last request access stats (#197)
Browse files Browse the repository at this point in the history
Similar to stats for first access to an object, provide last object access 
stats, but only print them in detailed mode.
  • Loading branch information
klauspost authored Nov 23, 2021
1 parent 8d7bda1 commit 721870a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 8 deletions.
17 changes: 15 additions & 2 deletions cli/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ func printRequestAnalysis(ctx *cli.Context, ops aggregate.Operation, details boo
console.Println(" * TTFB:", reqs.FirstByte)
}

if reqs.FirstAccess != nil {
if details && reqs.FirstAccess != nil {
reqs := reqs.FirstAccess
console.Print(
" * First Access: Avg: ", time.Duration(reqs.DurAvgMillis)*time.Millisecond,
Expand All @@ -476,7 +476,20 @@ func printRequestAnalysis(ctx *cli.Context, ops aggregate.Operation, details boo
if reqs.FirstByte != nil {
console.Print(" * First Access TTFB: ", reqs.FirstByte)
}
console.Println("")
}
if details && reqs.LastAccess != nil {
reqs := reqs.LastAccess
console.Print(
" * Last Access: Avg: ", time.Duration(reqs.DurAvgMillis)*time.Millisecond,
", 50%: ", time.Duration(reqs.DurMedianMillis)*time.Millisecond,
", 90%: ", time.Duration(reqs.Dur90Millis)*time.Millisecond,
", 99%: ", time.Duration(reqs.Dur99Millis)*time.Millisecond,
", Fastest: ", time.Duration(reqs.FastestMillis)*time.Millisecond,
", Slowest: ", time.Duration(reqs.SlowestMillis)*time.Millisecond,
"\n")
if reqs.FirstByte != nil {
console.Print(" * Last Access TTFB: ", reqs.FirstByte)
}
}

if eps := reqs.ByHost; len(eps) > 1 && details {
Expand Down
16 changes: 10 additions & 6 deletions pkg/aggregate/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type SingleSizedRequests struct {
// FirstAccess is filled if the same object is accessed multiple times.
// This records the first touch of the object.
FirstAccess *SingleSizedRequests `json:"first_access,omitempty"`
LastAccess *SingleSizedRequests `json:"last_access,omitempty"`
// Host names, sorted.
HostNames []string
// Request times by host.
Expand All @@ -69,14 +70,17 @@ func (a *SingleSizedRequests) fill(ops bench.Operations) {
a.FirstByte = TtfbFromBench(ops.TTFB(start, end))
}

func (a *SingleSizedRequests) fillFirst(ops bench.Operations) {
func (a *SingleSizedRequests) fillFirstLast(ops bench.Operations) {
if !ops.IsMultiTouch() {
return
}
r := SingleSizedRequests{}
ops = ops.FilterFirst()
r.fill(ops)
a.FirstAccess = &r
var first, last SingleSizedRequests
o := ops.FilterFirst()
first.fill(o)
a.FirstAccess = &first
o = ops.FilterLast()
last.fill(o)
a.LastAccess = &last
}

type RequestSizeRange struct {
Expand Down Expand Up @@ -195,7 +199,7 @@ func RequestAnalysisSingleSized(o bench.Operations, allThreads bool) *SingleSize
return &res
}
res.fill(active)
res.fillFirst(o)
res.fillFirstLast(o)
res.HostNames = o.Endpoints()
res.ByHost = RequestAnalysisHostsSingleSized(o)

Expand Down
21 changes: 21 additions & 0 deletions pkg/bench/ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,7 @@ func (o Operations) FilterFirst() Operations {
if len(o) == 0 {
return nil
}
o.SortByStartTime()
ok := make(Operations, 0, 1000)
seen := make(map[string]struct{}, len(o))
for _, op := range o {
Expand All @@ -935,6 +936,26 @@ func (o Operations) FilterFirst() Operations {
return ok
}

// FilterLast returns the last operation on any file.
func (o Operations) FilterLast() Operations {
if len(o) == 0 {
return nil
}
o.SortByStartTime()
ok := make(Operations, 0, 1000)
seen := make(map[string]struct{}, len(o))
for i := len(o) - 1; i >= 0; i-- {
op := o[i]
if _, ok := seen[op.File]; ok {
continue
}
seen[op.File] = struct{}{}
ok = append(ok, op)
}

return ok
}

// Errors returns the errors found.
func (o Operations) FilterErrors() Operations {
if len(o) == 0 {
Expand Down

0 comments on commit 721870a

Please sign in to comment.