forked from influxdata/telegraf
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor procstat input (influxdata#2540)
fixes influxdata#1636 fixes influxdata#2315
- Loading branch information
1 parent
2520280
commit fe3c9b8
Showing
6 changed files
with
594 additions
and
273 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package procstat | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"os/exec" | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
type PIDFinder interface { | ||
PidFile(path string) ([]PID, error) | ||
Pattern(pattern string) ([]PID, error) | ||
Uid(user string) ([]PID, error) | ||
FullPattern(path string) ([]PID, error) | ||
} | ||
|
||
// Implemention of PIDGatherer that execs pgrep to find processes | ||
type Pgrep struct { | ||
path string | ||
} | ||
|
||
func NewPgrep() (PIDFinder, error) { | ||
path, err := exec.LookPath("pgrep") | ||
if err != nil { | ||
return nil, fmt.Errorf("Could not find pgrep binary: %s", err) | ||
} | ||
return &Pgrep{path}, nil | ||
} | ||
|
||
func (pg *Pgrep) PidFile(path string) ([]PID, error) { | ||
var pids []PID | ||
pidString, err := ioutil.ReadFile(path) | ||
if err != nil { | ||
return pids, fmt.Errorf("Failed to read pidfile '%s'. Error: '%s'", | ||
path, err) | ||
} | ||
pid, err := strconv.Atoi(strings.TrimSpace(string(pidString))) | ||
if err != nil { | ||
return pids, err | ||
} | ||
pids = append(pids, PID(pid)) | ||
return pids, nil | ||
} | ||
|
||
func (pg *Pgrep) Pattern(pattern string) ([]PID, error) { | ||
args := []string{pattern} | ||
return find(pg.path, args) | ||
} | ||
|
||
func (pg *Pgrep) Uid(user string) ([]PID, error) { | ||
args := []string{"-u", user} | ||
return find(pg.path, args) | ||
} | ||
|
||
func (pg *Pgrep) FullPattern(pattern string) ([]PID, error) { | ||
args := []string{"-f", pattern} | ||
return find(pg.path, args) | ||
} | ||
|
||
func find(path string, args []string) ([]PID, error) { | ||
out, err := run(path, args) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return parseOutput(out) | ||
} | ||
|
||
func run(path string, args []string) (string, error) { | ||
out, err := exec.Command(path, args...).Output() | ||
if err != nil { | ||
return "", fmt.Errorf("Error running %s: %s", path, err) | ||
} | ||
return string(out), err | ||
} | ||
|
||
func parseOutput(out string) ([]PID, error) { | ||
pids := []PID{} | ||
fields := strings.Fields(out) | ||
for _, field := range fields { | ||
pid, err := strconv.Atoi(field) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if err == nil { | ||
pids = append(pids, PID(pid)) | ||
} | ||
} | ||
return pids, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package procstat | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
|
||
"github.com/shirou/gopsutil/cpu" | ||
"github.com/shirou/gopsutil/process" | ||
) | ||
|
||
type Process interface { | ||
PID() PID | ||
Tags() map[string]string | ||
|
||
IOCounters() (*process.IOCountersStat, error) | ||
MemoryInfo() (*process.MemoryInfoStat, error) | ||
Name() (string, error) | ||
NumCtxSwitches() (*process.NumCtxSwitchesStat, error) | ||
NumFDs() (int32, error) | ||
NumThreads() (int32, error) | ||
Percent(interval time.Duration) (float64, error) | ||
Times() (*cpu.TimesStat, error) | ||
} | ||
|
||
type Proc struct { | ||
hasCPUTimes bool | ||
tags map[string]string | ||
*process.Process | ||
} | ||
|
||
func NewProc(pid PID) (Process, error) { | ||
process, err := process.NewProcess(int32(pid)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
proc := &Proc{ | ||
Process: process, | ||
hasCPUTimes: false, | ||
tags: make(map[string]string), | ||
} | ||
return proc, nil | ||
} | ||
|
||
func (p *Proc) Tags() map[string]string { | ||
return p.tags | ||
} | ||
|
||
func (p *Proc) PID() PID { | ||
return PID(p.Process.Pid) | ||
} | ||
|
||
func (p *Proc) Percent(interval time.Duration) (float64, error) { | ||
cpu_perc, err := p.Process.Percent(time.Duration(0)) | ||
if !p.hasCPUTimes && err == nil { | ||
p.hasCPUTimes = true | ||
return 0, fmt.Errorf("Must call Percent twice to compute percent cpu.") | ||
} | ||
return cpu_perc, err | ||
} |
Oops, something went wrong.