- Start 后台每秒采集(CPU/内存/磁盘/网络/进程/连接/主机), GetInfo 取快照 - 基于 gopsutil, 附测试、examples/monitor 例程与包 README
218 lines
5.3 KiB
Go
218 lines
5.3 KiB
Go
package monitor
|
||
|
||
import (
|
||
"sort"
|
||
|
||
"github.com/shirou/gopsutil/v3/net"
|
||
)
|
||
|
||
// NetInfo 网卡信息(gopsutil net.InterfaceStat)
|
||
type NetInfo struct {
|
||
Name string `json:"name"` // interface name
|
||
BytesSent uint64 `json:"bytesSent"` // number of bytes sent
|
||
BytesRecv uint64 `json:"bytesRecv"` // number of bytes received
|
||
PacketsSent uint64 `json:"packetsSent"` // number of packets sent
|
||
PacketsRecv uint64 `json:"packetsRecv"` // number of packets received
|
||
TotalBytesSent uint64 `json:"totalBytesSent"` // number of bytes sent
|
||
TotalBytesRecv uint64 `json:"totalBytesRecv"` // number of bytes received
|
||
TotalPacketsSent uint64 `json:"totalPacketsSent"` // number of packets sent
|
||
TotalPacketsRecv uint64 `json:"totalPacketsRecv"` // number of packets received
|
||
}
|
||
|
||
// NetInfoLite 精简版网卡信息
|
||
type NetInfoLite struct {
|
||
BytesSent uint64 `json:"bytesSent"` // number of bytes sent
|
||
BytesRecv uint64 `json:"bytesRecv"` // number of bytes received
|
||
PacketsSent uint64 `json:"packetsSent"` // number of packets sent
|
||
PacketsRecv uint64 `json:"packetsRecv"` // number of packets received
|
||
TotalBytesSent uint64 `json:"totalBytesSent"` // number of bytes sent
|
||
TotalBytesRecv uint64 `json:"totalBytesRecv"` // number of bytes received
|
||
}
|
||
|
||
// Addr 网卡地址
|
||
type Addr struct {
|
||
Ip string `json:"ip"`
|
||
Port uint32 `json:"port"`
|
||
}
|
||
|
||
// ConnInfo 连接汇总:TCP/UDP 计数、监听端口列表与每进程连接计数
|
||
type ConnInfo struct {
|
||
Fd uint32 `json:"fd"`
|
||
Family uint32 `json:"family"`
|
||
Type uint32 `json:"type"`
|
||
LocalAddr Addr `json:"localAddr"`
|
||
RemoteAddr Addr `json:"remoteAddr"`
|
||
Status string `json:"status"`
|
||
Pid int32 `json:"pid"`
|
||
}
|
||
|
||
// NetListen 监听端口详情
|
||
type NetListen struct {
|
||
Addr string `json:"addr"`
|
||
Port uint32 `json:"port"`
|
||
Conn int `json:"conn"`
|
||
ConnInfo
|
||
}
|
||
|
||
// ProcConn 每进程连接计数
|
||
type ProcConn struct {
|
||
Pid int `json:"pid"`
|
||
Name string `json:"name"`
|
||
Conn int `json:"conn"`
|
||
}
|
||
|
||
// NetConnInfo 单条网络连接信息(gopsutil net.ConnectionStat)
|
||
type NetConnInfo struct {
|
||
Tcp int `json:"tcp"`
|
||
Udp int `json:"udp"`
|
||
Listen []NetListen `json:"listen"`
|
||
}
|
||
|
||
// getNetInfo 采集网卡列表
|
||
func getNetInfo() ([]NetInfo, error) {
|
||
|
||
netIo, err := net.IOCounters(true)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
nets := make([]NetInfo, len(netIo))
|
||
for i, v := range netIo {
|
||
nets[i].Name = netIo[i].Name
|
||
nets[i].TotalBytesSent = v.BytesSent
|
||
nets[i].TotalBytesRecv = v.BytesRecv
|
||
nets[i].TotalPacketsSent = v.PacketsSent
|
||
nets[i].TotalPacketsRecv = v.PacketsRecv
|
||
|
||
// 应该使用网卡名 未处理
|
||
if len(monInfo.Net) > i {
|
||
nets[i].BytesSent = v.BytesSent - monInfo.Net[i].TotalBytesSent
|
||
nets[i].BytesRecv = v.BytesRecv - monInfo.Net[i].TotalBytesRecv
|
||
nets[i].PacketsSent = v.PacketsSent - monInfo.Net[i].TotalPacketsSent
|
||
nets[i].PacketsRecv = v.PacketsRecv - monInfo.Net[i].TotalPacketsRecv
|
||
}
|
||
}
|
||
return nets, err
|
||
}
|
||
|
||
// getNetConnInfo 采集 TCP/UDP 连接计数与监听端口汇总
|
||
func getNetConnInfo() (NetConnInfo, error) {
|
||
|
||
// linux TcpStatus
|
||
/* {
|
||
"01": "ESTABLISHED",
|
||
"02": "SYN_SENT",
|
||
"03": "SYN_RECV",
|
||
"04": "FIN_WAIT1",
|
||
"05": "FIN_WAIT2",
|
||
"06": "TIME_WAIT",
|
||
"07": "CLOSE",
|
||
"08": "CLOSE_WAIT",
|
||
"09": "LAST_ACK",
|
||
"0A": "LISTEN",
|
||
"0B": "CLOSING",
|
||
} */
|
||
|
||
// windows TcpStatus
|
||
/* {
|
||
1: "CLOSED",
|
||
2: "LISTEN",
|
||
3: "SYN_SENT",
|
||
4: "SYN_RECEIVED",
|
||
5: "ESTABLISHED",
|
||
6: "FIN_WAIT_1",
|
||
7: "FIN_WAIT_2",
|
||
8: "CLOSE_WAIT",
|
||
9: "CLOSING",
|
||
10: "LAST_ACK",
|
||
11: "TIME_WAIT",
|
||
12: "DELETE",
|
||
} */
|
||
|
||
/* {
|
||
"all": {kindTCP4, kindTCP6, kindUDP4, kindUDP6},
|
||
"tcp": {kindTCP4, kindTCP6},
|
||
"tcp4": {kindTCP4},
|
||
"tcp6": {kindTCP6},
|
||
"udp": {kindUDP4, kindUDP6},
|
||
"udp4": {kindUDP4},
|
||
"udp6": {kindUDP6},
|
||
"inet": {kindTCP4, kindTCP6, kindUDP4, kindUDP6},
|
||
"inet4": {kindTCP4, kindUDP4},
|
||
"inet6": {kindTCP6, kindUDP6},
|
||
} */
|
||
|
||
info := NetConnInfo{}
|
||
tcp, err := net.Connections("tcp")
|
||
if err != nil {
|
||
return info, nil
|
||
}
|
||
udp, err := net.Connections("udp")
|
||
if err != nil {
|
||
return info, nil
|
||
}
|
||
|
||
//logger.Infof("net conn tcp:%d udp:%d", info.Tcp, info.Udp)
|
||
|
||
// 监听列表
|
||
listen := make([]NetListen, 0)
|
||
for _, v := range tcp {
|
||
if v.Status == "LISTEN" {
|
||
inPort := false
|
||
for _, l := range listen {
|
||
if l.Port == v.Laddr.Port {
|
||
inPort = true
|
||
break
|
||
}
|
||
}
|
||
if !inPort {
|
||
listen = append(listen, NetListen{
|
||
Addr: v.Laddr.IP,
|
||
Port: v.Laddr.Port,
|
||
Conn: 0,
|
||
ConnInfo: ConnInfo{
|
||
Fd: v.Fd,
|
||
Family: v.Family,
|
||
Type: v.Type,
|
||
LocalAddr: Addr{
|
||
Ip: v.Laddr.IP,
|
||
Port: v.Laddr.Port,
|
||
},
|
||
RemoteAddr: Addr{
|
||
Ip: v.Raddr.IP,
|
||
Port: v.Raddr.Port,
|
||
},
|
||
Status: v.Status,
|
||
Pid: v.Pid,
|
||
},
|
||
})
|
||
}
|
||
}
|
||
}
|
||
|
||
// 连接计数
|
||
count := 0
|
||
for _, v := range tcp {
|
||
if v.Status == "ESTABLISHED" {
|
||
for index, l := range listen {
|
||
if l.Port == v.Laddr.Port {
|
||
listen[index].Conn++
|
||
break
|
||
}
|
||
}
|
||
count++
|
||
}
|
||
}
|
||
|
||
//排序
|
||
sort.Slice(listen, func(i, j int) bool {
|
||
return listen[i].Conn > listen[j].Conn
|
||
})
|
||
|
||
// TCP和UDP连接数
|
||
info.Tcp = count //len(tcp)
|
||
info.Udp = len(udp)
|
||
|
||
info.Listen = listen
|
||
return info, nil
|
||
}
|