github.com/uppal0016/docker_new@v0.0.0-20240123060250-1c98be13ac2c/daemon/stats.go (about) 1 package daemon 2 3 import ( 4 "encoding/json" 5 "errors" 6 "runtime" 7 8 "golang.org/x/net/context" 9 10 "github.com/docker/docker/api/types/backend" 11 "github.com/docker/docker/pkg/ioutils" 12 "github.com/docker/docker/pkg/version" 13 "github.com/docker/engine-api/types" 14 "github.com/docker/engine-api/types/versions/v1p20" 15 ) 16 17 // ContainerStats writes information about the container to the stream 18 // given in the config object. 19 func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, config *backend.ContainerStatsConfig) error { 20 if runtime.GOOS == "windows" { 21 return errors.New("Windows does not support stats") 22 } 23 // Remote API version (used for backwards compatibility) 24 apiVersion := version.Version(config.Version) 25 26 container, err := daemon.GetContainer(prefixOrName) 27 if err != nil { 28 return err 29 } 30 31 // If the container is not running and requires no stream, return an empty stats. 32 if !container.IsRunning() && !config.Stream { 33 return json.NewEncoder(config.OutStream).Encode(&types.Stats{}) 34 } 35 36 outStream := config.OutStream 37 if config.Stream { 38 wf := ioutils.NewWriteFlusher(outStream) 39 defer wf.Close() 40 wf.Flush() 41 outStream = wf 42 } 43 44 var preCPUStats types.CPUStats 45 getStatJSON := func(v interface{}) *types.StatsJSON { 46 ss := v.(*types.StatsJSON) 47 ss.PreCPUStats = preCPUStats 48 // ss.MemoryStats.Limit = uint64(update.MemoryLimit) 49 preCPUStats = ss.CPUStats 50 return ss 51 } 52 53 enc := json.NewEncoder(outStream) 54 55 updates := daemon.subscribeToContainerStats(container) 56 defer daemon.unsubscribeToContainerStats(container, updates) 57 58 noStreamFirstFrame := true 59 for { 60 select { 61 case v, ok := <-updates: 62 if !ok { 63 return nil 64 } 65 66 var statsJSON interface{} 67 statsJSONPost120 := getStatJSON(v) 68 if apiVersion.LessThan("1.21") { 69 var ( 70 rxBytes uint64 71 rxPackets uint64 72 rxErrors uint64 73 rxDropped uint64 74 txBytes uint64 75 txPackets uint64 76 txErrors uint64 77 txDropped uint64 78 ) 79 for _, v := range statsJSONPost120.Networks { 80 rxBytes += v.RxBytes 81 rxPackets += v.RxPackets 82 rxErrors += v.RxErrors 83 rxDropped += v.RxDropped 84 txBytes += v.TxBytes 85 txPackets += v.TxPackets 86 txErrors += v.TxErrors 87 txDropped += v.TxDropped 88 } 89 statsJSON = &v1p20.StatsJSON{ 90 Stats: statsJSONPost120.Stats, 91 Network: types.NetworkStats{ 92 RxBytes: rxBytes, 93 RxPackets: rxPackets, 94 RxErrors: rxErrors, 95 RxDropped: rxDropped, 96 TxBytes: txBytes, 97 TxPackets: txPackets, 98 TxErrors: txErrors, 99 TxDropped: txDropped, 100 }, 101 } 102 } else { 103 statsJSON = statsJSONPost120 104 } 105 106 if !config.Stream && noStreamFirstFrame { 107 // prime the cpu stats so they aren't 0 in the final output 108 noStreamFirstFrame = false 109 continue 110 } 111 112 if err := enc.Encode(statsJSON); err != nil { 113 return err 114 } 115 116 if !config.Stream { 117 return nil 118 } 119 case <-ctx.Done(): 120 return nil 121 } 122 } 123 }