daemon/top_windows.go
4f0d95fa
 package daemon // import "github.com/docker/docker/daemon"
0a9ec218
 
 import (
ddae20c0
 	"context"
52237787
 	"errors"
52f04748
 	"fmt"
 	"time"
a793564b
 
16bdbaaa
 	containertypes "github.com/docker/docker/api/types/container"
07ff4f1d
 	units "github.com/docker/go-units"
0a9ec218
 )
 
52f04748
 // ContainerTop handles `docker top` client requests.
 // Future considerations:
 // -- Windows users are far more familiar with CPU% total.
 //    Further, users on Windows rarely see user/kernel CPU stats split.
 //    The kernel returns everything in terms of 100ns. To obtain
 //    CPU%, we could do something like docker stats does which takes two
 //    samples, subtract the difference and do the maths. Unfortunately this
 //    would slow the stat call down and require two kernel calls. So instead,
 //    we do something similar to linux and display the CPU as combined HH:MM:SS.mmm.
 // -- Perhaps we could add an argument to display "raw" stats
 // -- "Memory" is an extremely overloaded term in Windows. Hence we do what
 //    task manager does and use the private working set as the memory counter.
 //    We could return more info for those who really understand how memory
 //    management works in Windows if we introduced a "raw" stats (above).
16bdbaaa
 func (daemon *Daemon) ContainerTop(name string, psArgs string) (*containertypes.ContainerTopOKBody, error) {
52f04748
 	// It's not at all an equivalent to linux 'ps' on Windows
52237787
 	if psArgs != "" {
 		return nil, errors.New("Windows does not support arguments to top")
 	}
 
52f04748
 	container, err := daemon.GetContainer(name)
52237787
 	if err != nil {
 		return nil, err
 	}
 
ddae20c0
 	if !container.IsRunning() {
 		return nil, errNotRunning(container.ID)
 	}
 
 	if container.IsRestarting() {
 		return nil, errContainerIsRestarting(container.ID)
 	}
 
 	s, err := daemon.containerd.Summary(context.Background(), container.ID)
52f04748
 	if err != nil {
 		return nil, err
 	}
16bdbaaa
 	procList := &containertypes.ContainerTopOKBody{}
52f04748
 	procList.Titles = []string{"Name", "PID", "CPU", "Private Working Set"}
52237787
 
52f04748
 	for _, j := range s {
2f273328
 		d := time.Duration((j.KernelTime_100Ns + j.UserTime_100Ns) * 100) // Combined time in nanoseconds
52f04748
 		procList.Processes = append(procList.Processes, []string{
 			j.ImageName,
2f273328
 			fmt.Sprint(j.ProcessID),
52f04748
 			fmt.Sprintf("%02d:%02d:%02d.%03d", int(d.Hours()), int(d.Minutes())%60, int(d.Seconds())%60, int(d.Nanoseconds()/1000000)%1000),
 			units.HumanSize(float64(j.MemoryWorkingSetPrivateBytes))})
52237787
 	}
ddae20c0
 
52237787
 	return procList, nil
0a9ec218
 }