github.com/nguyentm83/docker@v1.5.0/daemon/top.go (about)

     1  package daemon
     2  
     3  import (
     4  	"os/exec"
     5  	"strconv"
     6  	"strings"
     7  
     8  	"github.com/docker/docker/engine"
     9  )
    10  
    11  func (daemon *Daemon) ContainerTop(job *engine.Job) engine.Status {
    12  	if len(job.Args) != 1 && len(job.Args) != 2 {
    13  		return job.Errorf("Not enough arguments. Usage: %s CONTAINER [PS_ARGS]\n", job.Name)
    14  	}
    15  	var (
    16  		name   = job.Args[0]
    17  		psArgs = "-ef"
    18  	)
    19  
    20  	if len(job.Args) == 2 && job.Args[1] != "" {
    21  		psArgs = job.Args[1]
    22  	}
    23  
    24  	if container := daemon.Get(name); container != nil {
    25  		if !container.IsRunning() {
    26  			return job.Errorf("Container %s is not running", name)
    27  		}
    28  		pids, err := daemon.ExecutionDriver().GetPidsForContainer(container.ID)
    29  		if err != nil {
    30  			return job.Error(err)
    31  		}
    32  		output, err := exec.Command("ps", strings.Split(psArgs, " ")...).Output()
    33  		if err != nil {
    34  			return job.Errorf("Error running ps: %s", err)
    35  		}
    36  
    37  		lines := strings.Split(string(output), "\n")
    38  		header := strings.Fields(lines[0])
    39  		out := &engine.Env{}
    40  		out.SetList("Titles", header)
    41  
    42  		pidIndex := -1
    43  		for i, name := range header {
    44  			if name == "PID" {
    45  				pidIndex = i
    46  			}
    47  		}
    48  		if pidIndex == -1 {
    49  			return job.Errorf("Couldn't find PID field in ps output")
    50  		}
    51  
    52  		processes := [][]string{}
    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 job.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(header)-1]
    68  					process = append(process, strings.Join(fields[len(header)-1:], " "))
    69  					processes = append(processes, process)
    70  				}
    71  			}
    72  		}
    73  		out.SetJson("Processes", processes)
    74  		out.WriteTo(job.Stdout)
    75  		return engine.StatusOK
    76  
    77  	}
    78  	return job.Errorf("No such container: %s", name)
    79  }