parent
d3a5cca1bc
commit
d3925fe578
2
agent.go
2
agent.go
|
@ -216,7 +216,7 @@ func (a *Agent) Test() error {
|
||||||
// Special instructions for some inputs. cpu, for example, needs to be
|
// Special instructions for some inputs. cpu, for example, needs to be
|
||||||
// run twice in order to return cpu usage percentages.
|
// run twice in order to return cpu usage percentages.
|
||||||
switch input.Name {
|
switch input.Name {
|
||||||
case "cpu", "mongodb":
|
case "cpu", "mongodb", "procstat":
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
fmt.Printf("* Plugin: %s, Collection 2\n", input.Name)
|
fmt.Printf("* Plugin: %s, Collection 2\n", input.Name)
|
||||||
if err := input.Input.Gather(acc); err != nil {
|
if err := input.Input.Gather(acc); err != nil {
|
||||||
|
|
|
@ -18,10 +18,14 @@ type Procstat struct {
|
||||||
Exe string
|
Exe string
|
||||||
Pattern string
|
Pattern string
|
||||||
Prefix string
|
Prefix string
|
||||||
|
|
||||||
|
pidmap map[int32]*process.Process
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProcstat() *Procstat {
|
func NewProcstat() *Procstat {
|
||||||
return &Procstat{}
|
return &Procstat{
|
||||||
|
pidmap: make(map[int32]*process.Process),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var sampleConfig = `
|
var sampleConfig = `
|
||||||
|
@ -46,12 +50,12 @@ func (_ *Procstat) Description() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Procstat) Gather(acc inputs.Accumulator) error {
|
func (p *Procstat) Gather(acc inputs.Accumulator) error {
|
||||||
procs, err := p.createProcesses()
|
err := p.createProcesses()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error: procstat getting process, exe: [%s] pidfile: [%s] pattern: [%s] %s",
|
log.Printf("Error: procstat getting process, exe: [%s] pidfile: [%s] pattern: [%s] %s",
|
||||||
p.Exe, p.PidFile, p.Pattern, err.Error())
|
p.Exe, p.PidFile, p.Pattern, err.Error())
|
||||||
} else {
|
} else {
|
||||||
for _, proc := range procs {
|
for _, proc := range p.pidmap {
|
||||||
p := NewSpecProcessor(p.Prefix, acc, proc)
|
p := NewSpecProcessor(p.Prefix, acc, proc)
|
||||||
p.pushMetrics()
|
p.pushMetrics()
|
||||||
}
|
}
|
||||||
|
@ -60,8 +64,7 @@ func (p *Procstat) Gather(acc inputs.Accumulator) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Procstat) createProcesses() ([]*process.Process, error) {
|
func (p *Procstat) createProcesses() error {
|
||||||
var out []*process.Process
|
|
||||||
var errstring string
|
var errstring string
|
||||||
var outerr error
|
var outerr error
|
||||||
|
|
||||||
|
@ -71,19 +74,22 @@ func (p *Procstat) createProcesses() ([]*process.Process, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pid := range pids {
|
for _, pid := range pids {
|
||||||
p, err := process.NewProcess(int32(pid))
|
_, ok := p.pidmap[pid]
|
||||||
|
if !ok {
|
||||||
|
proc, err := process.NewProcess(pid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
out = append(out, p)
|
p.pidmap[pid] = proc
|
||||||
} else {
|
} else {
|
||||||
errstring += err.Error() + " "
|
errstring += err.Error() + " "
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if errstring != "" {
|
if errstring != "" {
|
||||||
outerr = fmt.Errorf("%s", errstring)
|
outerr = fmt.Errorf("%s", errstring)
|
||||||
}
|
}
|
||||||
|
|
||||||
return out, outerr
|
return outerr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Procstat) getAllPids() ([]int32, error) {
|
func (p *Procstat) getAllPids() ([]int32, error) {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/process"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ func TestGather(t *testing.T) {
|
||||||
p := Procstat{
|
p := Procstat{
|
||||||
PidFile: file.Name(),
|
PidFile: file.Name(),
|
||||||
Prefix: "foo",
|
Prefix: "foo",
|
||||||
|
pidmap: make(map[int32]*process.Process),
|
||||||
}
|
}
|
||||||
p.Gather(&acc)
|
p.Gather(&acc)
|
||||||
assert.True(t, acc.HasFloatField("procstat", "foo_cpu_time_user"))
|
assert.True(t, acc.HasFloatField("procstat", "foo_cpu_time_user"))
|
||||||
|
|
|
@ -2,7 +2,7 @@ package procstat
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"time"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/process"
|
"github.com/shirou/gopsutil/process"
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ func NewSpecProcessor(
|
||||||
tags := make(map[string]string)
|
tags := make(map[string]string)
|
||||||
tags["pid"] = fmt.Sprintf("%v", p.Pid)
|
tags["pid"] = fmt.Sprintf("%v", p.Pid)
|
||||||
if name, err := p.Name(); err == nil {
|
if name, err := p.Name(); err == nil {
|
||||||
tags["name"] = name
|
tags["process_name"] = name
|
||||||
}
|
}
|
||||||
return &SpecProcessor{
|
return &SpecProcessor{
|
||||||
Prefix: prefix,
|
Prefix: prefix,
|
||||||
|
@ -52,21 +52,11 @@ func NewSpecProcessor(
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *SpecProcessor) pushMetrics() {
|
func (p *SpecProcessor) pushMetrics() {
|
||||||
if err := p.pushFDStats(); err != nil {
|
p.pushFDStats()
|
||||||
log.Printf("procstat, fd stats not available: %s", err.Error())
|
p.pushCtxStats()
|
||||||
}
|
p.pushIOStats()
|
||||||
if err := p.pushCtxStats(); err != nil {
|
p.pushCPUStats()
|
||||||
log.Printf("procstat, ctx stats not available: %s", err.Error())
|
p.pushMemoryStats()
|
||||||
}
|
|
||||||
if err := p.pushIOStats(); err != nil {
|
|
||||||
log.Printf("procstat, io stats not available: %s", err.Error())
|
|
||||||
}
|
|
||||||
if err := p.pushCPUStats(); err != nil {
|
|
||||||
log.Printf("procstat, cpu stats not available: %s", err.Error())
|
|
||||||
}
|
|
||||||
if err := p.pushMemoryStats(); err != nil {
|
|
||||||
log.Printf("procstat, mem stats not available: %s", err.Error())
|
|
||||||
}
|
|
||||||
p.flush()
|
p.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,10 +103,18 @@ func (p *SpecProcessor) pushCPUStats() error {
|
||||||
p.add("cpu_time_iowait", cpu_time.Iowait)
|
p.add("cpu_time_iowait", cpu_time.Iowait)
|
||||||
p.add("cpu_time_irq", cpu_time.Irq)
|
p.add("cpu_time_irq", cpu_time.Irq)
|
||||||
p.add("cpu_time_soft_irq", cpu_time.Softirq)
|
p.add("cpu_time_soft_irq", cpu_time.Softirq)
|
||||||
p.add("cpu_time_soft_steal", cpu_time.Steal)
|
p.add("cpu_time_steal", cpu_time.Steal)
|
||||||
p.add("cpu_time_soft_stolen", cpu_time.Stolen)
|
p.add("cpu_time_stolen", cpu_time.Stolen)
|
||||||
p.add("cpu_time_soft_guest", cpu_time.Guest)
|
p.add("cpu_time_guest", cpu_time.Guest)
|
||||||
p.add("cpu_time_soft_guest_nice", cpu_time.GuestNice)
|
p.add("cpu_time_guest_nice", cpu_time.GuestNice)
|
||||||
|
|
||||||
|
cpu_perc, err := p.proc.CPUPercent(time.Duration(0))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if cpu_perc == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
p.add("cpu_usage", cpu_perc)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue