122 lines
3.0 KiB
Go
122 lines
3.0 KiB
Go
package status
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/shirou/gopsutil/v3/net"
|
|
net2 "net"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type NetworkStatus struct {
|
|
Name string `json:"name,omitempty"`
|
|
InternalIPv4 []string `json:"internal_ip_v4,omitempty"`
|
|
InternalIPv6 []string `json:"internal_ip_v6,omitempty"`
|
|
ExternalIPv4 []string `json:"external_ip_v4,omitempty"`
|
|
ExternalIPv6 []string `json:"external_ip_v6,omitempty"`
|
|
Mac string `json:"mac,omitempty"`
|
|
Sent uint64 `json:"sent,omitempty"`
|
|
Recv uint64 `json:"recv,omitempty"`
|
|
SentRate string `json:"sent_rate,omitempty"`
|
|
RecvRate string `json:"recv_rate,omitempty"`
|
|
}
|
|
|
|
func GetNetworkStatus() (*NetworkStatus, error) {
|
|
interfaces, err := net.Interfaces()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var mainInterface net.InterfaceStat
|
|
for _, intf := range interfaces {
|
|
if strings.HasPrefix(intf.Name, "ens") || strings.HasPrefix(intf.Name, "eth") || strings.HasPrefix(intf.Name, "eno") {
|
|
mainInterface = intf
|
|
break
|
|
}
|
|
}
|
|
var allAddrs []string
|
|
log.DebugF("all main interface address are %v", mainInterface.Addrs)
|
|
for _, addr := range mainInterface.Addrs {
|
|
allAddrs = append(allAddrs, addr.Addr)
|
|
}
|
|
ipv4List, ipv6List := GetInternelIpAddrs(allAddrs)
|
|
log.DebugF("ipv4 list are => %v, ipv6 list are => %v", ipv4List, ipv6List)
|
|
|
|
counters, err := net.IOCounters(true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var sent uint64
|
|
var recv uint64
|
|
for _, counter := range counters {
|
|
if counter.Name == mainInterface.Name {
|
|
sent = counter.BytesSent
|
|
recv = counter.BytesRecv
|
|
break
|
|
}
|
|
}
|
|
|
|
// 休眠3秒
|
|
time.Sleep(3 * time.Second)
|
|
|
|
var sentAfter uint64
|
|
var recvAfter uint64
|
|
countersAfter, err := net.IOCounters(true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, counter := range countersAfter {
|
|
if counter.Name == mainInterface.Name {
|
|
sentAfter = counter.BytesSent
|
|
recvAfter = counter.BytesRecv
|
|
break
|
|
}
|
|
}
|
|
sendRate := fmt.Sprintf(formatBytes((sentAfter-sent)/3) + "/s")
|
|
recvRate := fmt.Sprintf(formatBytes((recvAfter-recv)/3) + "/s")
|
|
|
|
info := &NetworkStatus{
|
|
Name: mainInterface.Name,
|
|
InternalIPv4: ipv4List,
|
|
InternalIPv6: ipv6List,
|
|
ExternalIPv4: nil,
|
|
ExternalIPv6: nil,
|
|
Mac: mainInterface.HardwareAddr,
|
|
Sent: sent,
|
|
Recv: recv,
|
|
SentRate: sendRate,
|
|
RecvRate: recvRate,
|
|
}
|
|
return info, nil
|
|
}
|
|
|
|
func formatBytes(bytes uint64) string {
|
|
const unit = 1024
|
|
if bytes < unit {
|
|
return fmt.Sprintf("%d B", bytes)
|
|
}
|
|
div, exp := int64(unit), 0
|
|
for n := bytes / unit; n >= unit; n /= unit {
|
|
div *= unit
|
|
exp++
|
|
}
|
|
return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp])
|
|
}
|
|
|
|
func GetInternelIpAddrs(addresses []string) ([]string, []string) {
|
|
var ipv4 []string
|
|
var ipv6 []string
|
|
for _, addr := range addresses {
|
|
// it parse (0.0.0.0) not cidr
|
|
ip, _, err := net2.ParseCIDR(addr)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if ip.To4() != nil {
|
|
ipv4 = append(ipv4, addr)
|
|
} else if ip.To16() != nil {
|
|
ipv6 = append(ipv6, addr)
|
|
}
|
|
}
|
|
return ipv4, ipv6
|
|
}
|