github.com/vieux/docker@v0.6.3-0.20161004191708-e097c2a938c7/cli/command/formatter/stats.go (about)

     1  package formatter
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  
     7  	"github.com/docker/go-units"
     8  )
     9  
    10  const (
    11  	defaultStatsTableFormat    = "table {{.Container}}\t{{.CPUPrec}}\t{{.MemUsage}}\t{{.MemPrec}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDs}}"
    12  	winDefaultStatsTableFormat = "table {{.Container}}\t{{.CPUPrec}}\t{{{.MemUsage}}\t{.NetIO}}\t{{.BlockIO}}"
    13  	emptyStatsTableFormat      = "Waiting for statistics..."
    14  
    15  	containerHeader  = "CONTAINER"
    16  	cpuPrecHeader    = "CPU %"
    17  	netIOHeader      = "NET I/O"
    18  	blockIOHeader    = "BLOCK I/O"
    19  	winMemPrecHeader = "PRIV WORKING SET"  // Used only on Window
    20  	memPrecHeader    = "MEM %"             // Used only on Linux
    21  	memUseHeader     = "MEM USAGE / LIMIT" // Used only on Linux
    22  	pidsHeader       = "PIDS"              // Used only on Linux
    23  )
    24  
    25  // ContainerStatsAttrs represents the statistics data collected from a container.
    26  type ContainerStatsAttrs struct {
    27  	Windows          bool
    28  	Name             string
    29  	CPUPercentage    float64
    30  	Memory           float64 // On Windows this is the private working set
    31  	MemoryLimit      float64 // Not used on Windows
    32  	MemoryPercentage float64 // Not used on Windows
    33  	NetworkRx        float64
    34  	NetworkTx        float64
    35  	BlockRead        float64
    36  	BlockWrite       float64
    37  	PidsCurrent      uint64 // Not used on Windows
    38  }
    39  
    40  // ContainerStats represents the containers statistics data.
    41  type ContainerStats struct {
    42  	Mu sync.RWMutex
    43  	ContainerStatsAttrs
    44  	Err error
    45  }
    46  
    47  // NewStatsFormat returns a format for rendering an CStatsContext
    48  func NewStatsFormat(source, osType string) Format {
    49  	if source == TableFormatKey {
    50  		if osType == "windows" {
    51  			return Format(winDefaultStatsTableFormat)
    52  		}
    53  		return Format(defaultStatsTableFormat)
    54  	}
    55  	return Format(source)
    56  }
    57  
    58  // NewContainerStats returns a new ContainerStats entity and sets in it the given name
    59  func NewContainerStats(name, osType string) *ContainerStats {
    60  	return &ContainerStats{
    61  		ContainerStatsAttrs: ContainerStatsAttrs{
    62  			Name:    name,
    63  			Windows: (osType == "windows"),
    64  		},
    65  	}
    66  }
    67  
    68  // ContainerStatsWrite renders the context for a list of containers statistics
    69  func ContainerStatsWrite(ctx Context, containerStats []*ContainerStats) error {
    70  	render := func(format func(subContext subContext) error) error {
    71  		for _, cstats := range containerStats {
    72  			cstats.Mu.RLock()
    73  			cstatsAttrs := cstats.ContainerStatsAttrs
    74  			cstats.Mu.RUnlock()
    75  			containerStatsCtx := &containerStatsContext{
    76  				s: cstatsAttrs,
    77  			}
    78  			if err := format(containerStatsCtx); err != nil {
    79  				return err
    80  			}
    81  		}
    82  		return nil
    83  	}
    84  	return ctx.Write(&containerStatsContext{}, render)
    85  }
    86  
    87  type containerStatsContext struct {
    88  	HeaderContext
    89  	s ContainerStatsAttrs
    90  }
    91  
    92  func (c *containerStatsContext) Container() string {
    93  	c.AddHeader(containerHeader)
    94  	return c.s.Name
    95  }
    96  
    97  func (c *containerStatsContext) CPUPrec() string {
    98  	c.AddHeader(cpuPrecHeader)
    99  	return fmt.Sprintf("%.2f%%", c.s.CPUPercentage)
   100  }
   101  
   102  func (c *containerStatsContext) MemUsage() string {
   103  	c.AddHeader(memUseHeader)
   104  	if !c.s.Windows {
   105  		return fmt.Sprintf("%s / %s", units.BytesSize(c.s.Memory), units.BytesSize(c.s.MemoryLimit))
   106  	}
   107  	return fmt.Sprintf("-- / --")
   108  }
   109  
   110  func (c *containerStatsContext) MemPrec() string {
   111  	header := memPrecHeader
   112  	if c.s.Windows {
   113  		header = winMemPrecHeader
   114  	}
   115  	c.AddHeader(header)
   116  	return fmt.Sprintf("%.2f%%", c.s.MemoryPercentage)
   117  }
   118  
   119  func (c *containerStatsContext) NetIO() string {
   120  	c.AddHeader(netIOHeader)
   121  	return fmt.Sprintf("%s / %s", units.HumanSizeWithPrecision(c.s.NetworkRx, 3), units.HumanSizeWithPrecision(c.s.NetworkTx, 3))
   122  }
   123  
   124  func (c *containerStatsContext) BlockIO() string {
   125  	c.AddHeader(blockIOHeader)
   126  	return fmt.Sprintf("%s / %s", units.HumanSizeWithPrecision(c.s.BlockRead, 3), units.HumanSizeWithPrecision(c.s.BlockWrite, 3))
   127  }
   128  
   129  func (c *containerStatsContext) PIDs() string {
   130  	c.AddHeader(pidsHeader)
   131  	if !c.s.Windows {
   132  		return fmt.Sprintf("%d", c.s.PidsCurrent)
   133  	}
   134  	return fmt.Sprintf("-")
   135  }