初始化提交
This commit is contained in:
110
mengyamonitor-backend/network.go
Normal file
110
mengyamonitor-backend/network.go
Normal file
@@ -0,0 +1,110 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user