Skip to content

Commit

Permalink
Merge pull request prometheus#117 from TheTincho/forget-old-filesystems
Browse files Browse the repository at this point in the history
Revamp the filesystem collector to use throw-away ConstMetrics.
  • Loading branch information
beorn7 committed Sep 16, 2015
2 parents d8bf6da + e3f217e commit ca74e8a
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 168 deletions.
114 changes: 114 additions & 0 deletions collector/filesystem_common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// +build !nofilesystem
// +build linux freebsd

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
}
98 changes: 15 additions & 83 deletions collector/filesystem_freebsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ package collector

import (
"errors"
"flag"
"regexp"
"unsafe"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/log"
)

Expand All @@ -21,104 +19,38 @@ import (
import "C"

const (
filesystemSubsystem = "filesystem"
defIgnoredMountPoints = "^/(dev)($|/)"
)

var (
ignoredMountPoints = flag.String("collector.filesystem.ignored-mount-points", "^/(dev)($|/)", "Regexp of mount points to ignore for filesystem collector.")
filesystemLabelNames = []string{"filesystem"}
)

type filesystemCollector struct {
ignoredMountPointsPattern *regexp.Regexp

size, free, avail, files, filesFree *prometheus.GaugeVec
}

func init() {
Factories["filesystem"] = NewFilesystemCollector
}

// Takes a prometheus registry and returns a new Collector exposing
// Filesystems stats.
func NewFilesystemCollector() (Collector, error) {
var filesystemLabelNames = []string{"filesystem"}

return &filesystemCollector{
ignoredMountPointsPattern: regexp.MustCompile(*ignoredMountPoints),
size: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: filesystemSubsystem,
Name: "size_bytes",
Help: "Filesystem size in bytes.",
},
filesystemLabelNames,
),
free: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: filesystemSubsystem,
Name: "free_bytes",
Help: "Filesystem free space in bytes.",
},
filesystemLabelNames,
),
avail: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: filesystemSubsystem,
Name: "avail_bytes",
Help: "Filesystem space available to non-root users in bytes.",
},
filesystemLabelNames,
),
files: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: filesystemSubsystem,
Name: "file_nodes",
Help: "Filesystem total file nodes.",
},
filesystemLabelNames,
),
filesFree: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: filesystemSubsystem,
Name: "file_free_nodes",
Help: "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) {
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
}
c.size.WithLabelValues(name).Set(float64(mnt[i].f_blocks) * float64(mnt[i].f_bsize))
c.free.WithLabelValues(name).Set(float64(mnt[i].f_bfree) * float64(mnt[i].f_bsize))
c.avail.WithLabelValues(name).Set(float64(mnt[i].f_bavail) * float64(mnt[i].f_bsize))
c.files.WithLabelValues(name).Set(float64(mnt[i].f_files))
c.filesFree.WithLabelValues(name).Set(float64(mnt[i].f_ffree))
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),
})
}

c.size.Collect(ch)
c.free.Collect(ch)
c.avail.Collect(ch)
c.files.Collect(ch)
c.filesFree.Collect(ch)
return err
return stats, nil
}
103 changes: 18 additions & 85 deletions collector/filesystem_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +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"
filesystemSubsystem = "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 {
Expand All @@ -30,77 +27,13 @@ type filesystemDetails struct {
fsType string
}

type filesystemCollector struct {
ignoredMountPointsPattern *regexp.Regexp

size, free, avail, files, filesFree *prometheus.GaugeVec
}

func init() {
Factories["filesystem"] = NewFilesystemCollector
}

// Takes a prometheus registry and returns a new Collector exposing
// network device filesystems.
func NewFilesystemCollector() (Collector, error) {
var filesystemLabelNames = []string{"device", "mountpoint", "fstype"}

return &filesystemCollector{
ignoredMountPointsPattern: regexp.MustCompile(*ignoredMountPoints),
size: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: filesystemSubsystem,
Name: "size",
Help: "Filesystem size in bytes.",
},
filesystemLabelNames,
),
free: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: filesystemSubsystem,
Name: "free",
Help: "Filesystem free space in bytes.",
},
filesystemLabelNames,
),
avail: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: filesystemSubsystem,
Name: "avail",
Help: "Filesystem space available to non-root users in bytes.",
},
filesystemLabelNames,
),
files: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: filesystemSubsystem,
Name: "files",
Help: "Filesystem total file nodes.",
},
filesystemLabelNames,
),
filesFree: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: filesystemSubsystem,
Name: "files_free",
Help: "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)
Expand All @@ -109,21 +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", mpd.mountPoint, err)
return nil, fmt.Errorf("Statfs on %s returned %s",
mpd.mountPoint, err)
}

c.size.WithLabelValues(mpd.device, mpd.mountPoint, mpd.fsType).Set(float64(buf.Blocks) * float64(buf.Bsize))
c.free.WithLabelValues(mpd.device, mpd.mountPoint, mpd.fsType).Set(float64(buf.Bfree) * float64(buf.Bsize))
c.avail.WithLabelValues(mpd.device, mpd.mountPoint, mpd.fsType).Set(float64(buf.Bavail) * float64(buf.Bsize))
c.files.WithLabelValues(mpd.device, mpd.mountPoint, mpd.fsType).Set(float64(buf.Files))
c.filesFree.WithLabelValues(mpd.device, mpd.mountPoint, mpd.fsType).Set(float64(buf.Ffree))
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),
})
}
c.size.Collect(ch)
c.free.Collect(ch)
c.avail.Collect(ch)
c.files.Collect(ch)
c.filesFree.Collect(ch)
return err
return stats, nil
}

func mountPointDetails() ([]filesystemDetails, error) {
Expand Down

0 comments on commit ca74e8a

Please sign in to comment.