package stat import ( "bufio" "fmt" "io" "regexp" "strings" ) 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() }