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 }