Count link and syscall failures instead of printing them
This commit is contained in:
+31
-41
@@ -1,27 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var nicFields = []string{
|
||||
"rx_packets", "tx_packets",
|
||||
"rx_errors", "tx_errors",
|
||||
"rx_dropped", "tx_dropped",
|
||||
"rx_crc_errors", "rx_missed_errors",
|
||||
"rx_length_errors", "rx_over_errors",
|
||||
"rx_frame_errors", "rx_fifo_errors",
|
||||
"collisions",
|
||||
}
|
||||
// Everything the driver counts against a frame the link failed to carry, split
|
||||
// by direction of travel so each counter belongs to exactly one direction: the
|
||||
// transmitting interface owns the tx fields and the receiving interface the rx
|
||||
// ones. Reading both sets off both interfaces would report every drop twice.
|
||||
var (
|
||||
nicTxFields = []string{
|
||||
"tx_errors", "tx_dropped", "tx_fifo_errors",
|
||||
"tx_carrier_errors", "tx_aborted_errors", "tx_window_errors",
|
||||
"collisions",
|
||||
}
|
||||
nicRxFields = []string{
|
||||
"rx_errors", "rx_dropped", "rx_crc_errors", "rx_missed_errors",
|
||||
"rx_length_errors", "rx_over_errors", "rx_frame_errors", "rx_fifo_errors",
|
||||
}
|
||||
)
|
||||
|
||||
type nicCounters struct {
|
||||
stats map[string]uint64
|
||||
carrierChanges uint64
|
||||
carrierUp uint64
|
||||
carrierDown uint64
|
||||
tx uint64
|
||||
rx uint64
|
||||
carrierDown uint64
|
||||
}
|
||||
|
||||
func readUint(path string) (uint64, bool) {
|
||||
@@ -36,36 +40,22 @@ func readUint(path string) (uint64, bool) {
|
||||
return v, true
|
||||
}
|
||||
|
||||
func readNIC(ifname string) nicCounters {
|
||||
c := nicCounters{stats: make(map[string]uint64, len(nicFields))}
|
||||
base := "/sys/class/net/" + ifname
|
||||
for _, f := range nicFields {
|
||||
func sumFields(base string, fields []string) uint64 {
|
||||
var total uint64
|
||||
for _, f := range fields {
|
||||
if v, ok := readUint(base + "/statistics/" + f); ok {
|
||||
c.stats[f] = v
|
||||
total += v
|
||||
}
|
||||
}
|
||||
c.carrierChanges, _ = readUint(base + "/carrier_changes")
|
||||
c.carrierUp, _ = readUint(base + "/carrier_up_count")
|
||||
return total
|
||||
}
|
||||
|
||||
func readNIC(ifname string) nicCounters {
|
||||
base := "/sys/class/net/" + ifname
|
||||
c := nicCounters{
|
||||
tx: sumFields(base, nicTxFields),
|
||||
rx: sumFields(base, nicRxFields),
|
||||
}
|
||||
c.carrierDown, _ = readUint(base + "/carrier_down_count")
|
||||
return c
|
||||
}
|
||||
|
||||
func (c nicCounters) diff(prev nicCounters) string {
|
||||
var parts []string
|
||||
for _, f := range nicFields {
|
||||
now, ok := c.stats[f]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if d := now - prev.stats[f]; d != 0 && !strings.HasSuffix(f, "_packets") {
|
||||
parts = append(parts, fmt.Sprintf("%s=%d", f, d))
|
||||
}
|
||||
}
|
||||
if d := c.carrierChanges - prev.carrierChanges; d != 0 {
|
||||
parts = append(parts, fmt.Sprintf("carrier_changes=%d", d))
|
||||
}
|
||||
if d := c.carrierDown - prev.carrierDown; d != 0 {
|
||||
parts = append(parts, fmt.Sprintf("carrier_down=%d", d))
|
||||
}
|
||||
return strings.Join(parts, " ")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user