Merge pull request #482 from prometheus/grobie/fix-invalid-scanner-usage

Fix scanner usage without error handling
pull/483/head
Tobias Schmidt 2017-02-28 17:17:52 -04:00 committed by GitHub
commit a7da926abb
37 changed files with 87 additions and 94 deletions

View File

@ -51,7 +51,7 @@ func NewBondingCollector() (Collector, error) {
}
// Update reads and exposes bonding states, implements Collector interface. Caution: This works only on linux.
func (c *bondingCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *bondingCollector) Update(ch chan<- prometheus.Metric) error {
bondingStats, err := readBondingStats(sysFilePath("class/net"))
if err != nil {
return err

View File

@ -49,7 +49,7 @@ func NewBuddyinfoCollector() (Collector, error) {
// Update calls (*buddyinfoCollector).getBuddyInfo to get the platform specific
// buddyinfo metrics.
func (c *buddyinfoCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *buddyinfoCollector) Update(ch chan<- prometheus.Metric) error {
fs, err := procfs.NewFS(*procPath)
if err != nil {
return fmt.Errorf("failed to open procfs: %v", err)

View File

@ -32,7 +32,7 @@ func warnDeprecated(collector string) {
// Collector is the interface a collector has to implement.
type Collector interface {
// Get new metrics and expose them via prometheus registry.
Update(ch chan<- prometheus.Metric) (err error)
Update(ch chan<- prometheus.Metric) error
}
type typedDesc struct {

View File

@ -44,7 +44,7 @@ func NewConntrackCollector() (Collector, error) {
}, nil
}
func (c *conntrackCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *conntrackCollector) Update(ch chan<- prometheus.Metric) error {
value, err := readUintFromFile(procFilePath("sys/net/netfilter/nf_conntrack_count"))
if err != nil {
// Conntrack probably not loaded into the kernel.

View File

@ -107,7 +107,7 @@ func NewStatCollector() (Collector, error) {
}
// Expose CPU stats using sysctl.
func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *statCollector) Update(ch chan<- prometheus.Metric) error {
// We want time spent per-cpu per CPUSTATE.
// CPUSTATES (number of CPUSTATES) is defined as 5U.
// Order: CP_USER | CP_NICE | CP_SYS | CP_IDLE | CP_INTR

View File

@ -239,5 +239,5 @@ func parseDiskStats(r io.Reader) (map[string]map[int]string, error) {
diskStats[dev][12] = bytesWritten
}
return diskStats, nil
return diskStats, scanner.Err()
}

View File

@ -155,7 +155,7 @@ func newDRBDCollector() (Collector, error) {
return &drbdCollector{}, nil
}
func (c *drbdCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *drbdCollector) Update(ch chan<- prometheus.Metric) error {
statsFile := procFilePath("drbd")
file, err := os.Open(statsFile)
if err != nil {

View File

@ -78,7 +78,7 @@ func NewEdacCollector() (Collector, error) {
}, nil
}
func (c *edacCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *edacCollector) Update(ch chan<- prometheus.Metric) error {
memControllers, err := filepath.Glob(sysFilePath("devices/system/edac/mc/mc[0-9]*"))
if err != nil {
return err

View File

@ -40,7 +40,7 @@ func NewEntropyCollector() (Collector, error) {
}, nil
}
func (c *entropyCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *entropyCollector) Update(ch chan<- prometheus.Metric) error {
value, err := readUintFromFile(procFilePath("sys/kernel/random/entropy_avail"))
if err != nil {
return fmt.Errorf("couldn't get entropy_avail: %s", err)

View File

@ -16,12 +16,11 @@
package collector
import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"strconv"
"strings"
"github.com/prometheus/client_golang/prometheus"
)
@ -41,8 +40,8 @@ func NewFileFDStatCollector() (Collector, error) {
return &fileFDStatCollector{}, nil
}
func (c *fileFDStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
fileFDStat, err := getFileFDStats(procFilePath("sys/fs/file-nr"))
func (c *fileFDStatCollector) Update(ch chan<- prometheus.Metric) error {
fileFDStat, err := parseFileFDStats(procFilePath("sys/fs/file-nr"))
if err != nil {
return fmt.Errorf("couldn't get file-nr: %s", err)
}
@ -63,25 +62,27 @@ func (c *fileFDStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
return nil
}
func getFileFDStats(fileName string) (map[string]string, error) {
file, err := os.Open(fileName)
func parseFileFDStats(filename string) (map[string]string, error) {
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
return parseFileFDStats(file, fileName)
}
func parseFileFDStats(r io.Reader, fileName string) (map[string]string, error) {
var scanner = bufio.NewScanner(r)
scanner.Scan()
// The file-nr proc file is separated by tabs, not spaces.
line := strings.Split(scanner.Text(), "\u0009")
content, err := ioutil.ReadAll(file)
if err != nil {
return nil, err
}
parts := bytes.Split(bytes.TrimSpace(content), []byte("\u0009"))
if len(parts) < 3 {
return nil, fmt.Errorf("unexpected number of file stats in %q", filename)
}
var fileFDStat = map[string]string{}
// The file-nr proc is only 1 line with 3 values.
fileFDStat["allocated"] = line[0]
fileFDStat["allocated"] = string(parts[0])
// The second value is skipped as it will always be zero in linux 2.6.
fileFDStat["maximum"] = line[2]
fileFDStat["maximum"] = string(parts[2])
return fileFDStat, nil
}

View File

@ -13,28 +13,19 @@
package collector
import (
"os"
"testing"
)
import "testing"
func TestFileFDStats(t *testing.T) {
file, err := os.Open("fixtures/proc/sys/fs/file-nr")
if err != nil {
t.Fatal(err)
}
defer file.Close()
fileFDStats, err := parseFileFDStats(file, fileName)
fileFDStats, err := parseFileFDStats("fixtures/proc/sys/fs/file-nr")
if err != nil {
t.Fatal(err)
}
if want, got := "1024", fileFDStats["allocated"]; want != got {
t.Errorf("want filefd allocated %s, got %s", want, got)
t.Errorf("want filefd allocated %q, got %q", want, got)
}
if want, got := "1631329", fileFDStats["maximum"]; want != got {
t.Errorf("want filefd maximum %s, got %s", want, got)
t.Errorf("want filefd maximum %q, got %q", want, got)
}
}

View File

@ -124,7 +124,7 @@ func NewFilesystemCollector() (Collector, error) {
}, nil
}
func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) error {
stats, err := c.GetStats()
if err != nil {
return err

View File

@ -40,7 +40,7 @@ func gostring(b []int8) string {
}
// Expose filesystem fullness.
func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) {
func (c *filesystemCollector) GetStats() ([]filesystemStats, error) {
buf := make([]unix.Statfs_t, 16)
for {
n, err := unix.Getfsstat(buf, noWait)
@ -53,7 +53,7 @@ func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) {
}
buf = make([]unix.Statfs_t, len(buf)*2)
}
stats = []filesystemStats{}
stats := []filesystemStats{}
for _, fs := range buf {
mountpoint := gostring(fs.Mntonname[:])
if c.ignoredMountPointsPattern.MatchString(mountpoint) {

View File

@ -31,12 +31,12 @@ const (
)
// GetStats returns filesystem stats.
func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) {
func (c *filesystemCollector) GetStats() ([]filesystemStats, error) {
mps, err := mountPointDetails()
if err != nil {
return nil, err
}
stats = []filesystemStats{}
stats := []filesystemStats{}
for _, labels := range mps {
if c.ignoredMountPointsPattern.MatchString(labels.mountPoint) {
log.Debugf("Ignoring mount point: %s", labels.mountPoint)

View File

@ -56,7 +56,7 @@ func NewGmondCollector() (Collector, error) {
return &c, nil
}
func (c *gmondCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *gmondCollector) Update(ch chan<- prometheus.Metric) error {
conn, err := net.Dial(gangliaProto, gangliaAddress)
log.Debugf("gmondCollector Update")
if err != nil {

View File

@ -20,7 +20,8 @@ import (
"strings"
)
func splitToInts(str string, sep string) (ints []int, err error) {
func splitToInts(str, sep string) ([]int, error) {
var ints []int
for _, part := range strings.Split(str, sep) {
i, err := strconv.Atoi(part)
if err != nil {

View File

@ -392,7 +392,7 @@ func (c *hwMonCollector) hwmonHumanReadableChipName(dir string) (string, error)
return "", errors.New("Could not derive a human-readable chip type for " + dir)
}
func (c *hwMonCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *hwMonCollector) Update(ch chan<- prometheus.Metric) error {
// Step 1: scan /sys/class/hwmon, resolve all symlinks and call
// updatesHwmon for each folder

View File

@ -128,7 +128,7 @@ func readMetric(directory, metricFile string) (uint64, error) {
return metric, nil
}
func (c *infinibandCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *infinibandCollector) Update(ch chan<- prometheus.Metric) error {
devices, err := infinibandDevices(sysFilePath(infinibandPath))
// If no devices are found or another error is raised while attempting to find devices,

View File

@ -94,5 +94,5 @@ func parseInterrupts(r io.Reader) (map[string]interrupt, error) {
interrupts[intName] = intr
}
return interrupts, nil
return interrupts, scanner.Err()
}

View File

@ -60,7 +60,7 @@ func NewKsmdCollector() (Collector, error) {
}
// Update implements Collector and exposes kernel and system statistics.
func (c *ksmdCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *ksmdCollector) Update(ch chan<- prometheus.Metric) error {
for _, n := range ksmdFiles {
val, err := readUintFromFile(sysFilePath(path.Join("kernel/mm/ksm", n)))
if err != nil {

View File

@ -42,7 +42,7 @@ func NewLoadavgCollector() (Collector, error) {
}, nil
}
func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) error {
loads, err := getLoad()
if err != nil {
return fmt.Errorf("couldn't get load: %s", err)

View File

@ -274,17 +274,15 @@ var (
)
)
func (c *mdadmCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *mdadmCollector) Update(ch chan<- prometheus.Metric) error {
statusfile := procFilePath("mdstat")
// take care we don't crash on non-existent statusfiles
_, err = os.Stat(statusfile)
if os.IsNotExist(err) {
// no such file or directory, nothing to do, just return
log.Debugf("Not collecting mdstat, file does not exist: %s", statusfile)
return nil
}
if err != nil { // now things get weird, better to return
if _, err := os.Stat(statusfile); err != nil {
// Take care we don't crash on non-existent statusfiles.
if os.IsNotExist(err) {
// no such file or directory, nothing to do, just return
log.Debugf("Not collecting mdstat, file does not exist: %s", statusfile)
return nil
}
return err
}

View File

@ -71,16 +71,17 @@ func NewMegaCliCollector() (Collector, error) {
}, nil
}
func (c *megaCliCollector) Update(ch chan<- prometheus.Metric) (err error) {
err = c.updateAdapter()
if err != nil {
func (c *megaCliCollector) Update(ch chan<- prometheus.Metric) error {
if err := c.updateAdapter(); err != nil {
return err
}
if err := c.updateDisks(); err != nil {
return err
}
err = c.updateDisks()
c.driveTemperature.Collect(ch)
c.driveCounters.Collect(ch)
c.drivePresence.Collect(ch)
return err
return nil
}
func parseMegaCliDisks(r io.Reader) (map[int]map[int]map[string]string, error) {
@ -122,7 +123,7 @@ func parseMegaCliDisks(r io.Reader) (map[int]map[int]map[string]string, error) {
}
}
return stats, nil
return stats, scanner.Err()
}
func parseMegaCliAdapter(r io.Reader) (map[string]map[string]string, error) {
@ -155,7 +156,7 @@ func parseMegaCliAdapter(r io.Reader) (map[string]map[string]string, error) {
}
return raidStats, nil
return raidStats, scanner.Err()
}
func (c *megaCliCollector) updateAdapter() error {

View File

@ -40,7 +40,7 @@ func NewMeminfoCollector() (Collector, error) {
// Update calls (*meminfoCollector).getMemInfo to get the platform specific
// memory metrics.
func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) error {
memInfo, err := c.getMemInfo()
if err != nil {
return fmt.Errorf("couldn't get meminfo: %s", err)

View File

@ -62,5 +62,5 @@ func parseMemInfo(r io.Reader) (map[string]float64, error) {
memInfo[key] = fv
}
return memInfo, nil
return memInfo, scanner.Err()
}

View File

@ -57,7 +57,7 @@ func NewMeminfoNumaCollector() (Collector, error) {
}, nil
}
func (c *meminfoNumaCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *meminfoNumaCollector) Update(ch chan<- prometheus.Metric) error {
metrics, err := getMemInfoNuma()
if err != nil {
return fmt.Errorf("couldn't get NUMA meminfo: %s", err)

View File

@ -51,7 +51,7 @@ func NewNetDevCollector() (Collector, error) {
}, nil
}
func (c *netDevCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *netDevCollector) Update(ch chan<- prometheus.Metric) error {
netDev, err := getNetDevStats(c.ignoredDevicesPattern)
if err != nil {
return fmt.Errorf("couldn't get netstats: %s", err)

View File

@ -42,7 +42,7 @@ func NewNetStatCollector() (Collector, error) {
return &netStatCollector{}, nil
}
func (c *netStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *netStatCollector) Update(ch chan<- prometheus.Metric) error {
netStats, err := getNetStats(procFilePath("net/netstat"))
if err != nil {
return fmt.Errorf("couldn't get netstats: %s", err)
@ -108,5 +108,5 @@ func parseNetStats(r io.Reader, fileName string) (map[string]map[string]string,
}
}
return netStats, nil
return netStats, scanner.Err()
}

View File

@ -116,12 +116,12 @@ func NewNfsCollector() (Collector, error) {
return &nfsCollector{}, nil
}
func (c *nfsCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *nfsCollector) Update(ch chan<- prometheus.Metric) error {
statsFile := procFilePath("net/rpc/nfs")
content, err := ioutil.ReadFile(statsFile)
if err != nil {
if os.IsNotExist(err) {
log.Debugf("Not collecting NFS statistics, as %s does not exist: %s", statsFile)
log.Debugf("Not collecting NFS statistics, as %q does not exist", statsFile)
return nil
}
return err

View File

@ -62,7 +62,7 @@ func NewNtpCollector() (Collector, error) {
}, nil
}
func (c *ntpCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *ntpCollector) Update(ch chan<- prometheus.Metric) error {
resp, err := ntp.Query(*ntpServer, *ntpProtocolVersion)
if err != nil {
return fmt.Errorf("couldn't get NTP drift: %s", err)

View File

@ -44,7 +44,7 @@ func NewSockStatCollector() (Collector, error) {
return &sockStatCollector{}, nil
}
func (c *sockStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *sockStatCollector) Update(ch chan<- prometheus.Metric) error {
sockStats, err := getSockStats(procFilePath("net/sockstat"))
if err != nil {
return fmt.Errorf("couldn't get sockstats: %s", err)
@ -95,6 +95,9 @@ func parseSockStats(r io.Reader, fileName string) (map[string]map[string]string,
i++
}
}
if err := scanner.Err(); err != nil {
return nil, err
}
// The mem metrics is the count of pages used. Multiply the mem metrics by
// the page size from the kernel to get the number of bytes used.

View File

@ -84,7 +84,7 @@ func NewStatCollector() (Collector, error) {
}
// Expose kernel and system statistics.
func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *statCollector) Update(ch chan<- prometheus.Metric) error {
file, err := os.Open(procFilePath("stat"))
if err != nil {
return err
@ -158,5 +158,5 @@ func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) {
ch <- prometheus.MustNewConstMetric(c.procsBlocked, prometheus.GaugeValue, value)
}
}
return err
return scanner.Err()
}

View File

@ -75,7 +75,7 @@ func NewSystemdCollector() (Collector, error) {
}, nil
}
func (c *systemdCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
units, err := c.listUnits()
if err != nil {
return fmt.Errorf("couldn't get units states: %s", err)

View File

@ -73,7 +73,7 @@ func NewTCPStatCollector() (Collector, error) {
}, nil
}
func (c *tcpStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *tcpStatCollector) Update(ch chan<- prometheus.Metric) error {
tcpStats, err := getTCPStats(procFilePath("net/tcp"))
if err != nil {
return fmt.Errorf("couldn't get tcpstats: %s", err)
@ -130,7 +130,7 @@ func parseTCPStats(r io.Reader) (map[tcpConnectionState]float64, error) {
tcpStats[tcpConnectionState(st)]++
}
return tcpStats, nil
return tcpStats, scanner.Err()
}
func (st tcpConnectionState) String() string {

View File

@ -66,7 +66,7 @@ func NewTextFileCollector() (Collector, error) {
}
// Update implements the Collector interface.
func (c *textFileCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *textFileCollector) Update(ch chan<- prometheus.Metric) error {
return nil
}

View File

@ -40,7 +40,7 @@ func NewvmStatCollector() (Collector, error) {
return &vmStatCollector{}, nil
}
func (c *vmStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
func (c *vmStatCollector) Update(ch chan<- prometheus.Metric) error {
file, err := os.Open(procFilePath("vmstat"))
if err != nil {
return err
@ -64,5 +64,5 @@ func (c *vmStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
value,
)
}
return err
return scanner.Err()
}

View File

@ -26,16 +26,16 @@ import (
"github.com/prometheus/common/log"
)
func (c *zfsCollector) openProcFile(path string) (file *os.File, err error) {
file, err = os.Open(procFilePath(path))
func (c *zfsCollector) openProcFile(path string) (*os.File, error) {
file, err := os.Open(procFilePath(path))
if err != nil {
log.Debugf("Cannot open %q for reading. Is the kernel module loaded?", procFilePath(path))
err = errZFSNotAvailable
return nil, errZFSNotAvailable
}
return
return file, nil
}
func (c *zfsCollector) updateZfsStats(subsystem string, ch chan<- prometheus.Metric) (err error) {
func (c *zfsCollector) updateZfsStats(subsystem string, ch chan<- prometheus.Metric) error {
file, err := c.openProcFile(filepath.Join(c.linuxProcpathBase, c.linuxPathMap[subsystem]))
if err != nil {
return err
@ -76,12 +76,11 @@ func (c *zfsCollector) updatePoolStats(ch chan<- prometheus.Metric) (err error)
return nil
}
func (c *zfsCollector) parseProcfsFile(reader io.Reader, fmtExt string, handler func(zfsSysctl, int)) (err error) {
func (c *zfsCollector) parseProcfsFile(reader io.Reader, fmtExt string, handler func(zfsSysctl, int)) error {
scanner := bufio.NewScanner(reader)
parseLine := false
for scanner.Scan() {
parts := strings.Fields(scanner.Text())
if !parseLine && len(parts) == 3 && parts[0] == "name" && parts[1] == "type" && parts[2] == "data" {
@ -110,13 +109,12 @@ func (c *zfsCollector) parseProcfsFile(reader io.Reader, fmtExt string, handler
return scanner.Err()
}
func (c *zfsCollector) parsePoolProcfsFile(reader io.Reader, zpoolPath string, handler func(string, zfsSysctl, int)) (err error) {
func (c *zfsCollector) parsePoolProcfsFile(reader io.Reader, zpoolPath string, handler func(string, zfsSysctl, int)) error {
scanner := bufio.NewScanner(reader)
parseLine := false
var fields []string
for scanner.Scan() {
line := strings.Fields(scanner.Text())
if !parseLine && len(line) >= 12 && line[0] == "nread" {