Skip to content

Commit

Permalink
Merge pull request #981 from jimmidyson/net-stats-from-proc
Browse files Browse the repository at this point in the history
Improve perf of interface stats parsing
  • Loading branch information
jimmidyson committed Nov 27, 2015
2 parents fe7e856 + 360c73c commit a40b67f
Showing 1 changed file with 46 additions and 15 deletions.
61 changes: 46 additions & 15 deletions container/libcontainer/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,38 +149,70 @@ func isIgnoredDevice(ifName string) bool {
const netstatsLine = `%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d`

func scanInterfaceStats(netStatsFile string) ([]info.InterfaceStats, error) {
var (
bkt uint64
)

stats := []info.InterfaceStats{}

file, err := os.Open(netStatsFile)
if err != nil {
return stats, fmt.Errorf("failure opening %s: %v", netStatsFile, err)
return nil, fmt.Errorf("failure opening %s: %v", netStatsFile, err)
}
defer file.Close()

scanner := bufio.NewScanner(file)

// Discard header lines
for i := 0; i < 2; i++ {
if b := scanner.Scan(); !b {
return nil, scanner.Err()
}
}

stats := []info.InterfaceStats{}
for scanner.Scan() {
line := scanner.Text()
line = strings.Replace(line, ":", "", -1)

i := info.InterfaceStats{}
fields := strings.Fields(line)
// If the format of the line is invalid then don't trust any of the stats
// in this file.
if len(fields) != 17 {
return nil, fmt.Errorf("invalid interface stats line: %v", line)
}

devName := fields[0]
if isIgnoredDevice(devName) {
continue
}

i := info.InterfaceStats{
Name: devName,
}

_, err := fmt.Sscanf(line, netstatsLine,
&i.Name, &i.RxBytes, &i.RxPackets, &i.RxErrors, &i.RxDropped, &bkt, &bkt, &bkt,
&bkt, &i.TxBytes, &i.TxPackets, &i.TxErrors, &i.TxDropped, &bkt, &bkt, &bkt, &bkt)
statFields := append(fields[1:5], fields[9:13]...)
statPointers := []*uint64{
&i.RxBytes, &i.RxPackets, &i.RxErrors, &i.RxDropped,
&i.TxBytes, &i.TxPackets, &i.TxErrors, &i.TxDropped,
}

if err == nil && !isIgnoredDevice(i.Name) {
stats = append(stats, i)
err := setInterfaceStatValues(statFields, statPointers)
if err != nil {
return nil, fmt.Errorf("cannot parse interface stats (%v): %v", err, line)
}

stats = append(stats, i)
}

return stats, nil
}

func setInterfaceStatValues(fields []string, pointers []*uint64) error {
for i, v := range fields {
val, err := strconv.ParseUint(v, 10, 64)
if err != nil {
return err
}
*pointers[i] = val
}
return nil
}

func tcpStatsFromProc(rootFs string, pid int, file string) (info.TcpStat, error) {
tcpStatsFile := path.Join(rootFs, "proc", strconv.Itoa(pid), file)

Expand Down Expand Up @@ -221,8 +253,7 @@ func scanTcpStats(tcpStatsFile string) (info.TcpStat, error) {
scanner.Split(bufio.ScanLines)

// Discard header line
b := scanner.Scan()
if !b {
if b := scanner.Scan(); !b {
return stats, scanner.Err()
}

Expand Down

0 comments on commit a40b67f

Please sign in to comment.