github.com/hustcat/docker@v1.3.3-0.20160314103604-901c67a8eeab/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/engine-api/types" 12 ) 13 14 // ContainerTop lists the processes running inside of the given 15 // container by calling ps with the given args, or with the flags 16 // "-ef" if no args are given. An error is returned if the container 17 // is not found, or is not running, or if there are any problems 18 // running ps, or parsing the output. 19 func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error) { 20 if psArgs == "" { 21 psArgs = "-ef" 22 } 23 24 container, err := daemon.GetContainer(name) 25 if err != nil { 26 return nil, err 27 } 28 29 if !container.IsRunning() { 30 return nil, errNotRunning{container.ID} 31 } 32 33 if container.IsRestarting() { 34 return nil, errContainerIsRestarting(container.ID) 35 } 36 pids, err := daemon.ExecutionDriver().GetPidsForContainer(container.ID) 37 if err != nil { 38 return nil, err 39 } 40 41 output, err := exec.Command("ps", strings.Split(psArgs, " ")...).Output() 42 if err != nil { 43 return nil, fmt.Errorf("Error running ps: %v", err) 44 } 45 46 procList := &types.ContainerProcessList{} 47 48 lines := strings.Split(string(output), "\n") 49 procList.Titles = strings.Fields(lines[0]) 50 51 pidIndex := -1 52 for i, name := range procList.Titles { 53 if name == "PID" { 54 pidIndex = i 55 } 56 } 57 if pidIndex == -1 { 58 return nil, fmt.Errorf("Couldn't find PID field in ps output") 59 } 60 61 // loop through the output and extract the PID from each line 62 for _, line := range lines[1:] { 63 if len(line) == 0 { 64 continue 65 } 66 fields := strings.Fields(line) 67 p, err := strconv.Atoi(fields[pidIndex]) 68 if err != nil { 69 return nil, fmt.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err) 70 } 71 72 for _, pid := range pids { 73 if pid == p { 74 // Make sure number of fields equals number of header titles 75 // merging "overhanging" fields 76 process := fields[:len(procList.Titles)-1] 77 process = append(process, strings.Join(fields[len(procList.Titles)-1:], " ")) 78 procList.Processes = append(procList.Processes, process) 79 } 80 } 81 } 82 daemon.LogContainerEvent(container, "top") 83 return procList, nil 84 }