Merge pull request #121 from matthiasr/procfs-flag

Add flag to change the location of the procfs.
This commit is contained in:
Matthias Rampke 2015-09-26 17:22:49 +02:00
commit 7940efe157
15 changed files with 57 additions and 67 deletions

View file

@ -17,7 +17,6 @@ import (
)
const (
procDiskStats = "/proc/diskstats"
diskSubsystem = "disk"
)
@ -147,6 +146,7 @@ func NewDiskstatsCollector() (Collector, error) {
}
func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) (err error) {
procDiskStats := procFilePath("diskstats")
diskStats, err := getDiskStats()
if err != nil {
return fmt.Errorf("couldn't get diskstats: %s", err)
@ -184,7 +184,7 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) (err error) {
}
func getDiskStats() (map[string]map[int]string, error) {
file, err := os.Open(procDiskStats)
file, err := os.Open(procFilePath("diskstats"))
if err != nil {
return nil, err
}
@ -202,7 +202,7 @@ func parseDiskStats(r io.Reader) (map[string]map[int]string, error) {
for scanner.Scan() {
parts := strings.Fields(string(scanner.Text()))
if len(parts) < 4 { // we strip major, minor and dev
return nil, fmt.Errorf("invalid line in %s: %s", procDiskStats, scanner.Text())
return nil, fmt.Errorf("invalid line in %s: %s", procFilePath("diskstats"), scanner.Text())
}
dev := parts[2]
diskStats[dev] = map[int]string{}

View file

@ -13,7 +13,6 @@ import (
)
const (
procFileFDStat = "/proc/sys/fs/file-nr"
fileFDStatSubsystem = "filefd"
)
@ -33,7 +32,7 @@ func NewFileFDStatCollector() (Collector, error) {
}
func (c *fileFDStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
fileFDStat, err := getFileFDStats(procFileFDStat)
fileFDStat, err := getFileFDStats(procFilePath("sys/fs/file-nr"))
if err != nil {
return fmt.Errorf("couldn't get file-nr: %s", err)
}
@ -44,7 +43,7 @@ func (c *fileFDStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
Namespace: Namespace,
Subsystem: fileFDStatSubsystem,
Name: name,
Help: fmt.Sprintf("filefd %s from %s.", name, procFileFDStat),
Help: fmt.Sprintf("File descriptor statistics: %s.", name),
},
)
v, err := strconv.ParseFloat(value, 64)

View file

@ -14,7 +14,6 @@ import (
const (
defIgnoredMountPoints = "^/(sys|proc|dev)($|/)"
procMounts = "/proc/mounts"
)
var (
@ -60,7 +59,7 @@ func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) {
}
func mountPointDetails() ([]filesystemDetails, error) {
file, err := os.Open(procMounts)
file, err := os.Open(procFilePath("mounts"))
if err != nil {
return nil, err
}

View file

@ -4,6 +4,7 @@ package collector
import (
"bufio"
"errors"
"fmt"
"io"
"os"
@ -13,10 +14,6 @@ import (
"github.com/prometheus/client_golang/prometheus"
)
const (
procInterrupts = "/proc/interrupts"
)
type interruptsCollector struct {
metric *prometheus.CounterVec
}
@ -33,7 +30,7 @@ func NewInterruptsCollector() (Collector, error) {
prometheus.CounterOpts{
Namespace: Namespace,
Name: "interrupts",
Help: "Interrupt details from /proc/interrupts.",
Help: "Interrupt details.",
},
[]string{"CPU", "type", "info", "devices"},
),
@ -71,7 +68,7 @@ type interrupt struct {
}
func getInterrupts() (map[string]interrupt, error) {
file, err := os.Open(procInterrupts)
file, err := os.Open(procFilePath("interrupts"))
if err != nil {
return nil, err
}
@ -87,7 +84,7 @@ func parseInterrupts(r io.Reader) (map[string]interrupt, error) {
)
if !scanner.Scan() {
return nil, fmt.Errorf("%s empty", procInterrupts)
return nil, errors.New("interrupts empty")
}
cpuNum := len(strings.Fields(string(scanner.Text()))) // one header per cpu

View file

@ -3,7 +3,6 @@
package collector
import (
"flag"
"fmt"
"strconv"
@ -11,10 +10,6 @@ import (
"github.com/prometheus/procfs"
)
var (
ipvsProcfsMountPoint = flag.String("collector.ipvs.procfs", procfs.DefaultMountPoint, "procfs mountpoint.")
)
type ipvsCollector struct {
Collector
fs procfs.FS
@ -46,7 +41,7 @@ func newIPVSCollector() (*ipvsCollector, error) {
subsystem = "ipvs"
)
c.fs, err = procfs.NewFS(*ipvsProcfsMountPoint)
c.fs, err = procfs.NewFS(*procPath)
if err != nil {
return nil, err
}

View file

@ -107,7 +107,7 @@ var (
)
func TestIPVSCollector(t *testing.T) {
if err := flag.Set("collector.ipvs.procfs", "fixtures"); err != nil {
if err := flag.Set("collector.procfs", "fixtures"); err != nil {
t.Fatal(err)
}
collector, err := newIPVSCollector()
@ -169,7 +169,7 @@ func (c miniCollector) Describe(ch chan<- *prometheus.Desc) {
}
func TestIPVSCollectorResponse(t *testing.T) {
if err := flag.Set("collector.ipvs.procfs", "fixtures"); err != nil {
if err := flag.Set("collector.procfs", "fixtures"); err != nil {
t.Fatal(err)
}
collector, err := NewIPVSCollector()

View file

@ -12,10 +12,6 @@ import (
"github.com/prometheus/log"
)
const (
procLoad = "/proc/loadavg"
)
type loadavgCollector struct {
metric prometheus.Gauge
}
@ -48,7 +44,7 @@ func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) (err error) {
}
func getLoad1() (float64, error) {
data, err := ioutil.ReadFile(procLoad)
data, err := ioutil.ReadFile(procFilePath("loadavg"))
if err != nil {
return 0, err
}

View file

@ -15,7 +15,6 @@ import (
)
var (
statusfile = "/proc/mdstat"
statuslineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`)
buildlineRE = regexp.MustCompile(`\((\d+)/\d+\)`)
)
@ -90,7 +89,7 @@ func evalBuildline(buildline string) (int64, error) {
func parseMdstat(mdStatusFilePath string) ([]mdStatus, error) {
content, err := ioutil.ReadFile(mdStatusFilePath)
if err != nil {
return []mdStatus{}, fmt.Errorf("error parsing %s: %s", statusfile, err)
return []mdStatus{}, fmt.Errorf("error parsing mdstatus: %s", err)
}
mdStatusFile := string(content)
@ -128,13 +127,13 @@ func parseMdstat(mdStatusFilePath string) ([]mdStatus, error) {
isActive := (mainLine[2] == "active") // activity status of said md-device
if len(lines) <= i+3 {
return mdStates, fmt.Errorf("error parsing %s: entry for %s has fewer lines than expected", statusfile, currentMD)
return mdStates, fmt.Errorf("error parsing mdstatus: entry for %s has fewer lines than expected", currentMD)
}
active, total, size, err := evalStatusline(lines[i+1]) // parse statusline, always present
if err != nil {
return mdStates, fmt.Errorf("error parsing %s: %s", statusfile, err)
return mdStates, fmt.Errorf("error parsing mdstatus: %s", err)
}
// Now get the number of synced blocks.
@ -153,7 +152,7 @@ func parseMdstat(mdStatusFilePath string) ([]mdStatus, error) {
if strings.Contains(lines[j], "recovery") || strings.Contains(lines[j], "resync") {
syncedBlocks, err = evalBuildline(lines[j])
if err != nil {
return mdStates, fmt.Errorf("error parsing %s: %s", statusfile, err)
return mdStates, fmt.Errorf("error parsing mdstatus: %s", err)
}
} else {
syncedBlocks = size
@ -209,6 +208,7 @@ var (
)
func (c *mdadmCollector) Update(ch chan<- prometheus.Metric) (err error) {
statusfile := procFilePath("mdstatus")
// take care we don't crash on non-existent statusfiles
_, err = os.Stat(statusfile)
if os.IsNotExist(err) {
@ -223,7 +223,7 @@ func (c *mdadmCollector) Update(ch chan<- prometheus.Metric) (err error) {
// First parse mdstat-file...
mdstate, err := parseMdstat(statusfile)
if err != nil {
return fmt.Errorf("error parsing %s: %s", statusfile, err)
return fmt.Errorf("error parsing mdstatus: %s", err)
}
// ... and then plug the result into the metrics to be exported.

View file

@ -16,7 +16,6 @@ import (
)
const (
procMemInfo = "/proc/meminfo"
memInfoSubsystem = "memory"
)
@ -48,7 +47,7 @@ func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) {
Namespace: Namespace,
Subsystem: memInfoSubsystem,
Name: k,
Help: k + " from /proc/meminfo.",
Help: fmt.Sprintf("Memory information field %s.", k),
})
}
c.metrics[k].Set(v)
@ -58,7 +57,7 @@ func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) (err error) {
}
func getMemInfo() (map[string]float64, error) {
file, err := os.Open(procMemInfo)
file, err := os.Open(procFilePath("meminfo"))
if err != nil {
return nil, err
}
@ -86,7 +85,7 @@ func parseMemInfo(r io.Reader) (map[string]float64, error) {
case 3: // has unit, we presume kB
fv *= 1024
default:
return nil, fmt.Errorf("Invalid line in %s: %s", procMemInfo, line)
return nil, fmt.Errorf("Invalid line in meminfo: %s", line)
}
key := parts[0][:len(parts[0])-1] // remove trailing : from key
// Active(anon) -> Active_anon

View file

@ -16,10 +16,6 @@ import (
"github.com/prometheus/log"
)
const (
procNetDev = "/proc/net/dev"
)
var (
procNetDevFieldSep = regexp.MustCompile("[ :] *")
netdevIgnoredDevices = flag.String(
@ -59,7 +55,7 @@ func (c *netDevCollector) Update(ch chan<- prometheus.Metric) (err error) {
if !ok {
desc = prometheus.NewDesc(
prometheus.BuildFQName(Namespace, c.subsystem, key),
fmt.Sprintf("%s from /proc/net/dev.", key),
fmt.Sprintf("Network device statistic %s.", key),
[]string{"device"},
nil,
)
@ -76,7 +72,7 @@ func (c *netDevCollector) Update(ch chan<- prometheus.Metric) (err error) {
}
func getNetDevStats(ignore *regexp.Regexp) (map[string]map[string]string, error) {
file, err := os.Open(procNetDev)
file, err := os.Open(procFilePath("net/dev"))
if err != nil {
return nil, err
}
@ -91,8 +87,8 @@ func parseNetDevStats(r io.Reader, ignore *regexp.Regexp) (map[string]map[string
scanner.Scan()
parts := strings.Split(string(scanner.Text()), "|")
if len(parts) != 3 { // interface + receive + transmit
return nil, fmt.Errorf("invalid header line in %s: %s",
procNetDev, scanner.Text())
return nil, fmt.Errorf("invalid header line in net/dev: %s",
scanner.Text())
}
header := strings.Fields(parts[1])
@ -101,7 +97,7 @@ func parseNetDevStats(r io.Reader, ignore *regexp.Regexp) (map[string]map[string
line := strings.TrimLeft(string(scanner.Text()), " ")
parts := procNetDevFieldSep.Split(line, -1)
if len(parts) != 2*len(header)+1 {
return nil, fmt.Errorf("invalid line in %s: %s", procNetDev, scanner.Text())
return nil, fmt.Errorf("invalid line in net/dev: %s", scanner.Text())
}
dev := parts[0][:len(parts[0])]

View file

@ -14,8 +14,6 @@ import (
)
const (
procNetStat = "/proc/net/netstat"
procSNMPStat = "/proc/net/snmp"
netStatsSubsystem = "netstat"
)
@ -36,11 +34,11 @@ func NewNetStatCollector() (Collector, error) {
}
func (c *netStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
netStats, err := getNetStats(procNetStat)
netStats, err := getNetStats(procFilePath("net/netstat"))
if err != nil {
return fmt.Errorf("couldn't get netstats: %s", err)
}
snmpStats, err := getNetStats(procSNMPStat)
snmpStats, err := getNetStats(procFilePath("net/snmp"))
if err != nil {
return fmt.Errorf("couldn't get SNMP stats: %s", err)
}
@ -58,7 +56,7 @@ func (c *netStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
Namespace: Namespace,
Subsystem: netStatsSubsystem,
Name: key,
Help: fmt.Sprintf("%s %s from /proc/net/{netstat,snmp}.", protocol, name),
Help: fmt.Sprintf("Protocol %s statistic %s.", protocol, name),
},
)
}

17
collector/procpath.go Normal file
View file

@ -0,0 +1,17 @@
package collector
import (
"flag"
"path"
"github.com/prometheus/procfs"
)
var (
// The path of the proc filesystem.
procPath = flag.String("collector.procfs", procfs.DefaultMountPoint, "procfs mountpoint.")
)
func procFilePath(name string) string {
return path.Join(*procPath, name)
}

View file

@ -13,7 +13,6 @@ import (
)
const (
procSockStat = "/proc/net/sockstat"
sockStatSubsystem = "sockstat"
)
@ -36,7 +35,7 @@ func NewSockStatCollector() (Collector, error) {
}
func (c *sockStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
sockStats, err := getSockStats(procSockStat)
sockStats, err := getSockStats(procFilePath("net/sockstat"))
if err != nil {
return fmt.Errorf("couldn't get sockstats: %s", err)
}
@ -49,7 +48,7 @@ func (c *sockStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
Namespace: Namespace,
Subsystem: sockStatSubsystem,
Name: key,
Help: fmt.Sprintf("%s %s from /proc/net/sockstat.", protocol, name),
Help: fmt.Sprintf("Number of %s sockets in state %s.", protocol, name),
},
)
}

View file

@ -12,8 +12,7 @@ import (
)
const (
procStat = "/proc/stat"
userHz = 100
userHz = 100
)
type statCollector struct {
@ -75,9 +74,9 @@ func NewStatCollector() (Collector, error) {
}, nil
}
// Expose a variety of stats from /proc/stats.
// Expose kernel and system statistics.
func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) {
file, err := os.Open(procStat)
file, err := os.Open(procFilePath("stat"))
if err != nil {
return err
}

View file

@ -13,11 +13,6 @@ import (
"github.com/prometheus/client_golang/prometheus"
)
const (
procTCPStat = "/proc/net/tcp"
procTCP6Stat = "/proc/net/tcp6"
)
type TCPConnectionState int
const (
@ -58,14 +53,15 @@ func NewTCPStatCollector() (Collector, error) {
}
func (c *tcpStatCollector) Update(ch chan<- prometheus.Metric) (err error) {
tcpStats, err := getTCPStats(procTCPStat)
tcpStats, err := getTCPStats(procFilePath("net/tcp"))
if err != nil {
return fmt.Errorf("couldn't get tcpstats: %s", err)
}
// if enabled ipv6 system
if _, hasIPv6 := os.Stat(procTCP6Stat); hasIPv6 == nil {
tcp6Stats, err := getTCPStats(procTCP6Stat)
tcp6File := procFilePath("net/tcp6")
if _, hasIPv6 := os.Stat(tcp6File); hasIPv6 == nil {
tcp6Stats, err := getTCPStats(tcp6File)
if err != nil {
return fmt.Errorf("couldn't get tcp6stats: %s", err)
}