72 lines
1.6 KiB
Go
72 lines
1.6 KiB
Go
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",
|
|
}
|
|
|
|
type nicCounters struct {
|
|
stats map[string]uint64
|
|
carrierChanges uint64
|
|
carrierUp uint64
|
|
carrierDown uint64
|
|
}
|
|
|
|
func readUint(path string) (uint64, bool) {
|
|
b, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return 0, false
|
|
}
|
|
v, err := strconv.ParseUint(strings.TrimSpace(string(b)), 10, 64)
|
|
if err != nil {
|
|
return 0, false
|
|
}
|
|
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 {
|
|
if v, ok := readUint(base + "/statistics/" + f); ok {
|
|
c.stats[f] = v
|
|
}
|
|
}
|
|
c.carrierChanges, _ = readUint(base + "/carrier_changes")
|
|
c.carrierUp, _ = readUint(base + "/carrier_up_count")
|
|
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, " ")
|
|
}
|