Files
nodeprobe/internal/netstat/netstat.go
2026-01-04 21:51:40 +08:00

135 lines
3.1 KiB
Go

package netstat
import (
"bufio"
"fmt"
"os"
"strings"
"time"
)
// InterfaceStats 网卡统计信息
type InterfaceStats struct {
Name string //网卡名称
RxBytes uint64 //接收字节数
TxBytes uint64 //发送字节数
RxPackets uint64 //接收数据包数
TxPackets uint64 //发送数据包数
RxErrors uint64 //接收错误数
TxErrors uint64 //发送错误数
}
type TrafficRate struct {
Name string // 网卡名称
RxBytesRate float64 // 接收字节速率
TxBytesRate float64 // 发送字节速率
RxKbps float64 // 接收比特速率
TxKbps float64 // 发送比特速率
}
// GetInterfaceStats 获取所有网卡的统计信息
func GetInterfaceStats() ([]InterfaceStats, error) {
// 打开/proc/net/dev文件
file, err := os.Open("/proc/net/dev")
if err != nil {
return nil, err
}
defer file.Close()
// 创建scanner逐行读取文件内容
scanner := bufio.NewScanner(file)
// 跳过前两行 头部信息
scanner.Scan()
scanner.Scan()
var stats []InterfaceStats
for scanner.Scan() {
line := scanner.Text()
// 按空格分割
fields := strings.Fields(line)
if len(fields) < 17 {
continue
}
// 提取网卡名
ifaceName := strings.TrimSuffix(fields[0], ":")
if ifaceName == "lo" {
continue //跳过回环接口
}
stat := InterfaceStats{
Name: ifaceName,
RxBytes: parseUint64(fields[1]),
RxPackets: parseUint64(fields[2]),
RxErrors: parseUint64(fields[3]),
TxBytes: parseUint64(fields[9]),
TxPackets: parseUint64(fields[10]),
TxErrors: parseUint64(fields[11]),
}
stats = append(stats, stat)
}
return stats, scanner.Err()
}
func parseUint64(s string) uint64 {
var val uint64
fmt.Sscanf(s, "%d", &val)
return val
}
func CalculateRate(prev, curr []InterfaceStats, duration time.Duration) []TrafficRate {
prevMap := make(map[string]InterfaceStats)
for _, stat := range prev {
prevMap[stat.Name] = stat
}
var rates []TrafficRate
seconds := duration.Seconds()
for _, c := range curr {
p, exists := prevMap[c.Name]
if !exists {
continue
}
rxBytesDiff := c.RxBytes - p.RxBytes
txBytesDiff := c.TxBytes - p.TxBytes
rate := TrafficRate{
Name: c.Name,
RxBytesRate: float64(rxBytesDiff) / seconds,
TxBytesRate: float64(txBytesDiff) / seconds,
RxKbps: (float64(rxBytesDiff) * 8) / (seconds * 1024),
TxKbps: (float64(txBytesDiff) * 8) / (seconds * 1024),
}
rates = append(rates, rate)
}
return rates
}
func FormatBytes(bytes float64) string {
const unit = 1024
if bytes < unit {
return fmt.Sprintf("%.2f B", bytes)
}
div, exp := uint64(unit), 0
for n := bytes / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%.2f %cB", bytes/float64(div), "KMGTPE"[exp])
}
// FormatBps 格式化比特率为 1.23 Kbps、4.56 Mbps 等
func FormatBps(bps float64) string {
const unit = 1000
if bps < unit {
return fmt.Sprintf("%.2f bps", bps)
}
div, exp := float64(unit), 0
for n := bps / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%.2f %cps", bps/div, "KMGTPE"[exp])
}