380 lines
9.2 KiB
Go
Executable File
380 lines
9.2 KiB
Go
Executable File
package a_status
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/shirou/gopsutil/v3/net"
|
|
"io"
|
|
net2 "net"
|
|
"net/http"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
"wdd.io/agent-common/utils"
|
|
)
|
|
|
|
type NetworkMetric struct {
|
|
net.IOCountersStat
|
|
|
|
SendSpeed float64
|
|
RecvSpeed float64
|
|
}
|
|
|
|
type PublicNetworkInfo struct {
|
|
IP string `json:"ip,omitempty"`
|
|
City string `json:"city,omitempty"`
|
|
Region string `json:"region,omitempty"`
|
|
Country string `json:"country,omitempty"`
|
|
Loc string `json:"loc,omitempty"`
|
|
Org string `json:"org,omitempty"`
|
|
Postal string `json:"postal,omitempty"`
|
|
Timezone string `json:"timezone,omitempty"`
|
|
}
|
|
|
|
func (pn *PublicNetworkInfo) GetPublicNetworkInfo() {
|
|
|
|
url := "https://ipinfo.io"
|
|
req, err := http.NewRequest("GET", url, nil)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
req.Header.Set("Authorization", "Bearer 6ecb0db9bd8f19")
|
|
client := &http.Client{
|
|
Timeout: 5 * time.Second, // set timeout to 10 seconds
|
|
}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
err = json.Unmarshal(body, &pn)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
//utils.BeautifulPrint(pn)
|
|
|
|
}
|
|
|
|
type NetworkInfo struct {
|
|
Name string `json:"name"` // e.g., "en0", "lo0", "eth0.100"
|
|
MTU int `json:"mtu"` // maximum transmission unit
|
|
HardwareAddr string `json:"hardwareAddr"` // IEEE MAC-48, EUI-48 and EUI-64 form
|
|
Flags []string `json:"flags"` // e.g., FlagUp, FlagLoopback, FlagMulticast
|
|
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"`
|
|
}
|
|
|
|
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 GetNetworkMetric() ([]NetworkMetric, error) {
|
|
interfaceStatList, err := net.Interfaces()
|
|
if err != nil {
|
|
log.ErrorF("[GetNetworkMetric] - get interface list error %v\n", err)
|
|
return nil, err
|
|
}
|
|
contains := false
|
|
for _, interfaceStat := range interfaceStatList {
|
|
if MatchNetInterfaceRight(interfaceStat.Name) {
|
|
contains = true
|
|
break
|
|
}
|
|
}
|
|
if !contains {
|
|
msg := "[GetNetworkMetric]- can not find desired net interface !"
|
|
log.Warn(msg)
|
|
return nil, errors.New(msg)
|
|
}
|
|
|
|
ioCountersStats, err := net.IOCounters(true)
|
|
if err != nil {
|
|
log.ErrorF("[GetNetworkMetric] - get io counter list error %v\n", err)
|
|
return nil, err
|
|
}
|
|
|
|
//marshal, _ := json.Marshal(ioCountersStats)
|
|
//fmt.Println(string(marshal))
|
|
duration := time.Second * 2
|
|
log.DebugF("[GetNetworkMetric] - start to wait %d seconds ", duration/1000000000)
|
|
time.Sleep(duration)
|
|
|
|
afterIoCounterList, err := net.IOCounters(true)
|
|
if err != nil {
|
|
log.ErrorF("[GetNetworkMetric] - get io counter list second error %v\n", err)
|
|
return nil, err
|
|
}
|
|
|
|
var result []NetworkMetric
|
|
|
|
for _, interfaceStat := range interfaceStatList {
|
|
if MatchNetInterfaceRight(interfaceStat.Name) {
|
|
log.DebugF("[GetNetworkMetric] - match net interface name is => %s", interfaceStat.Name)
|
|
for _, after := range afterIoCounterList {
|
|
if strings.HasPrefix(after.Name, interfaceStat.Name) {
|
|
for _, before := range ioCountersStats {
|
|
if strings.HasPrefix(before.Name, interfaceStat.Name) {
|
|
// match after and before interface
|
|
|
|
// assign
|
|
networkMetric := NetworkMetric{
|
|
IOCountersStat: after,
|
|
SendSpeed: 0,
|
|
RecvSpeed: 0,
|
|
}
|
|
|
|
// calculate speed
|
|
networkMetric.SendSpeed = (float64(after.BytesSent - before.BytesSent)) / duration.Seconds()
|
|
networkMetric.RecvSpeed = (float64(after.BytesRecv - before.BytesRecv)) / duration.Seconds()
|
|
|
|
// append result
|
|
result = append(result, networkMetric)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func GetNetworkInfo() ([]NetworkInfo, error) {
|
|
|
|
interfaceStatList, err := net.Interfaces()
|
|
if err != nil {
|
|
log.ErrorF("[GetNetworkInfo] - get net interface list error %s", err.Error())
|
|
}
|
|
|
|
var result []NetworkInfo
|
|
for _, interfaceStat := range interfaceStatList {
|
|
if MatchNetInterfaceRight(interfaceStat.Name) {
|
|
// just collect useful net interface
|
|
|
|
// new result
|
|
networkInfo := NetworkInfo{
|
|
Name: interfaceStat.Name,
|
|
MTU: interfaceStat.MTU,
|
|
HardwareAddr: interfaceStat.HardwareAddr,
|
|
Flags: interfaceStat.Flags,
|
|
InternalIPv4: []string{},
|
|
InternalIPv6: []string{},
|
|
ExternalIPv4: nil,
|
|
ExternalIPv6: nil,
|
|
}
|
|
|
|
// calculate real ip addr
|
|
for _, interfaceAddr := range interfaceStat.Addrs {
|
|
|
|
ip, cidr, err := net2.ParseCIDR(interfaceAddr.Addr)
|
|
if err != nil {
|
|
log.ErrorF("[GetNetworkInfo] - parse interface addr error %v", err)
|
|
continue
|
|
}
|
|
|
|
// get the mask size
|
|
maskLength, _ := cidr.Mask.Size()
|
|
if ip.To4() != nil {
|
|
networkInfo.InternalIPv4 = append(networkInfo.InternalIPv4, ip.String()+"/"+strconv.Itoa(maskLength))
|
|
} else if ip.To16() != nil {
|
|
networkInfo.InternalIPv6 = append(networkInfo.InternalIPv6, ip.String()+"/"+strconv.Itoa(maskLength))
|
|
}
|
|
}
|
|
|
|
// assign
|
|
result = append(result, networkInfo)
|
|
}
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func GetLocalHostIP() string {
|
|
interfaceStatList, err := net.Interfaces()
|
|
if err != nil {
|
|
log.ErrorF("[GetLocalHostIP] -- error %s", err.Error())
|
|
return ""
|
|
}
|
|
|
|
utils.BeautifulPrint(interfaceStatList)
|
|
|
|
return ""
|
|
}
|
|
|
|
func GetNetworkConnectionALl() []net.ConnectionStat {
|
|
|
|
connections, err := net.Connections("all")
|
|
if err != nil {
|
|
log.ErrorF("[GetNetworkConnectionALl] - get network connections error ! %v", err)
|
|
return nil
|
|
}
|
|
for _, con := range connections {
|
|
fmt.Println()
|
|
marshal, _ := json.Marshal(con)
|
|
fmt.Println(string(marshal))
|
|
fmt.Println()
|
|
}
|
|
return connections
|
|
}
|
|
|
|
func GetNetworkConnectionTCP4() {
|
|
|
|
}
|
|
|
|
func GetNetworkConnectionTCP6() {
|
|
connections, _ := net.Connections("tcp6")
|
|
for _, con := range connections {
|
|
fmt.Println()
|
|
marshal, _ := json.Marshal(con)
|
|
fmt.Println(string(marshal))
|
|
fmt.Println()
|
|
}
|
|
}
|
|
|
|
func GetNetworkConnectionUDP4() {
|
|
|
|
}
|
|
|
|
func GetNetworkConnectionUDP6() {
|
|
|
|
}
|
|
|
|
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 := GetInternalIpAdders(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 GetInternalIpAdders(addresses []string) (ipv4List []string, ipv6List []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 {
|
|
ipv4List = append(ipv4List, addr)
|
|
} else if ip.To16() != nil {
|
|
ipv6List = append(ipv6List, addr)
|
|
}
|
|
}
|
|
return ipv4List, ipv6List
|
|
}
|
|
|
|
func MatchNetInterfaceRight(interfaceName string) bool {
|
|
|
|
match, _ := regexp.MatchString(`^(eth|enp|wlan|ens|eno)\d+`, interfaceName)
|
|
if match {
|
|
return true
|
|
}
|
|
|
|
match, _ = regexp.MatchString(`^(lo)`, interfaceName)
|
|
if match {
|
|
return true
|
|
}
|
|
|
|
return match
|
|
}
|