From 7a8f0bee479a30937e1dad0d558def101ffeb892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20DEHAY?= Date: Fri, 19 Feb 2016 19:25:17 +0100 Subject: [PATCH 1/3] Adding pgrep user support --- plugins/inputs/procstat/procstat.go | 33 +++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/plugins/inputs/procstat/procstat.go b/plugins/inputs/procstat/procstat.go index d3f18d5ea83e0..c1747b1e94093 100644 --- a/plugins/inputs/procstat/procstat.go +++ b/plugins/inputs/procstat/procstat.go @@ -19,6 +19,7 @@ type Procstat struct { Exe string Pattern string Prefix string + User string pidmap map[int32]*process.Process } @@ -37,6 +38,8 @@ var sampleConfig = ` # exe = "nginx" ## pattern as argument for pgrep (ie, pgrep -f ) # pattern = "nginx" + ## user as argument for pgrep (ie, pgrep -u ) + # user = "nginx" ## Field name prefix prefix = "" @@ -53,8 +56,8 @@ func (_ *Procstat) Description() string { func (p *Procstat) Gather(acc telegraf.Accumulator) error { err := p.createProcesses() if err != nil { - log.Printf("Error: procstat getting process, exe: [%s] pidfile: [%s] pattern: [%s] %s", - p.Exe, p.PidFile, p.Pattern, err.Error()) + log.Printf("Error: procstat getting process, exe: [%s] pidfile: [%s] pattern: [%s] user: [%s] %s", + p.Exe, p.PidFile, p.Pattern, p.User, err.Error()) } else { for _, proc := range p.pidmap { p := NewSpecProcessor(p.Prefix, acc, proc) @@ -103,6 +106,8 @@ func (p *Procstat) getAllPids() ([]int32, error) { pids, err = pidsFromExe(p.Exe) } else if p.Pattern != "" { pids, err = pidsFromPattern(p.Pattern) + } else if p.User != "" { + pids, err = pidsFromUser(p.User) } else { err = fmt.Errorf("Either exe, pid_file or pattern has to be specified") } @@ -175,6 +180,30 @@ func pidsFromPattern(pattern string) ([]int32, error) { return out, outerr } +func pidsFromUser(user string) ([]int32, error) { + var out []int32 + var outerr error + bin, err := exec.LookPath("pgrep") + if err != nil { + return out, fmt.Errorf("Couldn't find pgrep binary: %s", err) + } + pgrep, err := exec.Command(bin, "-u", user).Output() + if err != nil { + return out, fmt.Errorf("Failed to execute %s. Error: '%s'", bin, err) + } else { + pids := strings.Fields(string(pgrep)) + for _, pid := range pids { + ipid, err := strconv.Atoi(pid) + if err == nil { + out = append(out, int32(ipid)) + } else { + outerr = err + } + } + } + return out, outerr +} + func init() { inputs.Add("procstat", func() telegraf.Input { return NewProcstat() From 11f34919ddf23f057fd976a22162c52c62e7ac7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20DEHAY?= Date: Fri, 19 Feb 2016 19:27:47 +0100 Subject: [PATCH 2/3] README updated for pgrep user support --- plugins/inputs/procstat/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/inputs/procstat/README.md b/plugins/inputs/procstat/README.md index 0c37af50924de..90552c2a6cbcf 100644 --- a/plugins/inputs/procstat/README.md +++ b/plugins/inputs/procstat/README.md @@ -7,7 +7,8 @@ individual process using their /proc data. The plugin will tag processes by their PID and their process name. -Processes can be specified either by pid file or by executable name. Procstat +Processes can be specified either by pid file, by executable name, by command +line pattern matching, or by username (in this order or priority. Procstat plugin will use `pgrep` when executable name is provided to obtain the pid. Proctstas plugin will transmit IO, memory, cpu, file descriptor related measurements for every process specified. A prefix can be set to isolate From dbd558177f09665cb75f836985f4e563a7139626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20DEHAY?= Date: Fri, 19 Feb 2016 19:42:22 +0100 Subject: [PATCH 3/3] go fmt launched on file --- plugins/inputs/procstat/procstat.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/inputs/procstat/procstat.go b/plugins/inputs/procstat/procstat.go index c1747b1e94093..e5ae207fe5533 100644 --- a/plugins/inputs/procstat/procstat.go +++ b/plugins/inputs/procstat/procstat.go @@ -56,7 +56,7 @@ func (_ *Procstat) Description() string { func (p *Procstat) Gather(acc telegraf.Accumulator) error { err := p.createProcesses() if err != nil { - log.Printf("Error: procstat getting process, exe: [%s] pidfile: [%s] pattern: [%s] user: [%s] %s", + log.Printf("Error: procstat getting process, exe: [%s] pidfile: [%s] pattern: [%s] user: [%s] %s", p.Exe, p.PidFile, p.Pattern, p.User, err.Error()) } else { for _, proc := range p.pidmap {