Improve perf of interface stats parsing
This commit is contained in:
parent
fe7e8563b7
commit
360c73c6fd
@ -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`
|
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) {
|
func scanInterfaceStats(netStatsFile string) ([]info.InterfaceStats, error) {
|
||||||
var (
|
|
||||||
bkt uint64
|
|
||||||
)
|
|
||||||
|
|
||||||
stats := []info.InterfaceStats{}
|
|
||||||
|
|
||||||
file, err := os.Open(netStatsFile)
|
file, err := os.Open(netStatsFile)
|
||||||
if err != nil {
|
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()
|
defer file.Close()
|
||||||
|
|
||||||
scanner := bufio.NewScanner(file)
|
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() {
|
for scanner.Scan() {
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
line = strings.Replace(line, ":", "", -1)
|
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
|
||||||
_, err := fmt.Sscanf(line, netstatsLine,
|
// in this file.
|
||||||
&i.Name, &i.RxBytes, &i.RxPackets, &i.RxErrors, &i.RxDropped, &bkt, &bkt, &bkt,
|
if len(fields) != 17 {
|
||||||
&bkt, &i.TxBytes, &i.TxPackets, &i.TxErrors, &i.TxDropped, &bkt, &bkt, &bkt, &bkt)
|
return nil, fmt.Errorf("invalid interface stats line: %v", line)
|
||||||
|
|
||||||
if err == nil && !isIgnoredDevice(i.Name) {
|
|
||||||
stats = append(stats, i)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
devName := fields[0]
|
||||||
|
if isIgnoredDevice(devName) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
i := info.InterfaceStats{
|
||||||
|
Name: devName,
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
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) {
|
func tcpStatsFromProc(rootFs string, pid int, file string) (info.TcpStat, error) {
|
||||||
tcpStatsFile := path.Join(rootFs, "proc", strconv.Itoa(pid), file)
|
tcpStatsFile := path.Join(rootFs, "proc", strconv.Itoa(pid), file)
|
||||||
|
|
||||||
@ -221,8 +253,7 @@ func scanTcpStats(tcpStatsFile string) (info.TcpStat, error) {
|
|||||||
scanner.Split(bufio.ScanLines)
|
scanner.Split(bufio.ScanLines)
|
||||||
|
|
||||||
// Discard header line
|
// Discard header line
|
||||||
b := scanner.Scan()
|
if b := scanner.Scan(); !b {
|
||||||
if !b {
|
|
||||||
return stats, scanner.Err()
|
return stats, scanner.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user