2017-10-23 05:31:04 +00:00
|
|
|
package stat
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
2017-10-23 09:08:19 +00:00
|
|
|
"fmt"
|
|
|
|
"io"
|
2017-10-23 05:31:04 +00:00
|
|
|
"regexp"
|
|
|
|
"strings"
|
2017-10-24 09:23:56 +00:00
|
|
|
"strconv"
|
|
|
|
"git.loafle.net/overflow/ssh_crawler/util"
|
2017-10-23 05:31:04 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type NetDevStat struct {
|
2017-10-24 07:09:17 +00:00
|
|
|
Iface,
|
|
|
|
RecvByte,
|
|
|
|
RecvPacket,
|
|
|
|
RecvErr,
|
|
|
|
RecvDrop,
|
|
|
|
RecvFifo,
|
|
|
|
RecvFrame,
|
|
|
|
RecvCompressed,
|
|
|
|
RecvMulticast,
|
|
|
|
TransByte,
|
|
|
|
TransPacket,
|
|
|
|
TransErr,
|
|
|
|
TransDrop,
|
|
|
|
TransFifo,
|
|
|
|
TransFrame,
|
|
|
|
TransCompressed,
|
|
|
|
TransMulticast string
|
2017-10-23 05:31:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (net *NetDevStat) Command() string {
|
|
|
|
return "cat /proc/net/dev"
|
|
|
|
}
|
|
|
|
|
2017-10-25 08:37:32 +00:00
|
|
|
func (net *NetDevStat) Read(r io.Reader, keys []string) (interface{}, error) {
|
2017-10-23 05:31:04 +00:00
|
|
|
var (
|
|
|
|
scanner = bufio.NewScanner(r)
|
|
|
|
procNetDevFieldSep = regexp.MustCompile("[ :] *")
|
2017-10-24 09:23:56 +00:00
|
|
|
stats = []NetDevStat{}
|
2017-10-23 05:31:04 +00:00
|
|
|
)
|
|
|
|
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])]
|
2017-10-24 09:23:56 +00:00
|
|
|
stats = append(stats, NetDevStat{
|
2017-10-24 07:09:17 +00:00
|
|
|
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],
|
2017-10-23 05:31:04 +00:00
|
|
|
})
|
|
|
|
}
|
2017-10-24 09:23:56 +00:00
|
|
|
|
2017-10-25 08:37:32 +00:00
|
|
|
if keys == nil {
|
|
|
|
return &stats, nil
|
|
|
|
}
|
|
|
|
|
2017-10-24 09:23:56 +00:00
|
|
|
res, err := net.parse(keys, stats)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &res, scanner.Err()
|
2017-10-23 09:08:19 +00:00
|
|
|
}
|
2017-10-24 09:23:56 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|