package stat import ( "io" "bufio" "regexp" "strings" "fmt" ) 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) Parse(r io.Reader) ([]NetDevStat, error) { var ( scanner = bufio.NewScanner(r) procNetDevFieldSep = regexp.MustCompile("[ :] *") netDevStats = []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])] netDevStats = append(netDevStats, 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], }) } return netDevStats, scanner.Err() }