Skip to content

Commit 84af30d

Browse files
MrMaxBuildsotherpirate
authored andcommitted
Add new measurement with results of pgrep lookup to procstat input (influxdata#4307)
1 parent 13b9c6d commit 84af30d

File tree

4 files changed

+53
-8
lines changed

4 files changed

+53
-8
lines changed

internal/internal.go

+13
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"os/exec"
1212
"strconv"
1313
"strings"
14+
"syscall"
1415
"time"
1516
"unicode"
1617
)
@@ -193,3 +194,15 @@ func RandomSleep(max time.Duration, shutdown chan struct{}) {
193194
return
194195
}
195196
}
197+
198+
// Exit status takes the error from exec.Command
199+
// and returns the exit status and true
200+
// if error is not exit status, will return 0 and false
201+
func ExitStatus(err error) (int, bool) {
202+
if exiterr, ok := err.(*exec.ExitError); ok {
203+
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
204+
return status.ExitStatus(), true
205+
}
206+
}
207+
return 0, false
208+
}

plugins/inputs/procstat/pgrep.go

+8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"os/exec"
77
"strconv"
88
"strings"
9+
10+
"github.com/influxdata/telegraf/internal"
911
)
1012

1113
// Implemention of PIDGatherer that execs pgrep to find processes
@@ -62,6 +64,12 @@ func find(path string, args []string) ([]PID, error) {
6264

6365
func run(path string, args []string) (string, error) {
6466
out, err := exec.Command(path, args...).Output()
67+
68+
//if exit code 1, ie no processes found, do not return error
69+
if i, _ := internal.ExitStatus(err); i == 1 {
70+
return "", nil
71+
}
72+
6573
if err != nil {
6674
return "", fmt.Errorf("Error running %s: %s", path, err)
6775
}

plugins/inputs/procstat/procstat.go

+17-6
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func (p *Procstat) Gather(acc telegraf.Accumulator) error {
9797
p.createProcess = defaultProcess
9898
}
9999

100-
procs, err := p.updateProcesses(p.procs)
100+
procs, err := p.updateProcesses(acc, p.procs)
101101
if err != nil {
102102
acc.AddError(fmt.Errorf("E! Error: procstat getting process, exe: [%s] pidfile: [%s] pattern: [%s] user: [%s] %s",
103103
p.Exe, p.PidFile, p.Pattern, p.User, err.Error()))
@@ -230,8 +230,8 @@ func (p *Procstat) addMetrics(proc Process, acc telegraf.Accumulator) {
230230
}
231231

232232
// Update monitored Processes
233-
func (p *Procstat) updateProcesses(prevInfo map[PID]Process) (map[PID]Process, error) {
234-
pids, tags, err := p.findPids()
233+
func (p *Procstat) updateProcesses(acc telegraf.Accumulator, prevInfo map[PID]Process) (map[PID]Process, error) {
234+
pids, tags, err := p.findPids(acc)
235235
if err != nil {
236236
return nil, err
237237
}
@@ -281,9 +281,9 @@ func (p *Procstat) getPIDFinder() (PIDFinder, error) {
281281
}
282282

283283
// Get matching PIDs and their initial tags
284-
func (p *Procstat) findPids() ([]PID, map[string]string, error) {
284+
func (p *Procstat) findPids(acc telegraf.Accumulator) ([]PID, map[string]string, error) {
285285
var pids []PID
286-
var tags map[string]string
286+
tags := make(map[string]string)
287287
var err error
288288

289289
f, err := p.getPIDFinder()
@@ -313,7 +313,18 @@ func (p *Procstat) findPids() ([]PID, map[string]string, error) {
313313
err = fmt.Errorf("Either exe, pid_file, user, pattern, systemd_unit, or cgroup must be specified")
314314
}
315315

316-
return pids, tags, err
316+
rTags := make(map[string]string)
317+
for k, v := range tags {
318+
rTags[k] = v
319+
}
320+
321+
//adds a metric with info on the pgrep query
322+
fields := make(map[string]interface{})
323+
tags["pid_finder"] = p.PidFinder
324+
fields["pid_count"] = len(pids)
325+
acc.AddFields("procstat_lookup", fields, tags)
326+
327+
return pids, rTags, err
317328
}
318329

319330
// execCommand is so tests can mock out exec.Command usage.

plugins/inputs/procstat/procstat_test.go

+15-2
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,8 @@ func TestGather_systemdUnitPIDs(t *testing.T) {
343343
createPIDFinder: pidFinder([]PID{}, nil),
344344
SystemdUnit: "TestGather_systemdUnitPIDs",
345345
}
346-
pids, tags, err := p.findPids()
346+
var acc testutil.Accumulator
347+
pids, tags, err := p.findPids(&acc)
347348
require.NoError(t, err)
348349
assert.Equal(t, []PID{11408}, pids)
349350
assert.Equal(t, "TestGather_systemdUnitPIDs", tags["systemd_unit"])
@@ -364,8 +365,20 @@ func TestGather_cgroupPIDs(t *testing.T) {
364365
createPIDFinder: pidFinder([]PID{}, nil),
365366
CGroup: td,
366367
}
367-
pids, tags, err := p.findPids()
368+
var acc testutil.Accumulator
369+
pids, tags, err := p.findPids(&acc)
368370
require.NoError(t, err)
369371
assert.Equal(t, []PID{1234, 5678}, pids)
370372
assert.Equal(t, td, tags["cgroup"])
371373
}
374+
375+
func TestProcstatLookupMetric(t *testing.T) {
376+
p := Procstat{
377+
createPIDFinder: pidFinder([]PID{543}, nil),
378+
Exe: "-Gsys",
379+
}
380+
var acc testutil.Accumulator
381+
err := acc.GatherError(p.Gather)
382+
require.NoError(t, err)
383+
require.Equal(t, len(p.procs)+1, len(acc.Metrics))
384+
}

0 commit comments

Comments
 (0)