diff --git a/inputs/procstat/process.go b/inputs/procstat/process.go index a6f9b223..824a8eb5 100644 --- a/inputs/procstat/process.go +++ b/inputs/procstat/process.go @@ -27,6 +27,7 @@ type Process interface { Username() (string, error) CreateTime() (int64, error) Ppid() (int32, error) + Exe() (string, error) } type PIDFinder interface { diff --git a/inputs/procstat/procstat.go b/inputs/procstat/procstat.go index 3e6ae11d..9690f8cd 100644 --- a/inputs/procstat/procstat.go +++ b/inputs/procstat/procstat.go @@ -1,9 +1,13 @@ package procstat import ( + "crypto/md5" + "encoding/hex" "errors" "fmt" + "io" "log" + "os" "os/exec" "regexp" "runtime" @@ -179,6 +183,39 @@ func (ins *Instance) Gather(slist *types.SampleList) { } ins.updateProcesses(pids) + for pid, p := range ins.procs { + info := map[string]string{ + "pid": fmt.Sprint(pid), + } + if comm, err := p.Name(); err == nil { + info["comm"] = comm + } + info["binary_md5sum"] = "" + if cmd, err := p.Cmdline(); err == nil { + md5b := md5.Sum([]byte(cmd)) + sum := hex.EncodeToString(md5b[:]) + info["cmdline_md5sum"] = sum + } + if runtime.GOOS == "linux" { + if exe, err := p.Exe(); err == nil { + if sum, err := md5sum(exe); err == nil { + info["binary_md5sum"] = sum + } else { + if ins.DebugMod { + log.Println("E! failed to get md5sum of exe:", exe, "pid:", p.PID(), err) + } + if sum, err := md5sum(fmt.Sprintf("/proc/%d/exe", pid)); err == nil { + info["binary_md5sum"] = sum + } else { + if ins.DebugMod { + log.Println("E! failed to get md5sum of /proc/pid/exe:", p.PID(), err) + } + } + } + } + } + slist.PushFront(types.NewSample(inputName, "info", 1, info, tags)) + } for _, field := range ins.GatherMoreMetrics { switch field { @@ -231,6 +268,22 @@ func (ins *Instance) updateProcesses(pids []PID) { ins.procs = procs } +func md5sum(file string) (string, error) { + f, err := os.Open(file) + if err != nil { + return "", err + } + defer f.Close() + + md5h := md5.New() + if _, err := io.Copy(md5h, f); err != nil { + return "", err + } + + md5b := md5h.Sum([]byte("")) + return hex.EncodeToString(md5b[:]), nil +} + func (ins *Instance) makeProcTag(p Process) map[string]string { info := map[string]string{ "pid": fmt.Sprint(p.PID()), @@ -239,6 +292,7 @@ func (ins *Instance) makeProcTag(p Process) map[string]string { if err == nil { info["comm"] = comm } + if runtime.GOOS == "windows" { title := getWindowTitleByPid(uint32(p.PID())) if len(title) != 0 { @@ -272,7 +326,7 @@ func (ins *Instance) gatherFD(slist *types.SampleList, procs map[PID]Process, ta if err == nil { val += v if ins.GatherPerPid { - slist.PushFront(types.NewSample(inputName, "num_fds", val, ins.makeProcTag(procs[pid]), tags)) + slist.PushFront(types.NewSample(inputName, "num_fds", v, ins.makeProcTag(procs[pid]), tags)) } } }