Moved system package inputs out to top level (#4406)
This commit is contained in:
committed by
Daniel Nelson
parent
9a14d1f074
commit
7b73b0db3a
71
plugins/inputs/kernel/README.md
Normal file
71
plugins/inputs/kernel/README.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# Kernel Input Plugin
|
||||
|
||||
This plugin is only available on Linux.
|
||||
|
||||
The kernel plugin gathers info about the kernel that doesn't fit into other
|
||||
plugins. In general, it is the statistics available in `/proc/stat` that are
|
||||
not covered by other plugins as well as the value of `/proc/sys/kernel/random/entropy_avail`
|
||||
|
||||
The metrics are documented in `man proc` under the `/proc/stat` section.
|
||||
The metrics are documented in `man 4 random` under the `/proc/stat` section.
|
||||
|
||||
```
|
||||
|
||||
|
||||
/proc/sys/kernel/random/entropy_avail
|
||||
Contains the value of available entropy
|
||||
|
||||
/proc/stat
|
||||
kernel/system statistics. Varies with architecture. Common entries include:
|
||||
|
||||
page 5741 1808
|
||||
The number of pages the system paged in and the number that were paged out (from disk).
|
||||
|
||||
swap 1 0
|
||||
The number of swap pages that have been brought in and out.
|
||||
|
||||
intr 1462898
|
||||
This line shows counts of interrupts serviced since boot time, for each of
|
||||
the possible system interrupts. The first column is the total of all
|
||||
interrupts serviced; each subsequent column is the total for a particular interrupt.
|
||||
|
||||
ctxt 115315
|
||||
The number of context switches that the system underwent.
|
||||
|
||||
btime 769041601
|
||||
boot time, in seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).
|
||||
|
||||
processes 86031
|
||||
Number of forks since boot.
|
||||
```
|
||||
|
||||
### Configuration:
|
||||
|
||||
```toml
|
||||
# Get kernel statistics from /proc/stat
|
||||
[[inputs.kernel]]
|
||||
# no configuration
|
||||
```
|
||||
|
||||
### Measurements & Fields:
|
||||
|
||||
- kernel
|
||||
- boot_time (integer, seconds since epoch, `btime`)
|
||||
- context_switches (integer, `ctxt`)
|
||||
- disk_pages_in (integer, `page (0)`)
|
||||
- disk_pages_out (integer, `page (1)`)
|
||||
- interrupts (integer, `intr`)
|
||||
- processes_forked (integer, `processes`)
|
||||
- entropy_avail (integer, `entropy_available`)
|
||||
|
||||
### Tags:
|
||||
|
||||
None
|
||||
|
||||
### Example Output:
|
||||
|
||||
```
|
||||
$ telegraf --config ~/ws/telegraf.conf --input-filter kernel --test
|
||||
* Plugin: kernel, Collection 1
|
||||
> kernel entropy_available=2469i,boot_time=1457505775i,context_switches=2626618i,disk_pages_in=5741i,disk_pages_out=1808i,interrupts=1472736i,processes_forked=10673i 1457613402960879816
|
||||
```
|
||||
127
plugins/inputs/kernel/kernel.go
Normal file
127
plugins/inputs/kernel/kernel.go
Normal file
@@ -0,0 +1,127 @@
|
||||
// +build linux
|
||||
|
||||
package kernel
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"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
|
||||
entropyStatFile string
|
||||
}
|
||||
|
||||
func (k *Kernel) Description() string {
|
||||
return "Get kernel statistics from /proc/stat"
|
||||
}
|
||||
|
||||
func (k *Kernel) SampleConfig() string { return "" }
|
||||
|
||||
func (k *Kernel) Gather(acc telegraf.Accumulator) error {
|
||||
|
||||
data, err := k.getProcStat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
entropyData, err := ioutil.ReadFile(k.entropyStatFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
entropyString := string(entropyData)
|
||||
entropyValue, err := strconv.ParseInt(strings.TrimSpace(entropyString), 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fields := make(map[string]interface{})
|
||||
|
||||
fields["entropy_avail"] = int64(entropyValue)
|
||||
|
||||
dataFields := bytes.Fields(data)
|
||||
for i, field := range dataFields {
|
||||
switch {
|
||||
case bytes.Equal(field, interrupts):
|
||||
m, err := strconv.ParseInt(string(dataFields[i+1]), 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fields["interrupts"] = int64(m)
|
||||
case bytes.Equal(field, context_switches):
|
||||
m, err := strconv.ParseInt(string(dataFields[i+1]), 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fields["context_switches"] = int64(m)
|
||||
case bytes.Equal(field, processes_forked):
|
||||
m, err := strconv.ParseInt(string(dataFields[i+1]), 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fields["processes_forked"] = int64(m)
|
||||
case bytes.Equal(field, boot_time):
|
||||
m, err := strconv.ParseInt(string(dataFields[i+1]), 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fields["boot_time"] = int64(m)
|
||||
case bytes.Equal(field, disk_pages):
|
||||
in, err := strconv.ParseInt(string(dataFields[i+1]), 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out, err := strconv.ParseInt(string(dataFields[i+2]), 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fields["disk_pages_in"] = int64(in)
|
||||
fields["disk_pages_out"] = int64(out)
|
||||
}
|
||||
}
|
||||
|
||||
acc.AddCounter("kernel", fields, map[string]string{})
|
||||
|
||||
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() {
|
||||
inputs.Add("kernel", func() telegraf.Input {
|
||||
return &Kernel{
|
||||
statFile: "/proc/stat",
|
||||
entropyStatFile: "/proc/sys/kernel/random/entropy_avail",
|
||||
}
|
||||
})
|
||||
}
|
||||
27
plugins/inputs/kernel/kernel_notlinux.go
Normal file
27
plugins/inputs/kernel/kernel_notlinux.go
Normal file
@@ -0,0 +1,27 @@
|
||||
// +build !linux
|
||||
|
||||
package kernel
|
||||
|
||||
import (
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
type Kernel struct {
|
||||
}
|
||||
|
||||
func (k *Kernel) Description() string {
|
||||
return "Get kernel statistics from /proc/stat"
|
||||
}
|
||||
|
||||
func (k *Kernel) SampleConfig() string { return "" }
|
||||
|
||||
func (k *Kernel) Gather(acc telegraf.Accumulator) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
inputs.Add("kernel", func() telegraf.Input {
|
||||
return &Kernel{}
|
||||
})
|
||||
}
|
||||
184
plugins/inputs/kernel/kernel_test.go
Normal file
184
plugins/inputs/kernel/kernel_test.go
Normal file
@@ -0,0 +1,184 @@
|
||||
// +build linux
|
||||
|
||||
package kernel
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFullProcFile(t *testing.T) {
|
||||
tmpfile := makeFakeStatFile([]byte(statFile_Full))
|
||||
tmpfile2 := makeFakeStatFile([]byte(entropyStatFile_Full))
|
||||
defer os.Remove(tmpfile)
|
||||
defer os.Remove(tmpfile2)
|
||||
|
||||
k := Kernel{
|
||||
statFile: tmpfile,
|
||||
entropyStatFile: tmpfile2,
|
||||
}
|
||||
|
||||
acc := testutil.Accumulator{}
|
||||
err := k.Gather(&acc)
|
||||
assert.NoError(t, err)
|
||||
|
||||
fields := map[string]interface{}{
|
||||
"boot_time": int64(1457505775),
|
||||
"context_switches": int64(2626618),
|
||||
"disk_pages_in": int64(5741),
|
||||
"disk_pages_out": int64(1808),
|
||||
"interrupts": int64(1472736),
|
||||
"processes_forked": int64(10673),
|
||||
"entropy_avail": int64(1024),
|
||||
}
|
||||
acc.AssertContainsFields(t, "kernel", fields)
|
||||
}
|
||||
|
||||
func TestPartialProcFile(t *testing.T) {
|
||||
tmpfile := makeFakeStatFile([]byte(statFile_Partial))
|
||||
tmpfile2 := makeFakeStatFile([]byte(entropyStatFile_Partial))
|
||||
defer os.Remove(tmpfile)
|
||||
defer os.Remove(tmpfile2)
|
||||
|
||||
k := Kernel{
|
||||
statFile: tmpfile,
|
||||
entropyStatFile: tmpfile2,
|
||||
}
|
||||
|
||||
acc := testutil.Accumulator{}
|
||||
err := k.Gather(&acc)
|
||||
assert.NoError(t, err)
|
||||
|
||||
fields := map[string]interface{}{
|
||||
"boot_time": int64(1457505775),
|
||||
"context_switches": int64(2626618),
|
||||
"disk_pages_in": int64(5741),
|
||||
"disk_pages_out": int64(1808),
|
||||
"interrupts": int64(1472736),
|
||||
"entropy_avail": int64(1024),
|
||||
}
|
||||
acc.AssertContainsFields(t, "kernel", fields)
|
||||
}
|
||||
|
||||
func TestInvalidProcFile1(t *testing.T) {
|
||||
tmpfile := makeFakeStatFile([]byte(statFile_Invalid))
|
||||
tmpfile2 := makeFakeStatFile([]byte(entropyStatFile_Invalid))
|
||||
defer os.Remove(tmpfile)
|
||||
defer os.Remove(tmpfile2)
|
||||
|
||||
k := Kernel{
|
||||
statFile: tmpfile,
|
||||
entropyStatFile: tmpfile2,
|
||||
}
|
||||
|
||||
acc := testutil.Accumulator{}
|
||||
err := k.Gather(&acc)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestInvalidProcFile2(t *testing.T) {
|
||||
tmpfile := makeFakeStatFile([]byte(statFile_Invalid2))
|
||||
defer os.Remove(tmpfile)
|
||||
|
||||
k := Kernel{
|
||||
statFile: tmpfile,
|
||||
}
|
||||
|
||||
acc := testutil.Accumulator{}
|
||||
err := k.Gather(&acc)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestNoProcFile(t *testing.T) {
|
||||
tmpfile := makeFakeStatFile([]byte(statFile_Invalid2))
|
||||
os.Remove(tmpfile)
|
||||
|
||||
k := Kernel{
|
||||
statFile: tmpfile,
|
||||
}
|
||||
|
||||
acc := testutil.Accumulator{}
|
||||
err := k.Gather(&acc)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "does not exist")
|
||||
}
|
||||
|
||||
const statFile_Full = `cpu 6796 252 5655 10444977 175 0 101 0 0 0
|
||||
cpu0 6796 252 5655 10444977 175 0 101 0 0 0
|
||||
intr 1472736 57 10 0 0 0 0 0 0 0 0 0 0 156 0 0 0 0 0 0 111551 42541 12356 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
ctxt 2626618
|
||||
btime 1457505775
|
||||
processes 10673
|
||||
procs_running 2
|
||||
procs_blocked 0
|
||||
softirq 1031662 0 649485 20946 111071 11620 0 1 0 994 237545
|
||||
page 5741 1808
|
||||
swap 1 0
|
||||
entropy_avail 1024
|
||||
`
|
||||
|
||||
const statFile_Partial = `cpu 6796 252 5655 10444977 175 0 101 0 0 0
|
||||
cpu0 6796 252 5655 10444977 175 0 101 0 0 0
|
||||
intr 1472736 57 10 0 0 0 0 0 0 0 0 0 0 156 0 0 0 0 0 0 111551 42541 12356 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
ctxt 2626618
|
||||
btime 1457505775
|
||||
procs_running 2
|
||||
procs_blocked 0
|
||||
softirq 1031662 0 649485 20946 111071 11620 0 1 0 994 237545
|
||||
page 5741 1808
|
||||
`
|
||||
|
||||
// missing btime measurement
|
||||
const statFile_Invalid = `cpu 6796 252 5655 10444977 175 0 101 0 0 0
|
||||
cpu0 6796 252 5655 10444977 175 0 101 0 0 0
|
||||
intr 1472736 57 10 0 0 0 0 0 0 0 0 0 0 156 0 0 0 0 0 0 111551 42541 12356 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
ctxt 2626618
|
||||
btime
|
||||
processes 10673
|
||||
procs_running 2
|
||||
procs_blocked 0
|
||||
softirq 1031662 0 649485 20946 111071 11620 0 1 0 994 237545
|
||||
page 5741 1808
|
||||
swap 1 0
|
||||
entropy_avail 1024
|
||||
`
|
||||
|
||||
// missing second page measurement
|
||||
const statFile_Invalid2 = `cpu 6796 252 5655 10444977 175 0 101 0 0 0
|
||||
cpu0 6796 252 5655 10444977 175 0 101 0 0 0
|
||||
intr 1472736 57 10 0 0 0 0 0 0 0 0 0 0 156 0 0 0 0 0 0 111551 42541 12356 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
ctxt 2626618
|
||||
processes 10673
|
||||
procs_running 2
|
||||
page 5741
|
||||
procs_blocked 0
|
||||
softirq 1031662 0 649485 20946 111071 11620 0 1 0 994 237545
|
||||
entropy_avail 1024 2048
|
||||
`
|
||||
|
||||
const entropyStatFile_Full = `1024`
|
||||
|
||||
const entropyStatFile_Partial = `1024`
|
||||
|
||||
const entropyStatFile_Invalid = ``
|
||||
|
||||
func makeFakeStatFile(content []byte) string {
|
||||
tmpfile, err := ioutil.TempFile("", "kernel_test")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if _, err := tmpfile.Write(content); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := tmpfile.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return tmpfile.Name()
|
||||
}
|
||||
Reference in New Issue
Block a user