From 892893ff05c5abc964c4d910c1c66e117ed8afb6 Mon Sep 17 00:00:00 2001 From: "W. Andrew Denton" Date: Fri, 14 May 2021 10:07:30 -0700 Subject: [PATCH] ethtool: Log stats collection errors. Signed-off-by: W. Andrew Denton --- collector/ethtool_linux.go | 19 ++++++++++++++++++- collector/ethtool_linux_test.go | 10 +++++++--- collector/fixtures/ethtool/bond0 | 1 + 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 collector/fixtures/ethtool/bond0 diff --git a/collector/ethtool_linux.go b/collector/ethtool_linux.go index 3e01c29c..f5613491 100644 --- a/collector/ethtool_linux.go +++ b/collector/ethtool_linux.go @@ -25,12 +25,14 @@ import ( "os" "regexp" "sort" + "syscall" "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/procfs/sysfs" "github.com/safchain/ethtool" + "golang.org/x/sys/unix" ) var ( @@ -138,8 +140,23 @@ func (c *ethtoolCollector) Update(ch chan<- prometheus.Metric) error { var err error stats, err = c.stats.Stats(device) + + // If Stats() returns EOPNOTSUPP it doesn't support ethtool stats. Log that only at Debug level. + // Otherwise log it at Error level. if err != nil { - // Suppressing errors because it's hard to tell what interfaces support ethtool and which don't. + if errno, ok := err.(syscall.Errno); ok { + if err == unix.EOPNOTSUPP { + level.Debug(c.logger).Log("msg", "ethtool stats error", "err", err, "device", device, "errno", uint(errno)) + } else if errno != 0 { + level.Error(c.logger).Log("msg", "ethtool stats error", "err", err, "device", device, "errno", uint(errno)) + } + } else { + level.Error(c.logger).Log("msg", "ethtool stats error", "err", err, "device", device) + } + } + + if stats == nil || len(stats) < 1 { + // No stats returned; device does not support ethtool stats. continue } diff --git a/collector/ethtool_linux_test.go b/collector/ethtool_linux_test.go index 8aaeed3a..d8a5593b 100644 --- a/collector/ethtool_linux_test.go +++ b/collector/ethtool_linux_test.go @@ -25,6 +25,7 @@ import ( "github.com/go-kit/kit/log" "github.com/prometheus/client_golang/prometheus" + "golang.org/x/sys/unix" ) type EthtoolFixture struct { @@ -36,9 +37,9 @@ func (e *EthtoolFixture) Stats(intf string) (map[string]uint64, error) { fixtureFile, err := os.Open(filepath.Join(e.fixturePath, intf)) if e, ok := err.(*os.PathError); ok && e.Err == syscall.ENOENT { - // The fixture for this interface doesn't exist. That's OK because it replicates - // an interface that doesn't support ethtool. - return res, nil + // The fixture for this interface doesn't exist. Translate that to unix.EOPNOTSUPP + // to replicate an interface that doesn't support ethtool stats + return res, unix.EOPNOTSUPP } if err != nil { return res, err @@ -60,6 +61,9 @@ func (e *EthtoolFixture) Stats(intf string) (map[string]uint64, error) { if err != nil { return res, err } + if items[0] == "ERROR" { + return res, unix.Errno(val) + } res[items[0]] = val } diff --git a/collector/fixtures/ethtool/bond0 b/collector/fixtures/ethtool/bond0 new file mode 100644 index 00000000..42e4a141 --- /dev/null +++ b/collector/fixtures/ethtool/bond0 @@ -0,0 +1 @@ +ERROR: 1 \ No newline at end of file