github.com/mackerelio/mackerel-agent-plugins@v0.89.3/mackerel-plugin-proc-fd/lib/open_fd.go (about) 1 package mpprocfd 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 8 "github.com/mattn/go-pipeline" 9 ) 10 11 // OpenFd interface 12 type OpenFd interface { 13 getNumOpenFileDesc() (map[string]uint64, error) 14 } 15 16 var openFd OpenFd 17 18 // RealOpenFd struct 19 type RealOpenFd struct { 20 process string 21 } 22 23 func (o RealOpenFd) getNumOpenFileDesc() (map[string]uint64, error) { 24 fds := make(map[string]uint64) 25 26 // Fetch all pids which contain specified process name 27 out, err := pipeline.Output( 28 []string{"ps", "aux"}, 29 []string{"grep", o.process}, 30 []string{"grep", "-v", "grep"}, 31 []string{"grep", "-v", "mackerel-plugin-proc-fd"}, 32 []string{"awk", "{print $2}"}, 33 ) 34 if err != nil { 35 // No matching with p.Process invokes this case 36 return nil, err 37 } 38 39 // List the number of all open files beloging to each pid 40 for _, pid := range strings.Split(strings.TrimSpace(string(out)), "\n") { 41 out, err = pipeline.Output( 42 []string{"ls", "-l", fmt.Sprintf("/proc/%s/fd", pid)}, 43 []string{"grep", "-v", "total"}, 44 []string{"wc", "-l"}, 45 ) 46 if err != nil { 47 // The process with pid terminates" 48 return nil, err 49 } 50 51 num, err := strconv.ParseUint(strings.TrimSpace(string(out)), 10, 32) 52 if err != nil { 53 return nil, err 54 } 55 fds[pid] = num 56 } 57 58 return fds, nil 59 }