2015-05-13 12:27:59 +02:00
// +build !nofilesystem
package collector
import (
"errors"
"flag"
"regexp"
"unsafe"
"github.com/prometheus/client_golang/prometheus"
2015-06-24 08:05:09 +02:00
"github.com/prometheus/log"
2015-05-13 12:27:59 +02:00
)
/ *
# include < sys / param . h >
# include < sys / ucred . h >
# include < sys / mount . h >
# include < stdio . h >
* /
import "C"
const (
filesystemSubsystem = "filesystem"
)
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
size , free , avail , files , filesFree * prometheus . GaugeVec
}
func init ( ) {
Factories [ "filesystem" ] = NewFilesystemCollector
}
2015-06-24 08:05:09 +02:00
// Takes a prometheus registry and returns a new Collector exposing
// Filesystems stats.
2015-06-23 15:49:18 +02:00
func NewFilesystemCollector ( ) ( Collector , error ) {
2015-05-13 12:27:59 +02:00
var filesystemLabelNames = [ ] string { "filesystem" }
return & filesystemCollector {
ignoredMountPointsPattern : regexp . MustCompile ( * ignoredMountPoints ) ,
size : prometheus . NewGaugeVec (
prometheus . GaugeOpts {
Namespace : Namespace ,
Subsystem : filesystemSubsystem ,
2015-06-24 08:05:09 +02:00
Name : "size_bytes" ,
2015-05-13 12:27:59 +02:00
Help : "Filesystem size in bytes." ,
} ,
filesystemLabelNames ,
) ,
free : prometheus . NewGaugeVec (
prometheus . GaugeOpts {
Namespace : Namespace ,
Subsystem : filesystemSubsystem ,
2015-06-24 08:05:09 +02:00
Name : "free_bytes" ,
2015-05-13 12:27:59 +02:00
Help : "Filesystem free space in bytes." ,
} ,
filesystemLabelNames ,
) ,
avail : prometheus . NewGaugeVec (
prometheus . GaugeOpts {
Namespace : Namespace ,
Subsystem : filesystemSubsystem ,
2015-06-24 08:05:09 +02:00
Name : "avail_bytes" ,
2015-05-13 12:27:59 +02:00
Help : "Filesystem space available to non-root users in bytes." ,
} ,
filesystemLabelNames ,
) ,
files : prometheus . NewGaugeVec (
prometheus . GaugeOpts {
Namespace : Namespace ,
Subsystem : filesystemSubsystem ,
2015-06-24 08:05:09 +02:00
Name : "file_nodes" ,
2015-05-13 12:27:59 +02:00
Help : "Filesystem total file nodes." ,
} ,
filesystemLabelNames ,
) ,
filesFree : prometheus . NewGaugeVec (
prometheus . GaugeOpts {
Namespace : Namespace ,
Subsystem : filesystemSubsystem ,
2015-06-24 08:05:09 +02:00
Name : "file_free_nodes" ,
2015-05-13 12:27:59 +02:00
Help : "Filesystem total free file nodes." ,
} ,
filesystemLabelNames ,
) ,
} , nil
}
// Expose filesystem fullness.
func ( c * filesystemCollector ) Update ( ch chan <- prometheus . Metric ) ( err error ) {
var mntbuf * C . struct_statfs
count := C . getmntinfo ( & mntbuf , C . MNT_NOWAIT )
if count == 0 {
return errors . New ( "getmntinfo() failed!" )
}
mnt := ( * [ 1 << 30 ] C . struct_statfs ) ( unsafe . Pointer ( mntbuf ) )
for i := 0 ; i < int ( count ) ; i ++ {
name := C . GoString ( & mnt [ i ] . f_mntonname [ 0 ] )
if c . ignoredMountPointsPattern . MatchString ( name ) {
2015-06-24 08:05:09 +02:00
log . Debugf ( "Ignoring mount point: %s" , name )
2015-05-13 12:27:59 +02:00
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 ) )
}
c . size . Collect ( ch )
c . free . Collect ( ch )
c . avail . Collect ( ch )
c . files . Collect ( ch )
c . filesFree . Collect ( ch )
return err
}