top_windows.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. package daemon
  2. import (
  3. "errors"
  4. "fmt"
  5. "time"
  6. containertypes "github.com/docker/docker/api/types/container"
  7. "github.com/docker/go-units"
  8. )
  9. // ContainerTop handles `docker top` client requests.
  10. // Future considerations:
  11. // -- Windows users are far more familiar with CPU% total.
  12. // Further, users on Windows rarely see user/kernel CPU stats split.
  13. // The kernel returns everything in terms of 100ns. To obtain
  14. // CPU%, we could do something like docker stats does which takes two
  15. // samples, subtract the difference and do the maths. Unfortunately this
  16. // would slow the stat call down and require two kernel calls. So instead,
  17. // we do something similar to linux and display the CPU as combined HH:MM:SS.mmm.
  18. // -- Perhaps we could add an argument to display "raw" stats
  19. // -- "Memory" is an extremely overloaded term in Windows. Hence we do what
  20. // task manager does and use the private working set as the memory counter.
  21. // We could return more info for those who really understand how memory
  22. // management works in Windows if we introduced a "raw" stats (above).
  23. func (daemon *Daemon) ContainerTop(name string, psArgs string) (*containertypes.ContainerTopOKBody, error) {
  24. // It's not at all an equivalent to linux 'ps' on Windows
  25. if psArgs != "" {
  26. return nil, errors.New("Windows does not support arguments to top")
  27. }
  28. container, err := daemon.GetContainer(name)
  29. if err != nil {
  30. return nil, err
  31. }
  32. s, err := daemon.containerd.Summary(container.ID)
  33. if err != nil {
  34. return nil, err
  35. }
  36. procList := &containertypes.ContainerTopOKBody{}
  37. procList.Titles = []string{"Name", "PID", "CPU", "Private Working Set"}
  38. for _, j := range s {
  39. d := time.Duration((j.KernelTime100ns + j.UserTime100ns) * 100) // Combined time in nanoseconds
  40. procList.Processes = append(procList.Processes, []string{
  41. j.ImageName,
  42. fmt.Sprint(j.ProcessId),
  43. fmt.Sprintf("%02d:%02d:%02d.%03d", int(d.Hours()), int(d.Minutes())%60, int(d.Seconds())%60, int(d.Nanoseconds()/1000000)%1000),
  44. units.HumanSize(float64(j.MemoryWorkingSetPrivateBytes))})
  45. }
  46. return procList, nil
  47. }