From dace6dc48bf1f66c6586a08e73900b4305d3eca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Ferrari?= Date: Wed, 16 Sep 2015 16:34:34 +0300 Subject: [PATCH] Fix issues from code review, and split common code into filesystem_common.go. --- collector/filesystem_common.go | 113 ++++++++++++++++++++++++++++++++ collector/filesystem_freebsd.go | 108 +++++------------------------- collector/filesystem_linux.go | 113 +++++--------------------------- 3 files changed, 145 insertions(+), 189 deletions(-) create mode 100644 collector/filesystem_common.go diff --git a/collector/filesystem_common.go b/collector/filesystem_common.go new file mode 100644 index 00000000..1adf1ba7 --- /dev/null +++ b/collector/filesystem_common.go @@ -0,0 +1,113 @@ +// +build !nofilesystem + +package collector + +import ( + "flag" + "regexp" + + "github.com/prometheus/client_golang/prometheus" +) + +// Arch-dependent implementation must define: +// * defIgnoredMountPoints +// * filesystemLabelNames +// * filesystemCollector.GetStats + +var ( + ignoredMountPoints = flag.String( + "collector.filesystem.ignored-mount-points", + defIgnoredMountPoints, + "Regexp of mount points to ignore for filesystem collector.") +) + +type filesystemCollector struct { + ignoredMountPointsPattern *regexp.Regexp + sizeDesc, freeDesc, availDesc, + filesDesc, filesFreeDesc *prometheus.Desc +} + +type filesystemStats struct { + labelValues []string + size, free, avail, files, filesFree float64 +} + +func init() { + Factories["filesystem"] = NewFilesystemCollector +} + +// Takes a prometheus registry and returns a new Collector exposing +// Filesystems stats. +func NewFilesystemCollector() (Collector, error) { + subsystem := "filesystem" + pattern := regexp.MustCompile(*ignoredMountPoints) + + sizeDesc := prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "size"), + "Filesystem size in bytes.", + filesystemLabelNames, nil, + ) + + freeDesc := prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "free"), + "Filesystem free space in bytes.", + filesystemLabelNames, nil, + ) + + availDesc := prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "avail"), + "Filesystem space available to non-root users in bytes.", + filesystemLabelNames, nil, + ) + + filesDesc := prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "files"), + "Filesystem total file nodes.", + filesystemLabelNames, nil, + ) + + filesFreeDesc := prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "files_free"), + "Filesystem total free file nodes.", + filesystemLabelNames, nil, + ) + + return &filesystemCollector{ + ignoredMountPointsPattern: pattern, + sizeDesc: sizeDesc, + freeDesc: freeDesc, + availDesc: availDesc, + filesDesc: filesDesc, + filesFreeDesc: filesFreeDesc, + }, nil +} + +func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) (err error) { + stats, err := c.GetStats() + if err != nil { + return err + } + for _, s := range stats { + ch <- prometheus.MustNewConstMetric( + c.sizeDesc, prometheus.GaugeValue, + s.size, s.labelValues..., + ) + ch <- prometheus.MustNewConstMetric( + c.freeDesc, prometheus.GaugeValue, + s.free, s.labelValues..., + ) + ch <- prometheus.MustNewConstMetric( + c.availDesc, prometheus.GaugeValue, + s.avail, s.labelValues..., + ) + ch <- prometheus.MustNewConstMetric( + c.filesDesc, prometheus.GaugeValue, + s.files, s.labelValues..., + ) + ch <- prometheus.MustNewConstMetric( + c.filesFreeDesc, prometheus.GaugeValue, + s.filesFree, s.labelValues..., + ) + } + return nil +} diff --git a/collector/filesystem_freebsd.go b/collector/filesystem_freebsd.go index 4ca93871..7ffa5e89 100644 --- a/collector/filesystem_freebsd.go +++ b/collector/filesystem_freebsd.go @@ -4,11 +4,9 @@ package collector import ( "errors" - "flag" "regexp" "unsafe" - "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/log" ) @@ -21,114 +19,38 @@ import ( import "C" const ( - subsystem = "filesystem" + defIgnoredMountPoints = "^/(dev)($|/)" ) var ( - ignoredMountPoints = flag.String( - "collector.filesystem.ignored-mount-points", - "^/(dev)($|/)", - "Regexp of mount points to ignore for filesystem collector.") -) - -type filesystemCollector struct { - ignoredMountPointsPattern *regexp.Regexp -} - -func init() { - Factories["filesystem"] = NewFilesystemCollector -} - -func NewFilesystemCollector() (Collector, error) { - pattern := regexp.MustCompile(*ignoredMountPoints) - return &filesystemCollector{ - ignoredMountPointsPattern: pattern, - }, nil -} - -var ( - filesystemLabelNames = []string{"device", "mountpoint", "fstype"} - - sizeDesc = prometheus.NewDesc( - prometheus.BuildFQName(Namespace, subsystem, "size"), - "Filesystem size in bytes.", - filesystemLabelNames, nil, - ) - - freeDesc = prometheus.NewDesc( - prometheus.BuildFQName(Namespace, subsystem, "free"), - "Filesystem free space in bytes.", - filesystemLabelNames, nil, - ) - - availDesc = prometheus.NewDesc( - prometheus.BuildFQName(Namespace, subsystem, "avail"), - "Filesystem space available to non-root users in bytes.", - filesystemLabelNames, nil, - ) - - filesDesc = prometheus.NewDesc( - prometheus.BuildFQName(Namespace, subsystem, "files"), - "Filesystem total file nodes.", - filesystemLabelNames, nil, - ) - - filesFreeDesc = prometheus.NewDesc( - prometheus.BuildFQName(Namespace, subsystem, "files_free"), - "Filesystem total free file nodes.", - filesystemLabelNames, nil, - ) + filesystemLabelNames = []string{"filesystem"} ) // Expose filesystem fullness. -func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) (err error) { +func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) { var mntbuf *C.struct_statfs count := C.getmntinfo(&mntbuf, C.MNT_NOWAIT) if count == 0 { - return errors.New("getmntinfo() failed") + return nil, errors.New("getmntinfo() failed") } mnt := (*[1 << 30]C.struct_statfs)(unsafe.Pointer(mntbuf)) + stats = []filesystemStats{} for i := 0; i < int(count); i++ { name := C.GoString(&mnt[i].f_mntonname[0]) if c.ignoredMountPointsPattern.MatchString(name) { log.Debugf("Ignoring mount point: %s", name) continue } - ch <- prometheus.MustNewConstMetric( - sizeDesc, - prometheus.GaugeValue, - float64(mnt[i].f_blocks) * float64(mnt[i].f_bsize), - mpd.device, mpd.mountPoint, mpd.fsType, - ) - - ch <- prometheus.MustNewConstMetric( - freeDesc, - prometheus.GaugeValue, - float64(mnt[i].f_bfree) * float64(mnt[i].f_bsize), - mpd.device, mpd.mountPoint, mpd.fsType, - ) - - ch <- prometheus.MustNewConstMetric( - availDesc, - prometheus.GaugeValue, - float64(mnt[i].f_bavail) * float64(mnt[i].f_bsize), - mpd.device, mpd.mountPoint, mpd.fsType, - ) - - ch <- prometheus.MustNewConstMetric( - filesDesc, - prometheus.GaugeValue, - float64(mnt[i].f_files), - mpd.device, mpd.mountPoint, mpd.fsType, - ) - - ch <- prometheus.MustNewConstMetric( - filesFreeDesc, - prometheus.GaugeValue, - float64(mnt[i].f_ffree), - mpd.device, mpd.mountPoint, mpd.fsType, - ) + labelValues := []string{name} + stats = append(stats, filesystemStats{ + labelValues: labelValues, + size: float64(mnt[i].f_blocks) * float64(mnt[i].f_bsize), + free: float64(mnt[i].f_bfree) * float64(mnt[i].f_bsize), + avail: float64(mnt[i].f_bavail) * float64(mnt[i].f_bsize), + files: float64(mnt[i].f_files), + filesFree: float64(mnt[i].f_ffree), + }) } - return nil + return stats, nil } diff --git a/collector/filesystem_linux.go b/collector/filesystem_linux.go index 6c2929f7..6090b2da 100644 --- a/collector/filesystem_linux.go +++ b/collector/filesystem_linux.go @@ -4,27 +4,21 @@ package collector import ( "bufio" - "flag" "fmt" "os" - "regexp" "strings" "syscall" - "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/log" ) const ( - procMounts = "/proc/mounts" - subsystem = "filesystem" + defIgnoredMountPoints = "^/(sys|proc|dev)($|/)" + procMounts = "/proc/mounts" ) var ( - ignoredMountPoints = flag.String( - "collector.filesystem.ignored-mount-points", - "^/(sys|proc|dev)($|/)", - "Regexp of mount points to ignore for filesystem collector.") + filesystemLabelNames = []string{"device", "mountpoint", "fstype"} ) type filesystemDetails struct { @@ -33,61 +27,13 @@ type filesystemDetails struct { fsType string } -type filesystemCollector struct { - ignoredMountPointsPattern *regexp.Regexp -} - -func init() { - Factories["filesystem"] = NewFilesystemCollector -} - -func NewFilesystemCollector() (Collector, error) { - pattern := regexp.MustCompile(*ignoredMountPoints) - return &filesystemCollector{ - ignoredMountPointsPattern: pattern, - }, nil -} - -var ( - filesystemLabelNames = []string{"device", "mountpoint", "fstype"} - - sizeDesc = prometheus.NewDesc( - prometheus.BuildFQName(Namespace, subsystem, "size"), - "Filesystem size in bytes.", - filesystemLabelNames, nil, - ) - - freeDesc = prometheus.NewDesc( - prometheus.BuildFQName(Namespace, subsystem, "free"), - "Filesystem free space in bytes.", - filesystemLabelNames, nil, - ) - - availDesc = prometheus.NewDesc( - prometheus.BuildFQName(Namespace, subsystem, "avail"), - "Filesystem space available to non-root users in bytes.", - filesystemLabelNames, nil, - ) - - filesDesc = prometheus.NewDesc( - prometheus.BuildFQName(Namespace, subsystem, "files"), - "Filesystem total file nodes.", - filesystemLabelNames, nil, - ) - - filesFreeDesc = prometheus.NewDesc( - prometheus.BuildFQName(Namespace, subsystem, "files_free"), - "Filesystem total free file nodes.", - filesystemLabelNames, nil, - ) -) - // Expose filesystem fullness. -func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) (err error) { +func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) { mpds, err := mountPointDetails() if err != nil { - return err + return nil, err } + stats = []filesystemStats{} for _, mpd := range mpds { if c.ignoredMountPointsPattern.MatchString(mpd.mountPoint) { log.Debugf("Ignoring mount point: %s", mpd.mountPoint) @@ -96,46 +42,21 @@ func (c *filesystemCollector) Update(ch chan<- prometheus.Metric) (err error) { buf := new(syscall.Statfs_t) err := syscall.Statfs(mpd.mountPoint, buf) if err != nil { - return fmt.Errorf("Statfs on %s returned %s", + return nil, fmt.Errorf("Statfs on %s returned %s", mpd.mountPoint, err) } - ch <- prometheus.MustNewConstMetric( - sizeDesc, - prometheus.GaugeValue, - float64(buf.Blocks) * float64(buf.Bsize), - mpd.device, mpd.mountPoint, mpd.fsType, - ) - - ch <- prometheus.MustNewConstMetric( - freeDesc, - prometheus.GaugeValue, - float64(buf.Bfree) * float64(buf.Bsize), - mpd.device, mpd.mountPoint, mpd.fsType, - ) - - ch <- prometheus.MustNewConstMetric( - availDesc, - prometheus.GaugeValue, - float64(buf.Bavail) * float64(buf.Bsize), - mpd.device, mpd.mountPoint, mpd.fsType, - ) - - ch <- prometheus.MustNewConstMetric( - filesDesc, - prometheus.GaugeValue, - float64(buf.Files), - mpd.device, mpd.mountPoint, mpd.fsType, - ) - - ch <- prometheus.MustNewConstMetric( - filesFreeDesc, - prometheus.GaugeValue, - float64(buf.Ffree), - mpd.device, mpd.mountPoint, mpd.fsType, - ) + labelValues := []string{mpd.device, mpd.mountPoint, mpd.fsType} + stats = append(stats, filesystemStats{ + labelValues: labelValues, + size: float64(buf.Blocks) * float64(buf.Bsize), + free: float64(buf.Bfree) * float64(buf.Bsize), + avail: float64(buf.Bavail) * float64(buf.Bsize), + files: float64(buf.Files), + filesFree: float64(buf.Ffree), + }) } - return nil + return stats, nil } func mountPointDetails() ([]filesystemDetails, error) {