github.com/rsampaio/docker@v0.7.2-0.20150827203920-fdc73cc3fc31/daemon/top_unix.go (about) 1 //+build !windows 2 3 package daemon 4 5 import ( 6 "fmt" 7 "os/exec" 8 "strconv" 9 "strings" 10 11 "github.com/docker/docker/api/types" 12 ) 13 14 func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error) { 15 if psArgs == "" { 16 psArgs = "-ef" 17 } 18 19 container, err := daemon.Get(name) 20 if err != nil { 21 return nil, err 22 } 23 24 if !container.IsRunning() { 25 return nil, fmt.Errorf("Container %s is not running", name) 26 } 27 28 pids, err := daemon.ExecutionDriver().GetPidsForContainer(container.ID) 29 if err != nil { 30 return nil, err 31 } 32 33 output, err := exec.Command("ps", strings.Split(psArgs, " ")...).Output() 34 if err != nil { 35 return nil, fmt.Errorf("Error running ps: %s", err) 36 } 37 38 procList := &types.ContainerProcessList{} 39 40 lines := strings.Split(string(output), "\n") 41 procList.Titles = strings.Fields(lines[0]) 42 43 pidIndex := -1 44 for i, name := range procList.Titles { 45 if name == "PID" { 46 pidIndex = i 47 } 48 } 49 if pidIndex == -1 { 50 return nil, fmt.Errorf("Couldn't find PID field in ps output") 51 } 52 53 for _, line := range lines[1:] { 54 if len(line) == 0 { 55 continue 56 } 57 fields := strings.Fields(line) 58 p, err := strconv.Atoi(fields[pidIndex]) 59 if err != nil { 60 return nil, fmt.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err) 61 } 62 63 for _, pid := range pids { 64 if pid == p { 65 // Make sure number of fields equals number of header titles 66 // merging "overhanging" fields 67 process := fields[:len(procList.Titles)-1] 68 process = append(process, strings.Join(fields[len(procList.Titles)-1:], " ")) 69 procList.Processes = append(procList.Processes, process) 70 } 71 } 72 } 73 container.LogEvent("top") 74 return procList, nil 75 }