优化网络流量监控显示,添加光标控制和流量条形图
This commit is contained in:
@@ -26,8 +26,9 @@ func main() {
|
|||||||
// 2. 设置刷新间隔(默认 1 秒)
|
// 2. 设置刷新间隔(默认 1 秒)
|
||||||
interval := 1 * time.Second
|
interval := 1 * time.Second
|
||||||
|
|
||||||
// 3. 打印表头
|
// 3. 隐藏光标
|
||||||
printHeader()
|
fmt.Print("\033[?25l")
|
||||||
|
defer fmt.Print("\033[?25h") // 退出时恢复光标
|
||||||
|
|
||||||
// 4. 创建 ticker 定时器
|
// 4. 创建 ticker 定时器
|
||||||
ticker := time.NewTicker(interval)
|
ticker := time.NewTicker(interval)
|
||||||
@@ -37,7 +38,15 @@ func main() {
|
|||||||
sigChan := make(chan os.Signal, 1)
|
sigChan := make(chan os.Signal, 1)
|
||||||
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
|
||||||
|
|
||||||
// 6. 主循环
|
// 6. 首次显示
|
||||||
|
clearScreen()
|
||||||
|
currStats, _ := netstat.GetInterfaceStats()
|
||||||
|
rates := netstat.CalculateRate(prevStats, currStats, interval)
|
||||||
|
printHeader()
|
||||||
|
printStats(rates, currStats)
|
||||||
|
prevStats = currStats
|
||||||
|
|
||||||
|
// 7. 主循环
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
@@ -50,24 +59,38 @@ func main() {
|
|||||||
// 计算速率
|
// 计算速率
|
||||||
rates := netstat.CalculateRate(prevStats, currStats, interval)
|
rates := netstat.CalculateRate(prevStats, currStats, interval)
|
||||||
|
|
||||||
// 打印一行统计
|
// 移动光标到开头并打印统计
|
||||||
|
moveCursorToTop()
|
||||||
|
printHeader()
|
||||||
printStats(rates, currStats)
|
printStats(rates, currStats)
|
||||||
|
|
||||||
// 更新上一次的数据
|
// 更新上一次的数据
|
||||||
prevStats = currStats
|
prevStats = currStats
|
||||||
|
|
||||||
case <-sigChan:
|
case <-sigChan:
|
||||||
|
fmt.Print("\033[?25h") // 恢复光标
|
||||||
fmt.Println("\nExiting...")
|
fmt.Println("\nExiting...")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 清屏
|
||||||
|
func clearScreen() {
|
||||||
|
fmt.Print("\033[2J")
|
||||||
|
fmt.Print("\033[H")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移动光标到顶部
|
||||||
|
func moveCursorToTop() {
|
||||||
|
fmt.Print("\033[H")
|
||||||
|
}
|
||||||
|
|
||||||
func printHeader() {
|
func printHeader() {
|
||||||
fmt.Println("Network Interface Traffic Monitor")
|
fmt.Println("Network Interface Traffic Monitor")
|
||||||
fmt.Println("----------------------------------")
|
fmt.Println("----------------------------------")
|
||||||
fmt.Printf("%-10s %15s %15s %15s %15s\n",
|
fmt.Printf("%-20s %30s %30s %15s %15s\n",
|
||||||
"Interface", "RX Rate", "TX Rate", "RX Total", "TX Total")
|
"Interface", "Download", "Upload", "RX Total", "TX Total")
|
||||||
fmt.Println("----------------------------------")
|
fmt.Println("----------------------------------")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,15 +101,72 @@ func printStats(rates []netstat.TrafficRate, stats []netstat.InterfaceStats) {
|
|||||||
statsMap[s.Name] = s
|
statsMap[s.Name] = s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 找出最大速率用于归一化
|
||||||
|
maxRate := 0.0
|
||||||
|
for _, r := range rates {
|
||||||
|
if r.RxKbps*1000 > maxRate {
|
||||||
|
maxRate = r.RxKbps * 1000
|
||||||
|
}
|
||||||
|
if r.TxKbps*1000 > maxRate {
|
||||||
|
maxRate = r.TxKbps * 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if maxRate == 0 {
|
||||||
|
maxRate = 1
|
||||||
|
}
|
||||||
|
|
||||||
for _, r := range rates {
|
for _, r := range rates {
|
||||||
s := statsMap[r.Name]
|
s := statsMap[r.Name]
|
||||||
fmt.Printf("%-10s %15s %15s %15s %15s\n",
|
|
||||||
|
// 生成下载和上传的可视化条形图
|
||||||
|
rxBar := makeTrafficBar(r.RxKbps*1000, maxRate, true)
|
||||||
|
txBar := makeTrafficBar(r.TxKbps*1000, maxRate, false)
|
||||||
|
|
||||||
|
fmt.Printf("%-20s %30s %30s %15s %15s\n",
|
||||||
r.Name,
|
r.Name,
|
||||||
netstat.FormatBps(r.RxKbps*1000),
|
rxBar,
|
||||||
netstat.FormatBps(r.TxKbps*1000),
|
txBar,
|
||||||
netstat.FormatBytes(float64(s.RxBytes)),
|
netstat.FormatBytes(float64(s.RxBytes)),
|
||||||
netstat.FormatBytes(float64(s.TxBytes)),
|
netstat.FormatBytes(float64(s.TxBytes)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
fmt.Println()
|
// 清除剩余行(如果接口数量减少)
|
||||||
|
fmt.Print("\033[J")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成流量条形图
|
||||||
|
func makeTrafficBar(bps, maxBps float64, isDownload bool) string {
|
||||||
|
// ANSI 颜色代码
|
||||||
|
green := "\033[32m" // 下载用绿色
|
||||||
|
blue := "\033[36m" // 上传用青色
|
||||||
|
reset := "\033[0m"
|
||||||
|
|
||||||
|
color := blue
|
||||||
|
if isDownload {
|
||||||
|
color = green
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算条形图长度(最多10个字符)
|
||||||
|
barLength := 10
|
||||||
|
filledLength := int((bps / maxBps) * float64(barLength))
|
||||||
|
if filledLength > barLength {
|
||||||
|
filledLength = barLength
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用不同的字符显示强度
|
||||||
|
blocks := []rune{'▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'}
|
||||||
|
bar := ""
|
||||||
|
|
||||||
|
for i := 0; i < barLength; i++ {
|
||||||
|
if i < filledLength {
|
||||||
|
bar += string(blocks[7]) // 满格
|
||||||
|
} else {
|
||||||
|
bar += string(blocks[0]) // 空格
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化速率信息
|
||||||
|
speedStr := netstat.FormatBps(bps)
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s%s%s %9s", color, bar, reset, speedStr)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user