mirror of
https://github.com/prometheus/node_exporter.git
synced 2024-12-31 16:37:31 -08:00
1c17481a42
Switch to Update using the Collecter Collect interface, due to not knowing all metricnames in all modules beforehand we can't use Describe and thus the full Collecter interface. Remove 'updates', it's meaning varies by module and doesn't add much.
155 lines
3.8 KiB
Go
155 lines
3.8 KiB
Go
// +build !nostat
|
|
|
|
package collector
|
|
|
|
import (
|
|
"bufio"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
)
|
|
|
|
// #include <unistd.h>
|
|
import "C"
|
|
|
|
const (
|
|
procStat = "/proc/stat"
|
|
)
|
|
|
|
var (
|
|
cpuMetrics = prometheus.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Namespace: Namespace,
|
|
Name: "cpu",
|
|
Help: "Seconds the cpus spent in each mode.",
|
|
},
|
|
[]string{"cpu", "mode"},
|
|
)
|
|
intrMetric = prometheus.NewCounter(prometheus.CounterOpts{
|
|
Namespace: Namespace,
|
|
Name: "intr",
|
|
Help: "Total number of interrupts serviced.",
|
|
})
|
|
ctxtMetric = prometheus.NewCounter(prometheus.CounterOpts{
|
|
Namespace: Namespace,
|
|
Name: "context_switches",
|
|
Help: "Total number of context switches.",
|
|
})
|
|
forksMetric = prometheus.NewCounter(prometheus.CounterOpts{
|
|
Namespace: Namespace,
|
|
Name: "forks",
|
|
Help: "Total number of forks.",
|
|
})
|
|
btimeMetric = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
Namespace: Namespace,
|
|
Name: "boot_time",
|
|
Help: "Node boot time, in unixtime.",
|
|
})
|
|
procsRunningMetric = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
Namespace: Namespace,
|
|
Name: "procs_running",
|
|
Help: "Number of processes in runnable state.",
|
|
})
|
|
procsBlockedMetric = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
Namespace: Namespace,
|
|
Name: "procs_blocked",
|
|
Help: "Number of processes blocked waiting for I/O to complete.",
|
|
})
|
|
)
|
|
|
|
type statCollector struct {
|
|
config Config
|
|
}
|
|
|
|
func init() {
|
|
Factories["stat"] = NewStatCollector
|
|
}
|
|
|
|
// Takes a config struct and prometheus registry and returns a new Collector exposing
|
|
// network device stats.
|
|
func NewStatCollector(config Config) (Collector, error) {
|
|
c := statCollector{
|
|
config: config,
|
|
}
|
|
return &c, nil
|
|
}
|
|
|
|
// Expose a variety of stats from /proc/stats.
|
|
func (c *statCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
|
file, err := os.Open(procStat)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
for scanner.Scan() {
|
|
parts := strings.Fields(scanner.Text())
|
|
switch {
|
|
case strings.HasPrefix(parts[0], "cpu"):
|
|
// Export only per-cpu stats, it can be aggregated up in prometheus.
|
|
if parts[0] == "cpu" {
|
|
break
|
|
}
|
|
// Only some of these may be present, depending on kernel version.
|
|
cpuFields := []string{"user", "nice", "system", "idle", "iowait", "irq", "softirq", "steal", "guest"}
|
|
for i, v := range parts[1 : len(cpuFields)+1] {
|
|
value, err := strconv.ParseFloat(v, 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// Convert from ticks to seconds
|
|
value /= float64(C.sysconf(C._SC_CLK_TCK))
|
|
cpuMetrics.With(prometheus.Labels{"cpu": parts[0], "mode": cpuFields[i]}).Set(value)
|
|
}
|
|
case parts[0] == "intr":
|
|
// Only expose the overall number, use the 'interrupts' collector for more detail.
|
|
value, err := strconv.ParseFloat(parts[1], 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
intrMetric.Set(value)
|
|
case parts[0] == "ctxt":
|
|
value, err := strconv.ParseFloat(parts[1], 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
ctxtMetric.Set(value)
|
|
case parts[0] == "processes":
|
|
value, err := strconv.ParseFloat(parts[1], 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
forksMetric.Set(value)
|
|
case parts[0] == "btime":
|
|
value, err := strconv.ParseFloat(parts[1], 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
btimeMetric.Set(value)
|
|
case parts[0] == "procs_running":
|
|
value, err := strconv.ParseFloat(parts[1], 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
procsRunningMetric.Set(value)
|
|
case parts[0] == "procs_blocked":
|
|
value, err := strconv.ParseFloat(parts[1], 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
procsBlockedMetric.Set(value)
|
|
}
|
|
}
|
|
cpuMetrics.Collect(ch)
|
|
ctxtMetric.Collect(ch)
|
|
intrMetric.Collect(ch)
|
|
forksMetric.Collect(ch)
|
|
btimeMetric.Collect(ch)
|
|
procsRunningMetric.Collect(ch)
|
|
procsBlockedMetric.Collect(ch)
|
|
return err
|
|
}
|