Files
mengyamonitor/mengyamonitor-backend/network.go
2025-12-14 15:25:31 +08:00

111 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import (
"os"
"os/exec"
"strconv"
"strings"
"time"
)
// readNetworkInterfaces 读取网络接口信息(包含瞬时流量速度) - 优化版:所有接口并行采样
func readNetworkInterfaces() []NetworkInterface {
interfaces := []NetworkInterface{}
// 读取网络接口列表
entries, err := os.ReadDir("/sys/class/net")
if err != nil {
return interfaces
}
// 收集要监控的接口名称
var validIfaces []string
for _, entry := range entries {
ifName := entry.Name()
if ifName == "lo" { // 跳过回环接口
continue
}
// 跳过 Docker 相关网络接口
if strings.HasPrefix(ifName, "docker") ||
strings.HasPrefix(ifName, "br-") ||
strings.HasPrefix(ifName, "veth") {
continue
}
validIfaces = append(validIfaces, ifName)
}
// 第一次批量读取所有接口的流量
firstReadings := make(map[string][2]uint64) // [rx, tx]
for _, ifName := range validIfaces {
rxPath := "/sys/class/net/" + ifName + "/statistics/rx_bytes"
txPath := "/sys/class/net/" + ifName + "/statistics/tx_bytes"
var rxBytes, txBytes uint64
if rxStr := readFirstLine(rxPath); rxStr != "" {
rxBytes, _ = strconv.ParseUint(strings.TrimSpace(rxStr), 10, 64)
}
if txStr := readFirstLine(txPath); txStr != "" {
txBytes, _ = strconv.ParseUint(strings.TrimSpace(txStr), 10, 64)
}
firstReadings[ifName] = [2]uint64{rxBytes, txBytes}
}
// 等待500ms所有接口一起等待而不是每个接口单独等待
time.Sleep(500 * time.Millisecond)
// 第二次批量读取并构建结果
for _, ifName := range validIfaces {
iface := NetworkInterface{
Name: ifName,
}
// 读取 MAC 地址
macPath := "/sys/class/net/" + ifName + "/address"
iface.MACAddress = strings.TrimSpace(readFirstLine(macPath))
// 读取 IP 地址 (使用 ip addr show)
cmd := exec.Command("ip", "addr", "show", ifName)
if out, err := cmd.Output(); err == nil {
lines := strings.Split(string(out), "\n")
for _, line := range lines {
line = strings.TrimSpace(line)
if strings.HasPrefix(line, "inet ") {
fields := strings.Fields(line)
if len(fields) >= 2 {
iface.IPAddress = strings.Split(fields[1], "/")[0]
break
}
}
}
}
// 读取第二次流量统计
rxPath := "/sys/class/net/" + ifName + "/statistics/rx_bytes"
txPath := "/sys/class/net/" + ifName + "/statistics/tx_bytes"
var rxBytes2, txBytes2 uint64
if rxStr := readFirstLine(rxPath); rxStr != "" {
rxBytes2, _ = strconv.ParseUint(strings.TrimSpace(rxStr), 10, 64)
}
if txStr := readFirstLine(txPath); txStr != "" {
txBytes2, _ = strconv.ParseUint(strings.TrimSpace(txStr), 10, 64)
}
// 设置累计流量
iface.RxBytes = rxBytes2
iface.TxBytes = txBytes2
// 计算瞬时速度 (bytes/s乘以2因为采样间隔是0.5秒)
if first, ok := firstReadings[ifName]; ok {
iface.RxSpeed = float64(rxBytes2-first[0]) * 2
iface.TxSpeed = float64(txBytes2-first[1]) * 2
}
interfaces = append(interfaces, iface)
}
return interfaces
}