2016-03-10 12:40:03 +00:00
|
|
|
// +build linux
|
|
|
|
|
|
|
|
package system
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"strconv"
|
|
|
|
|
2016-12-23 15:18:27 +00:00
|
|
|
"github.com/influxdata/telegraf/plugins"
|
2016-03-10 12:40:03 +00:00
|
|
|
"github.com/influxdata/telegraf/plugins/inputs"
|
|
|
|
)
|
|
|
|
|
|
|
|
// /proc/stat file line prefixes to gather stats on:
|
|
|
|
var (
|
|
|
|
interrupts = []byte("intr")
|
|
|
|
context_switches = []byte("ctxt")
|
|
|
|
processes_forked = []byte("processes")
|
|
|
|
disk_pages = []byte("page")
|
|
|
|
boot_time = []byte("btime")
|
|
|
|
)
|
|
|
|
|
|
|
|
type Kernel struct {
|
|
|
|
statFile string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (k *Kernel) Description() string {
|
|
|
|
return "Get kernel statistics from /proc/stat"
|
|
|
|
}
|
|
|
|
|
|
|
|
func (k *Kernel) SampleConfig() string { return "" }
|
|
|
|
|
2016-12-23 15:18:27 +00:00
|
|
|
func (k *Kernel) Gather(acc plugins.Accumulator) error {
|
2016-03-10 12:40:03 +00:00
|
|
|
data, err := k.getProcStat()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
fields := make(map[string]interface{})
|
|
|
|
|
|
|
|
dataFields := bytes.Fields(data)
|
|
|
|
for i, field := range dataFields {
|
|
|
|
switch {
|
|
|
|
case bytes.Equal(field, interrupts):
|
2016-05-25 11:07:47 +00:00
|
|
|
m, err := strconv.ParseInt(string(dataFields[i+1]), 10, 64)
|
2016-03-10 12:40:03 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
fields["interrupts"] = int64(m)
|
|
|
|
case bytes.Equal(field, context_switches):
|
2016-05-25 11:07:47 +00:00
|
|
|
m, err := strconv.ParseInt(string(dataFields[i+1]), 10, 64)
|
2016-03-10 12:40:03 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
fields["context_switches"] = int64(m)
|
|
|
|
case bytes.Equal(field, processes_forked):
|
2016-05-25 11:07:47 +00:00
|
|
|
m, err := strconv.ParseInt(string(dataFields[i+1]), 10, 64)
|
2016-03-10 12:40:03 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
fields["processes_forked"] = int64(m)
|
|
|
|
case bytes.Equal(field, boot_time):
|
2016-05-25 11:07:47 +00:00
|
|
|
m, err := strconv.ParseInt(string(dataFields[i+1]), 10, 64)
|
2016-03-10 12:40:03 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
fields["boot_time"] = int64(m)
|
|
|
|
case bytes.Equal(field, disk_pages):
|
2016-05-25 11:07:47 +00:00
|
|
|
in, err := strconv.ParseInt(string(dataFields[i+1]), 10, 64)
|
2016-03-10 12:40:03 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-05-25 11:07:47 +00:00
|
|
|
out, err := strconv.ParseInt(string(dataFields[i+2]), 10, 64)
|
2016-03-10 12:40:03 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
fields["disk_pages_in"] = int64(in)
|
|
|
|
fields["disk_pages_out"] = int64(out)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-31 16:27:37 +00:00
|
|
|
acc.AddCounter("kernel", fields, map[string]string{})
|
2016-03-10 12:40:03 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (k *Kernel) getProcStat() ([]byte, error) {
|
|
|
|
if _, err := os.Stat(k.statFile); os.IsNotExist(err) {
|
|
|
|
return nil, fmt.Errorf("kernel: %s does not exist!", k.statFile)
|
|
|
|
} else if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
data, err := ioutil.ReadFile(k.statFile)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return data, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
2016-12-23 15:18:27 +00:00
|
|
|
inputs.Add("kernel", func() plugins.Input {
|
2016-03-10 12:40:03 +00:00
|
|
|
return &Kernel{
|
|
|
|
statFile: "/proc/stat",
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|