diff --git a/CHANGELOG.md b/CHANGELOG.md index f5ab4fea..eca02bd9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,12 @@ ### **Breaking changes** +* The netdev collector CLI argument `--collector.netdev.ignored-devices` was renamed to `--collector.netdev.device-blacklist` in order to conform with the systemd collector. #1279 + + ### Changes -* [CHANGE] +* [CHANGE] Add `--collector.netdev.device-whitelist`. #1279 * [FEATURE] * [ENHANCEMENT] * [BUGFIX] Fix incorrect sysctl call in BSD meminfo collector, resulting in broken swap metrics on FreeBSD #1345 diff --git a/collector/netdev_bsd.go b/collector/netdev_bsd.go index d846daf5..18eca223 100644 --- a/collector/netdev_bsd.go +++ b/collector/netdev_bsd.go @@ -34,7 +34,7 @@ import ( */ import "C" -func getNetDevStats(ignore *regexp.Regexp) (map[string]map[string]string, error) { +func getNetDevStats(ignore *regexp.Regexp, accept *regexp.Regexp) (map[string]map[string]string, error) { netDev := map[string]map[string]string{} var ifap, ifa *C.struct_ifaddrs @@ -46,7 +46,11 @@ func getNetDevStats(ignore *regexp.Regexp) (map[string]map[string]string, error) for ifa = ifap; ifa != nil; ifa = ifa.ifa_next { if ifa.ifa_addr.sa_family == C.AF_LINK { dev := C.GoString(ifa.ifa_name) - if ignore.MatchString(dev) { + if ignore != nil && ignore.MatchString(dev) { + log.Debugf("Ignoring device: %s", dev) + continue + } + if accept != nil && !accept.MatchString(dev) { log.Debugf("Ignoring device: %s", dev) continue } diff --git a/collector/netdev_common.go b/collector/netdev_common.go index 9fa3cd2b..0c11023b 100644 --- a/collector/netdev_common.go +++ b/collector/netdev_common.go @@ -17,6 +17,7 @@ package collector import ( + "errors" "fmt" "regexp" "strconv" @@ -26,12 +27,14 @@ import ( ) var ( - netdevIgnoredDevices = kingpin.Flag("collector.netdev.ignored-devices", "Regexp of net devices to ignore for netdev collector.").Default("^$").String() + netdevIgnoredDevices = kingpin.Flag("collector.netdev.device-blacklist", "Regexp of net devices to blacklist (mutually exclusive to device-whitelist).").String() + netdevAcceptDevices = kingpin.Flag("collector.netdev.device-whitelist", "Regexp of net devices to whitelist (mutually exclusive to device-blacklist).").String() ) type netDevCollector struct { subsystem string ignoredDevicesPattern *regexp.Regexp + acceptDevicesPattern *regexp.Regexp metricDescs map[string]*prometheus.Desc } @@ -41,16 +44,30 @@ func init() { // NewNetDevCollector returns a new Collector exposing network device stats. func NewNetDevCollector() (Collector, error) { - pattern := regexp.MustCompile(*netdevIgnoredDevices) + if *netdevIgnoredDevices != "" && *netdevAcceptDevices != "" { + return nil, errors.New("device-blacklist & accept-devices are mutually exclusive") + } + + var ignorePattern *regexp.Regexp = nil + if *netdevIgnoredDevices != "" { + ignorePattern = regexp.MustCompile(*netdevIgnoredDevices) + } + + var acceptPattern *regexp.Regexp = nil + if *netdevAcceptDevices != "" { + acceptPattern = regexp.MustCompile(*netdevAcceptDevices) + } + return &netDevCollector{ subsystem: "network", - ignoredDevicesPattern: pattern, + ignoredDevicesPattern: ignorePattern, + acceptDevicesPattern: acceptPattern, metricDescs: map[string]*prometheus.Desc{}, }, nil } func (c *netDevCollector) Update(ch chan<- prometheus.Metric) error { - netDev, err := getNetDevStats(c.ignoredDevicesPattern) + netDev, err := getNetDevStats(c.ignoredDevicesPattern, c.acceptDevicesPattern) if err != nil { return fmt.Errorf("couldn't get netstats: %s", err) } diff --git a/collector/netdev_darwin.go b/collector/netdev_darwin.go index b02ed401..c07e7fa1 100644 --- a/collector/netdev_darwin.go +++ b/collector/netdev_darwin.go @@ -27,7 +27,7 @@ import ( "golang.org/x/sys/unix" ) -func getNetDevStats(ignore *regexp.Regexp) (map[string]map[string]string, error) { +func getNetDevStats(ignore *regexp.Regexp, accept *regexp.Regexp) (map[string]map[string]string, error) { netDev := map[string]map[string]string{} ifs, err := net.Interfaces() @@ -46,6 +46,10 @@ func getNetDevStats(ignore *regexp.Regexp) (map[string]map[string]string, error) log.Debugf("Ignoring device: %s", iface.Name) continue } + if accept != nil && !accept.MatchString(iface.Name) { + log.Debugf("Ignoring device: %s", iface.Name) + continue + } devStats := map[string]string{} devStats["receive_packets"] = strconv.FormatUint(ifaceData.Data.Ipackets, 10) diff --git a/collector/netdev_linux.go b/collector/netdev_linux.go index 4ea09a3e..a5c61635 100644 --- a/collector/netdev_linux.go +++ b/collector/netdev_linux.go @@ -31,17 +31,17 @@ var ( procNetDevFieldSep = regexp.MustCompile(` +`) ) -func getNetDevStats(ignore *regexp.Regexp) (map[string]map[string]string, error) { +func getNetDevStats(ignore *regexp.Regexp, accept *regexp.Regexp) (map[string]map[string]string, error) { file, err := os.Open(procFilePath("net/dev")) if err != nil { return nil, err } defer file.Close() - return parseNetDevStats(file, ignore) + return parseNetDevStats(file, ignore, accept) } -func parseNetDevStats(r io.Reader, ignore *regexp.Regexp) (map[string]map[string]string, error) { +func parseNetDevStats(r io.Reader, ignore *regexp.Regexp, accept *regexp.Regexp) (map[string]map[string]string, error) { scanner := bufio.NewScanner(r) scanner.Scan() // skip first header scanner.Scan() @@ -64,7 +64,11 @@ func parseNetDevStats(r io.Reader, ignore *regexp.Regexp) (map[string]map[string } dev := parts[1] - if ignore.MatchString(dev) { + if ignore != nil && ignore.MatchString(dev) { + log.Debugf("Ignoring device: %s", dev) + continue + } + if accept != nil && !accept.MatchString(dev) { log.Debugf("Ignoring device: %s", dev) continue } diff --git a/collector/netdev_linux_test.go b/collector/netdev_linux_test.go index 7228ae2f..163c87ff 100644 --- a/collector/netdev_linux_test.go +++ b/collector/netdev_linux_test.go @@ -19,14 +19,14 @@ import ( "testing" ) -func TestNetDevStats(t *testing.T) { +func TestNetDevStatsIgnore(t *testing.T) { file, err := os.Open("fixtures/proc/net/dev") if err != nil { t.Fatal(err) } defer file.Close() - netStats, err := parseNetDevStats(file, regexp.MustCompile("^veth")) + netStats, err := parseNetDevStats(file, regexp.MustCompile("^veth"), nil) if err != nil { t.Fatal(err) } @@ -59,3 +59,23 @@ func TestNetDevStats(t *testing.T) { t.Error("want fixture interface 💩0 to exist, but it does not") } } + +func TestNetDevStatsAccept(t *testing.T) { + file, err := os.Open("fixtures/proc/net/dev") + if err != nil { + t.Fatal(err) + } + defer file.Close() + + netStats, err := parseNetDevStats(file, nil, regexp.MustCompile("^💩0$")) + if err != nil { + t.Fatal(err) + } + + if want, got := 1, len(netStats); want != got { + t.Errorf("want count of devices to be %d, got %d", want, got) + } + if want, got := "72", netStats["💩0"]["receive_multicast"]; want != got { + t.Error("want fixture interface 💩0 to exist, but it does not") + } +} diff --git a/collector/netdev_openbsd.go b/collector/netdev_openbsd.go index 0e9c9009..b080cbcd 100644 --- a/collector/netdev_openbsd.go +++ b/collector/netdev_openbsd.go @@ -31,7 +31,7 @@ import ( */ import "C" -func getNetDevStats(ignore *regexp.Regexp) (map[string]map[string]string, error) { +func getNetDevStats(ignore *regexp.Regexp, accept *regexp.Regexp) (map[string]map[string]string, error) { netDev := map[string]map[string]string{} var ifap, ifa *C.struct_ifaddrs @@ -43,7 +43,11 @@ func getNetDevStats(ignore *regexp.Regexp) (map[string]map[string]string, error) for ifa = ifap; ifa != nil; ifa = ifa.ifa_next { if ifa.ifa_addr.sa_family == C.AF_LINK { dev := C.GoString(ifa.ifa_name) - if ignore.MatchString(dev) { + if ignore != nil && ignore.MatchString(dev) { + log.Debugf("Ignoring device: %s", dev) + continue + } + if accept != nil && !accept.MatchString(dev) { log.Debugf("Ignoring device: %s", dev) continue }