mirror of
https://github.com/prometheus/node_exporter.git
synced 2024-11-13 17:14:23 -08:00
Add --collector.netdev.device-whitelist flag (#1279)
* Add --collector.netdev.device-whitelist flag Sometimes it is desired to monitor only one netdev. The golang regexp does not support a negated regex, so the ignored-devices flag is too cumbersome for this task. This change introduces a new flag: accept-devices, which is mutually exclusive to ignored-devices. This flag allows specifying ONLY the netdev you'd like. Signed-off-by: Noam Meltzer <noam@cynerio.co>
This commit is contained in:
parent
fc02b5dfbc
commit
501ccf9fb4
|
@ -2,9 +2,12 @@
|
||||||
|
|
||||||
### **Breaking changes**
|
### **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
|
### Changes
|
||||||
|
|
||||||
* [CHANGE]
|
* [CHANGE] Add `--collector.netdev.device-whitelist`. #1279
|
||||||
* [FEATURE]
|
* [FEATURE]
|
||||||
* [ENHANCEMENT]
|
* [ENHANCEMENT]
|
||||||
* [BUGFIX] Fix incorrect sysctl call in BSD meminfo collector, resulting in broken swap metrics on FreeBSD #1345
|
* [BUGFIX] Fix incorrect sysctl call in BSD meminfo collector, resulting in broken swap metrics on FreeBSD #1345
|
||||||
|
|
|
@ -34,7 +34,7 @@ import (
|
||||||
*/
|
*/
|
||||||
import "C"
|
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{}
|
netDev := map[string]map[string]string{}
|
||||||
|
|
||||||
var ifap, ifa *C.struct_ifaddrs
|
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 {
|
for ifa = ifap; ifa != nil; ifa = ifa.ifa_next {
|
||||||
if ifa.ifa_addr.sa_family == C.AF_LINK {
|
if ifa.ifa_addr.sa_family == C.AF_LINK {
|
||||||
dev := C.GoString(ifa.ifa_name)
|
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)
|
log.Debugf("Ignoring device: %s", dev)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package collector
|
package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -26,12 +27,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
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 {
|
type netDevCollector struct {
|
||||||
subsystem string
|
subsystem string
|
||||||
ignoredDevicesPattern *regexp.Regexp
|
ignoredDevicesPattern *regexp.Regexp
|
||||||
|
acceptDevicesPattern *regexp.Regexp
|
||||||
metricDescs map[string]*prometheus.Desc
|
metricDescs map[string]*prometheus.Desc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,16 +44,30 @@ func init() {
|
||||||
|
|
||||||
// NewNetDevCollector returns a new Collector exposing network device stats.
|
// NewNetDevCollector returns a new Collector exposing network device stats.
|
||||||
func NewNetDevCollector() (Collector, error) {
|
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{
|
return &netDevCollector{
|
||||||
subsystem: "network",
|
subsystem: "network",
|
||||||
ignoredDevicesPattern: pattern,
|
ignoredDevicesPattern: ignorePattern,
|
||||||
|
acceptDevicesPattern: acceptPattern,
|
||||||
metricDescs: map[string]*prometheus.Desc{},
|
metricDescs: map[string]*prometheus.Desc{},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *netDevCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *netDevCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
netDev, err := getNetDevStats(c.ignoredDevicesPattern)
|
netDev, err := getNetDevStats(c.ignoredDevicesPattern, c.acceptDevicesPattern)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get netstats: %s", err)
|
return fmt.Errorf("couldn't get netstats: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ import (
|
||||||
"golang.org/x/sys/unix"
|
"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{}
|
netDev := map[string]map[string]string{}
|
||||||
|
|
||||||
ifs, err := net.Interfaces()
|
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)
|
log.Debugf("Ignoring device: %s", iface.Name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if accept != nil && !accept.MatchString(iface.Name) {
|
||||||
|
log.Debugf("Ignoring device: %s", iface.Name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
devStats := map[string]string{}
|
devStats := map[string]string{}
|
||||||
devStats["receive_packets"] = strconv.FormatUint(ifaceData.Data.Ipackets, 10)
|
devStats["receive_packets"] = strconv.FormatUint(ifaceData.Data.Ipackets, 10)
|
||||||
|
|
|
@ -31,17 +31,17 @@ var (
|
||||||
procNetDevFieldSep = regexp.MustCompile(` +`)
|
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"))
|
file, err := os.Open(procFilePath("net/dev"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer file.Close()
|
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 := bufio.NewScanner(r)
|
||||||
scanner.Scan() // skip first header
|
scanner.Scan() // skip first header
|
||||||
scanner.Scan()
|
scanner.Scan()
|
||||||
|
@ -64,7 +64,11 @@ func parseNetDevStats(r io.Reader, ignore *regexp.Regexp) (map[string]map[string
|
||||||
}
|
}
|
||||||
|
|
||||||
dev := parts[1]
|
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)
|
log.Debugf("Ignoring device: %s", dev)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,14 +19,14 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNetDevStats(t *testing.T) {
|
func TestNetDevStatsIgnore(t *testing.T) {
|
||||||
file, err := os.Open("fixtures/proc/net/dev")
|
file, err := os.Open("fixtures/proc/net/dev")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
netStats, err := parseNetDevStats(file, regexp.MustCompile("^veth"))
|
netStats, err := parseNetDevStats(file, regexp.MustCompile("^veth"), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -59,3 +59,23 @@ func TestNetDevStats(t *testing.T) {
|
||||||
t.Error("want fixture interface 💩0 to exist, but it does not")
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ import (
|
||||||
*/
|
*/
|
||||||
import "C"
|
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{}
|
netDev := map[string]map[string]string{}
|
||||||
|
|
||||||
var ifap, ifa *C.struct_ifaddrs
|
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 {
|
for ifa = ifap; ifa != nil; ifa = ifa.ifa_next {
|
||||||
if ifa.ifa_addr.sa_family == C.AF_LINK {
|
if ifa.ifa_addr.sa_family == C.AF_LINK {
|
||||||
dev := C.GoString(ifa.ifa_name)
|
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)
|
log.Debugf("Ignoring device: %s", dev)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue