zry98 3 weeks ago committed by GitHub
commit 4bdd0892bd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -55,19 +55,23 @@ https://github.com/tailscale/tailscale/blob/main/ipn/ipnstate/ipnstate.go
fs.BoolVar(&statusArgs.self, "self", true, "show status of local machine")
fs.BoolVar(&statusArgs.peers, "peers", true, "show status of peers")
fs.StringVar(&statusArgs.listen, "listen", "127.0.0.1:8384", "listen address for web mode; use port 0 for automatic")
fs.BoolVar(&statusArgs.browser, "browser", true, "Open a browser in web mode")
fs.BoolVar(&statusArgs.browser, "browser", true, "open a browser in web mode")
fs.BoolVar(&statusArgs.humanReadableSI, "human", false, "print human-readable bytes in SI format (in powers of 1000)")
fs.BoolVar(&statusArgs.humanReadableIEC, "human-iec", false, "print human-readable bytes in IEC format (in powers of 1024)")
return fs
})(),
}
var statusArgs struct {
json bool // JSON output mode
web bool // run webserver
listen string // in web mode, webserver address to listen on, empty means auto
browser bool // in web mode, whether to open browser
active bool // in CLI mode, filter output to only peers with active sessions
self bool // in CLI mode, show status of local machine
peers bool // in CLI mode, show status of peer machines
json bool // JSON output mode
web bool // run webserver
listen string // in web mode, webserver address to listen on, empty means auto
browser bool // in web mode, whether to open browser
active bool // in CLI mode, filter output to only peers with active sessions
self bool // in CLI mode, show status of local machine
peers bool // in CLI mode, show status of peer machines
humanReadableSI bool // in CLI mode, print human-readable peer traffic bytes in SI format
humanReadableIEC bool // in CLI mode, print human-readable peer traffic bytes in IEC format
}
func runStatus(ctx context.Context, args []string) error {
@ -193,7 +197,13 @@ func runStatus(ctx context.Context, args []string) error {
}
}
if anyTraffic {
f(", tx %d rx %d", ps.TxBytes, ps.RxBytes)
if statusArgs.humanReadableSI {
f(", tx %s rx %s", humanReadableBytes(ps.TxBytes, true), humanReadableBytes(ps.RxBytes, false))
} else if statusArgs.humanReadableIEC {
f(", tx %s rx %s", humanReadableBytes(ps.TxBytes, false), humanReadableBytes(ps.RxBytes, true))
} else {
f(", tx %d rx %d", ps.TxBytes, ps.RxBytes)
}
}
f("\n")
}
@ -336,3 +346,30 @@ func firstIPString(v []netip.Addr) string {
}
return v[0].String()
}
// humanReadableBytes returns a human-readable string for the given number of bytes.
func humanReadableBytes(b int64, useIEC bool) string {
var base float64
var units []string
if useIEC {
base = 1024
units = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"}
} else {
base = 1000
units = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB"}
}
if b < int64(base) {
return fmt.Sprintf("%d B", b)
}
var exp int
div := float64(b)
for div >= base {
div /= base
exp++
}
if exp >= len(units) {
exp = len(units) - 1
}
return fmt.Sprintf("%.1f %s", div, units[exp])
}

@ -0,0 +1,36 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
package cli
import "testing"
func TestHumanReadableBytes(t *testing.T) {
type args struct {
b int64
useIEC bool
}
tests := []struct {
name string
args args
want string
}{
{"SI_0", args{0, false}, "0 B"},
{"SI_42", args{42, false}, "42 B"},
{"SI_1K", args{1000, false}, "1.0 kB"},
{"SI_1G", args{1000000000, false}, "1.0 GB"},
{"SI_1E", args{1000000000000000000, false}, "1.0 EB"},
{"IEC_0", args{0, true}, "0 B"},
{"IEC_42", args{42, true}, "42 B"},
{"IEC_1K", args{1024, true}, "1.0 KiB"},
{"IEC_1G", args{1073741824, true}, "1.0 GiB"},
{"IEC_1E", args{1152921504606846976, true}, "1.0 EiB"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := humanReadableBytes(tt.args.b, tt.args.useIEC); got != tt.want {
t.Errorf("humanReadableBytes() = %v, want %v", got, tt.want)
}
})
}
}
Loading…
Cancel
Save