feat: cli: Nicer net stat
This commit is contained in:
parent
6b68071d2f
commit
3de6856058
91
cli/net.go
91
cli/net.go
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
@ -11,9 +12,11 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/fatih/color"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
protocol "github.com/libp2p/go-libp2p-core/protocol"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
@ -701,9 +704,34 @@ var NetBlockListCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var BarCols = float64(64)
|
||||
|
||||
func BarString(total, y, g float64) string {
|
||||
yBars := int(math.Round(y / total * BarCols))
|
||||
gBars := int(math.Round(g / total * BarCols))
|
||||
if yBars < 0 {
|
||||
yBars = 0
|
||||
}
|
||||
if gBars < 0 {
|
||||
gBars = 0
|
||||
}
|
||||
eBars := int(BarCols) - yBars - gBars
|
||||
var barString = color.YellowString(strings.Repeat("|", yBars)) +
|
||||
color.GreenString(strings.Repeat("|", gBars))
|
||||
if eBars >= 0 {
|
||||
barString += strings.Repeat(" ", eBars)
|
||||
}
|
||||
return barString
|
||||
}
|
||||
|
||||
var NetStatCmd = &cli.Command{
|
||||
Name: "stat",
|
||||
Usage: "Report resource usage for a scope",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "json",
|
||||
},
|
||||
},
|
||||
ArgsUsage: "scope",
|
||||
Description: `Report resource usage for a scope.
|
||||
|
||||
@ -731,11 +759,72 @@ var NetStatCmd = &cli.Command{
|
||||
|
||||
result, err := api.NetStat(ctx, scope)
|
||||
if err != nil {
|
||||
return err
|
||||
return xerrors.Errorf("get stat: %w", err)
|
||||
}
|
||||
|
||||
if cctx.Bool("json") {
|
||||
enc := json.NewEncoder(os.Stdout)
|
||||
return enc.Encode(result)
|
||||
}
|
||||
|
||||
printScope := func(stat *network.ScopeStat, scope string) {
|
||||
if stat == nil {
|
||||
return
|
||||
}
|
||||
|
||||
limit, err := api.NetLimit(ctx, scope)
|
||||
if err != nil {
|
||||
fmt.Printf("error: %s\n", color.RedString("%s", err))
|
||||
}
|
||||
|
||||
fmt.Printf("%s\n", scope)
|
||||
fmt.Printf("\tmemory: [%s] %s/%s\n", BarString(float64(limit.Memory), 0, float64(stat.Memory)),
|
||||
types.SizeStr(types.NewInt(uint64(stat.Memory))),
|
||||
types.SizeStr(types.NewInt(uint64(limit.Memory))))
|
||||
|
||||
fmt.Printf("\tstreams in: [%s] %d/%d\n", BarString(float64(limit.StreamsInbound), 0, float64(stat.NumStreamsInbound)), stat.NumStreamsInbound, limit.StreamsInbound)
|
||||
fmt.Printf("\tstreams out: [%s] %d/%d\n", BarString(float64(limit.StreamsOutbound), 0, float64(stat.NumStreamsOutbound)), stat.NumStreamsOutbound, limit.StreamsOutbound)
|
||||
fmt.Printf("\tconn in: [%s] %d/%d\n", BarString(float64(limit.ConnsInbound), 0, float64(stat.NumConnsInbound)), stat.NumConnsInbound, limit.ConnsInbound)
|
||||
fmt.Printf("\tconn out: [%s] %d/%d\n", BarString(float64(limit.ConnsOutbound), 0, float64(stat.NumConnsOutbound)), stat.NumConnsOutbound, limit.ConnsOutbound)
|
||||
fmt.Printf("\tfile desc: [%s] %d/%d\n", BarString(float64(limit.FD), 0, float64(stat.NumFD)), stat.NumFD, limit.FD)
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
printScope(result.System, "system")
|
||||
printScope(result.Transient, "transient")
|
||||
|
||||
printScopes := func(name string, st map[string]network.ScopeStat) {
|
||||
type namedStat struct {
|
||||
name string
|
||||
stat network.ScopeStat
|
||||
}
|
||||
|
||||
stats := make([]namedStat, 0, len(st))
|
||||
for n, stat := range st {
|
||||
stats = append(stats, namedStat{
|
||||
name: n,
|
||||
stat: stat,
|
||||
})
|
||||
}
|
||||
sort.Slice(stats, func(i, j int) bool {
|
||||
if stats[i].stat.Memory == stats[j].stat.Memory {
|
||||
return stats[i].name < stats[j].name
|
||||
}
|
||||
|
||||
return stats[i].stat.Memory > stats[j].stat.Memory
|
||||
})
|
||||
|
||||
for _, stat := range stats {
|
||||
printScope(&stat.stat, name+stat.name)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
printScopes("svc:", result.Services)
|
||||
printScopes("proto:", result.Protocols)
|
||||
printScopes("peer:", result.Peers)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"net/http"
|
||||
"os"
|
||||
"sort"
|
||||
@ -42,20 +41,6 @@ var sealingCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var barCols = float64(64)
|
||||
|
||||
func barString(total, y, g float64) string {
|
||||
yBars := int(math.Round(y / total * barCols))
|
||||
gBars := int(math.Round(g / total * barCols))
|
||||
eBars := int(barCols) - yBars - gBars
|
||||
var barString = color.YellowString(strings.Repeat("|", yBars)) +
|
||||
color.GreenString(strings.Repeat("|", gBars))
|
||||
if eBars >= 0 {
|
||||
barString += strings.Repeat(" ", eBars)
|
||||
}
|
||||
return barString
|
||||
}
|
||||
|
||||
func workersCmd(sealing bool) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "workers",
|
||||
@ -170,7 +155,7 @@ func workersCmd(sealing bool) *cli.Command {
|
||||
// CPU use
|
||||
|
||||
fmt.Printf("\tCPU: [%s] %d/%d core(s) in use\n",
|
||||
barString(float64(stat.Info.Resources.CPUs), 0, float64(stat.CpuUse)), stat.CpuUse, stat.Info.Resources.CPUs)
|
||||
lcli.BarString(float64(stat.Info.Resources.CPUs), 0, float64(stat.CpuUse)), stat.CpuUse, stat.Info.Resources.CPUs)
|
||||
|
||||
// RAM use
|
||||
|
||||
@ -181,7 +166,7 @@ func workersCmd(sealing bool) *cli.Command {
|
||||
if ramUsed > ramTasks {
|
||||
ramReserved = ramUsed - ramTasks
|
||||
}
|
||||
ramBar := barString(float64(ramTotal), float64(ramReserved), float64(ramTasks))
|
||||
ramBar := lcli.BarString(float64(ramTotal), float64(ramReserved), float64(ramTasks))
|
||||
|
||||
fmt.Printf("\tRAM: [%s] %d%% %s/%s\n", ramBar,
|
||||
(ramTasks+ramReserved)*100/stat.Info.Resources.MemPhysical,
|
||||
@ -197,7 +182,7 @@ func workersCmd(sealing bool) *cli.Command {
|
||||
if vmemUsed > vmemTasks {
|
||||
vmemReserved = vmemUsed - vmemTasks
|
||||
}
|
||||
vmemBar := barString(float64(vmemTotal), float64(vmemReserved), float64(vmemTasks))
|
||||
vmemBar := lcli.BarString(float64(vmemTotal), float64(vmemReserved), float64(vmemTasks))
|
||||
|
||||
fmt.Printf("\tVMEM: [%s] %d%% %s/%s\n", vmemBar,
|
||||
(vmemTasks+vmemReserved)*100/vmemTotal,
|
||||
@ -207,7 +192,7 @@ func workersCmd(sealing bool) *cli.Command {
|
||||
// GPU use
|
||||
|
||||
if len(stat.Info.Resources.GPUs) > 0 {
|
||||
gpuBar := barString(float64(len(stat.Info.Resources.GPUs)), 0, stat.GpuUsed)
|
||||
gpuBar := lcli.BarString(float64(len(stat.Info.Resources.GPUs)), 0, stat.GpuUsed)
|
||||
fmt.Printf("\tGPU: [%s] %.f%% %.2f/%d gpu(s) in use\n", color.GreenString(gpuBar),
|
||||
stat.GpuUsed*100/float64(len(stat.Info.Resources.GPUs)),
|
||||
stat.GpuUsed, len(stat.Info.Resources.GPUs))
|
||||
|
Loading…
Reference in New Issue
Block a user