ssh_crawler/stat/network.go
insanity d75e100746 ing
2017-10-25 17:37:32 +09:00

143 lines
3.2 KiB
Go

package stat
import (
"bufio"
"fmt"
"io"
"regexp"
"strings"
"strconv"
"git.loafle.net/overflow/ssh_crawler/util"
)
type NetDevStat struct {
Iface,
RecvByte,
RecvPacket,
RecvErr,
RecvDrop,
RecvFifo,
RecvFrame,
RecvCompressed,
RecvMulticast,
TransByte,
TransPacket,
TransErr,
TransDrop,
TransFifo,
TransFrame,
TransCompressed,
TransMulticast string
}
func (net *NetDevStat) Command() string {
return "cat /proc/net/dev"
}
func (net *NetDevStat) Read(r io.Reader, keys []string) (interface{}, error) {
var (
scanner = bufio.NewScanner(r)
procNetDevFieldSep = regexp.MustCompile("[ :] *")
stats = []NetDevStat{}
)
scanner.Scan()
scanner.Scan()
parts := strings.Split(scanner.Text(), "|")
if len(parts) != 3 { // interface + receive + transmit
return nil, fmt.Errorf("invalid header line in net/dev: %s",
scanner.Text())
}
header := strings.Fields(parts[1])
for scanner.Scan() {
line := strings.TrimLeft(scanner.Text(), " ")
parts := procNetDevFieldSep.Split(line, -1)
if len(parts) != 2*len(header)+1 {
return nil, fmt.Errorf("invalid line in net/dev: %s", scanner.Text())
}
dev := parts[0][:len(parts[0])]
stats = append(stats, NetDevStat{
Iface: dev,
RecvByte: parts[1],
RecvPacket: parts[2],
RecvErr: parts[3],
RecvDrop: parts[4],
RecvFifo: parts[5],
RecvFrame: parts[6],
RecvCompressed: parts[7],
RecvMulticast: parts[8],
TransByte: parts[9],
TransPacket: parts[10],
TransErr: parts[11],
TransDrop: parts[12],
TransFifo: parts[13],
TransFrame: parts[14],
TransCompressed: parts[15],
TransMulticast: parts[16],
})
}
if keys == nil {
return &stats, nil
}
res, err := net.parse(keys, stats)
if err != nil {
return nil, err
}
return &res, scanner.Err()
}
func (net *NetDevStat) parse(keys []string, data []NetDevStat) (map[string]string, error) {
resMap := make(map[string]string)
for _, key := range keys {
t := strings.Split(key, ".")
suffix := t[len(t)-1]
ext := util.ExtractInBracket(key)
idx, _ := strconv.Atoi(ext)
switch suffix {
case "iface":
resMap[key] = data[idx].Iface
case "recv_byte":
resMap[key] = data[idx].RecvByte
case "recv_packet":
resMap[key] = data[idx].RecvPacket
case "recv_err":
resMap[key] = data[idx].RecvErr
case "recv_drop":
resMap[key] = data[idx].RecvDrop
case "recv_fifo":
resMap[key] = data[idx].RecvFifo
case "recv_frame":
resMap[key] = data[idx].RecvFrame
case "recv_compressed":
resMap[key] = data[idx].RecvCompressed
case "recv_multicast":
resMap[key] = data[idx].RecvMulticast
case "send_byte":
resMap[key] = data[idx].TransByte
case "send_packet":
resMap[key] = data[idx].TransPacket
case "send_err":
resMap[key] = data[idx].TransErr
case "send_drop":
resMap[key] = data[idx].TransDrop
case "send_fifo":
resMap[key] = data[idx].TransFifo
case "send_frame":
resMap[key] = data[idx].TransFrame
case "send_compressed":
resMap[key] = data[idx].TransCompressed
case "send_multicast":
resMap[key] = data[idx].TransMulticast
default:
}
}
return resMap, nil
}