优化网络流量监控显示,添加光标控制和流量条形图

This commit is contained in:
lirui
2026-01-04 22:06:37 +08:00
parent 05297c50fb
commit 232103b08c

View File

@@ -26,8 +26,9 @@ func main() {
// 2. 设置刷新间隔(默认 1 秒)
interval := 1 * time.Second
// 3. 打印表头
printHeader()
// 3. 隐藏光标
fmt.Print("\033[?25l")
defer fmt.Print("\033[?25h") // 退出时恢复光标
// 4. 创建 ticker 定时器
ticker := time.NewTicker(interval)
@@ -37,7 +38,15 @@ func main() {
sigChan := make(chan os.Signal, 1)
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 {
select {
case <-ticker.C:
@@ -50,24 +59,38 @@ func main() {
// 计算速率
rates := netstat.CalculateRate(prevStats, currStats, interval)
// 打印一行统计
// 移动光标到开头并打印统计
moveCursorToTop()
printHeader()
printStats(rates, currStats)
// 更新上一次的数据
prevStats = currStats
case <-sigChan:
fmt.Print("\033[?25h") // 恢复光标
fmt.Println("\nExiting...")
return
}
}
}
// 清屏
func clearScreen() {
fmt.Print("\033[2J")
fmt.Print("\033[H")
}
// 移动光标到顶部
func moveCursorToTop() {
fmt.Print("\033[H")
}
func printHeader() {
fmt.Println("Network Interface Traffic Monitor")
fmt.Println("----------------------------------")
fmt.Printf("%-10s %15s %15s %15s %15s\n",
"Interface", "RX Rate", "TX Rate", "RX Total", "TX Total")
fmt.Printf("%-20s %30s %30s %15s %15s\n",
"Interface", "Download", "Upload", "RX Total", "TX Total")
fmt.Println("----------------------------------")
}
@@ -78,15 +101,72 @@ func printStats(rates []netstat.TrafficRate, stats []netstat.InterfaceStats) {
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 {
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,
netstat.FormatBps(r.RxKbps*1000),
netstat.FormatBps(r.TxKbps*1000),
rxBar,
txBar,
netstat.FormatBytes(float64(s.RxBytes)),
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)
}