feat: cli: Nicer net stat
This commit is contained in:
parent
6b68071d2f
commit
3de6856058
99
cli/net.go
99
cli/net.go
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
@ -11,9 +12,11 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dustin/go-humanize"
|
"github.com/dustin/go-humanize"
|
||||||
|
"github.com/fatih/color"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/libp2p/go-libp2p-core/network"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
protocol "github.com/libp2p/go-libp2p-core/protocol"
|
protocol "github.com/libp2p/go-libp2p-core/protocol"
|
||||||
"github.com/multiformats/go-multiaddr"
|
"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{
|
var NetStatCmd = &cli.Command{
|
||||||
Name: "stat",
|
Name: "stat",
|
||||||
Usage: "Report resource usage for a scope",
|
Usage: "Report resource usage for a scope",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "json",
|
||||||
|
},
|
||||||
|
},
|
||||||
ArgsUsage: "scope",
|
ArgsUsage: "scope",
|
||||||
Description: `Report resource usage for a scope.
|
Description: `Report resource usage for a scope.
|
||||||
|
|
||||||
@ -731,11 +759,72 @@ var NetStatCmd = &cli.Command{
|
|||||||
|
|
||||||
result, err := api.NetStat(ctx, scope)
|
result, err := api.NetStat(ctx, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return xerrors.Errorf("get stat: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
enc := json.NewEncoder(os.Stdout)
|
if cctx.Bool("json") {
|
||||||
return enc.Encode(result)
|
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"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"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 {
|
func workersCmd(sealing bool) *cli.Command {
|
||||||
return &cli.Command{
|
return &cli.Command{
|
||||||
Name: "workers",
|
Name: "workers",
|
||||||
@ -170,7 +155,7 @@ func workersCmd(sealing bool) *cli.Command {
|
|||||||
// CPU use
|
// CPU use
|
||||||
|
|
||||||
fmt.Printf("\tCPU: [%s] %d/%d core(s) in use\n",
|
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
|
// RAM use
|
||||||
|
|
||||||
@ -181,7 +166,7 @@ func workersCmd(sealing bool) *cli.Command {
|
|||||||
if ramUsed > ramTasks {
|
if ramUsed > ramTasks {
|
||||||
ramReserved = 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,
|
fmt.Printf("\tRAM: [%s] %d%% %s/%s\n", ramBar,
|
||||||
(ramTasks+ramReserved)*100/stat.Info.Resources.MemPhysical,
|
(ramTasks+ramReserved)*100/stat.Info.Resources.MemPhysical,
|
||||||
@ -197,7 +182,7 @@ func workersCmd(sealing bool) *cli.Command {
|
|||||||
if vmemUsed > vmemTasks {
|
if vmemUsed > vmemTasks {
|
||||||
vmemReserved = 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,
|
fmt.Printf("\tVMEM: [%s] %d%% %s/%s\n", vmemBar,
|
||||||
(vmemTasks+vmemReserved)*100/vmemTotal,
|
(vmemTasks+vmemReserved)*100/vmemTotal,
|
||||||
@ -207,7 +192,7 @@ func workersCmd(sealing bool) *cli.Command {
|
|||||||
// GPU use
|
// GPU use
|
||||||
|
|
||||||
if len(stat.Info.Resources.GPUs) > 0 {
|
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),
|
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*100/float64(len(stat.Info.Resources.GPUs)),
|
||||||
stat.GpuUsed, len(stat.Info.Resources.GPUs))
|
stat.GpuUsed, len(stat.Info.Resources.GPUs))
|
||||||
|
Loading…
Reference in New Issue
Block a user