github.com/chenchun/docker@v1.3.2-0.20150629222414-20467faf132b/daemon/stats.go (about)

     1  package daemon
     2  
     3  import (
     4  	"encoding/json"
     5  	"io"
     6  
     7  	"github.com/docker/docker/api/types"
     8  	"github.com/docker/docker/daemon/execdriver"
     9  )
    10  
    11  type ContainerStatsConfig struct {
    12  	Stream    bool
    13  	OutStream io.Writer
    14  	Stop      <-chan bool
    15  }
    16  
    17  func (daemon *Daemon) ContainerStats(name string, config *ContainerStatsConfig) error {
    18  	updates, err := daemon.SubscribeToContainerStats(name)
    19  	if err != nil {
    20  		return err
    21  	}
    22  
    23  	if config.Stream {
    24  		config.OutStream.Write(nil)
    25  	}
    26  
    27  	var preCpuStats types.CpuStats
    28  	getStat := func(v interface{}) *types.Stats {
    29  		update := v.(*execdriver.ResourceStats)
    30  		ss := convertStatsToAPITypes(update.Stats)
    31  		ss.PreCpuStats = preCpuStats
    32  		ss.MemoryStats.Limit = uint64(update.MemoryLimit)
    33  		ss.Read = update.Read
    34  		ss.CpuStats.SystemUsage = update.SystemUsage
    35  		preCpuStats = ss.CpuStats
    36  		return ss
    37  	}
    38  
    39  	enc := json.NewEncoder(config.OutStream)
    40  
    41  	defer daemon.UnsubscribeToContainerStats(name, updates)
    42  
    43  	noStreamFirstFrame := true
    44  	for {
    45  		select {
    46  		case v, ok := <-updates:
    47  			if !ok {
    48  				return nil
    49  			}
    50  
    51  			s := getStat(v)
    52  			if !config.Stream && noStreamFirstFrame {
    53  				// prime the cpu stats so they aren't 0 in the final output
    54  				noStreamFirstFrame = false
    55  				continue
    56  			}
    57  
    58  			if err := enc.Encode(s); err != nil {
    59  				return err
    60  			}
    61  
    62  			if !config.Stream {
    63  				return nil
    64  			}
    65  		case <-config.Stop:
    66  			return nil
    67  		}
    68  	}
    69  }