diff --git a/cmd/lotus-shed/mempool-stats.go b/cmd/lotus-shed/mempool-stats.go index d2651a826..320ba31a5 100644 --- a/cmd/lotus-shed/mempool-stats.go +++ b/cmd/lotus-shed/mempool-stats.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "sort" "time" "github.com/ipfs/go-cid" @@ -58,22 +59,68 @@ var mpoolStatsCmd = &cli.Command{ return fmt.Errorf("unrecognized mpool update state: %d", u.Type) } case <-tick: + var ages []time.Duration if len(tracker) == 0 { continue } - var avg time.Duration - var oldest time.Duration for _, v := range tracker { age := time.Since(v.seen) - if age > oldest { - oldest = age - } - - avg += age + ages = append(ages, age) } - fmt.Printf("%d messages in mempool for average of %s, max=%s\n", len(tracker), avg/time.Duration(len(tracker)), oldest) + + st := ageStats(ages) + fmt.Printf("%d messages in mempool for average of %s, (%s / %s / %s)\n", st.Count, st.Average, st.Perc50, st.Perc80, st.Perc95) } } return nil }, } + +type ageStat struct { + Average time.Duration + Max time.Duration + Perc40 time.Duration + Perc50 time.Duration + Perc60 time.Duration + Perc70 time.Duration + Perc80 time.Duration + Perc90 time.Duration + Perc95 time.Duration + Count int +} + +func ageStats(ages []time.Duration) *ageStat { + sort.Slice(ages, func(i, j int) bool { + return ages[i] < ages[j] + }) + + st := ageStat{ + Count: len(ages), + } + var sum time.Duration + for _, a := range ages { + sum += a + if a > st.Max { + st.Max = a + } + } + st.Average = sum / time.Duration(len(ages)) + + p40 := (4 * len(ages)) / 10 + p50 := len(ages) / 2 + p60 := (6 * len(ages)) / 10 + p70 := (7 * len(ages)) / 10 + p80 := (4 * len(ages)) / 5 + p90 := (9 * len(ages)) / 10 + p95 := (19 * len(ages)) / 20 + + st.Perc40 = ages[p40] + st.Perc50 = ages[p50] + st.Perc60 = ages[p60] + st.Perc70 = ages[p70] + st.Perc80 = ages[p80] + st.Perc90 = ages[p90] + st.Perc95 = ages[p95] + + return &st +}