MCPcopy Index your code
hub / github.com/docker/cli / RunStats

Function RunStats

cli/command/container/stats.go:109–365  ·  view source on GitHub ↗

RunStats displays a live stream of resource usage statistics for one or more containers. This shows real-time information on CPU usage, memory usage, and network I/O. nolint:gocyclo

(ctx context.Context, dockerCLI command.Cli, options *StatsOptions)

Source from the content-addressed store, hash-verified

107//
108//nolint:gocyclo
109func RunStats(ctx context.Context, dockerCLI command.Cli, options *StatsOptions) error {
110 apiClient := dockerCLI.Client()
111
112 // Get the daemonOSType to handle platform-specific stats fields.
113 // This value is used as a fallback for docker < v29, which did not
114 // include the OSType field per stats.
115 daemonOSType = dockerCLI.ServerInfo().OSType
116
117 // waitFirst is a WaitGroup to wait first stat data's reach for each container
118 waitFirst := &sync.WaitGroup{}
119 // closeChan is used to collect errors from goroutines. It uses a small buffer
120 // to avoid blocking sends when sends occur after closeChan is set to nil or
121 // after the reader has exited, preventing deadlocks.
122 closeChan := make(chan error, 4)
123 cStats := stats{}
124
125 showAll := len(options.Containers) == 0
126 if showAll {
127 // If no names were specified, start a long-running goroutine which
128 // monitors container events. We make sure we're subscribed before
129 // retrieving the list of running containers to avoid a race where we
130 // would "miss" a creation.
131 started := make(chan struct{})
132
133 if options.Filters == nil {
134 options.Filters = make(client.Filters)
135 }
136
137 // FIXME(thaJeztah): any way we can (and should?) validate allowed filters?
138 for filter := range options.Filters {
139 if _, ok := acceptedStatsFilters[filter]; !ok {
140 return errdefs.ErrInvalidArgument.WithMessage("invalid filter '" + filter + "'")
141 }
142 }
143
144 eh := newEventHandler()
145 addEvents := []events.Action{events.ActionStart}
146 if options.All {
147 addEvents = append(addEvents, events.ActionCreate)
148 }
149 eh.setHandler(addEvents, func(ctx context.Context, e events.Message) {
150 if s := NewStats(e.Actor.ID); cStats.add(s) {
151 waitFirst.Add(1)
152 log.G(ctx).Debug("collecting stats for container")
153 go collect(ctx, s, apiClient, !options.NoStream, waitFirst)
154 }
155 })
156
157 // Remove containers when they are removed ("destroyed"); containers
158 // do not emit [events.ActionRemove], only [events.ActionDestroy].
159 //
160 // When running with "--all" we don't remove containers when they die,
161 // because they may come back, but without "--all" we remove them
162 // on the first possible occasion (either "die" or "destroy").
163 rmEvents := []events.Action{events.ActionDestroy}
164 if !options.All {
165 rmEvents = append(rmEvents, events.ActionDie)
166 }

Callers 1

newStatsCommandFunction · 0.85

Calls 15

addMethod · 0.95
removeMethod · 0.95
snapshotMethod · 0.95
newEventHandlerFunction · 0.85
NewStatsFunction · 0.85
collectFunction · 0.85
NewStatsFormatFunction · 0.85
statsFormatWriteFunction · 0.85
setHandlerMethod · 0.80
EventsMethod · 0.80
watchMethod · 0.80
GetErrorMethod · 0.80

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…