| package client | |
| import ( | |
| "context" | |
| "io" | |
| "net/url" | |
| ) | |
| // ContainerStatsOptions holds parameters to retrieve container statistics | |
| // using the [Client.ContainerStats] method. | |
| type ContainerStatsOptions struct { | |
| // Stream enables streaming [container.StatsResponse] results instead | |
| // of collecting a single sample. If enabled, the client remains attached | |
| // until the [ContainerStatsResult.Body] is closed or the context is | |
| // cancelled. | |
| Stream bool | |
| // IncludePreviousSample asks the daemon to collect a prior sample to populate the | |
| // [container.StatsResponse.PreRead] and [container.StatsResponse.PreCPUStats] | |
| // fields. | |
| // | |
| // It set, the daemon collects two samples at a one-second interval before | |
| // returning the result. The first sample populates the PreCPUStats (“previous | |
| // CPU”) field, allowing delta calculations for CPU usage. If false, only | |
| // a single sample is taken and returned immediately, leaving PreRead and | |
| // PreCPUStats empty. | |
| // | |
| // This option has no effect if Stream is enabled. If Stream is enabled, | |
| // [container.StatsResponse.PreCPUStats] is never populated for the first | |
| // record. | |
| IncludePreviousSample bool | |
| } | |
| // ContainerStatsResult holds the result from [Client.ContainerStats]. | |
| // | |
| // It wraps an [io.ReadCloser] that provides one or more [container.StatsResponse] | |
| // objects for a container, as produced by the "GET /containers/{id}/stats" endpoint. | |
| // If streaming is disabled, the stream contains a single record. | |
| type ContainerStatsResult struct { | |
| Body io.ReadCloser | |
| } | |
| // ContainerStats retrieves live resource usage statistics for the specified | |
| // container. The caller must close the [io.ReadCloser] in the returned result | |
| // to release associated resources. | |
| // | |
| // The underlying [io.ReadCloser] is automatically closed if the context is canceled, | |
| func (cli *Client) ContainerStats(ctx context.Context, containerID string, options ContainerStatsOptions) (ContainerStatsResult, error) { | |
| containerID, err := trimID("container", containerID) | |
| if err != nil { | |
| return ContainerStatsResult{}, err | |
| } | |
| query := url.Values{} | |
| if options.Stream { | |
| query.Set("stream", "true") | |
| } else { | |
| // Note: daemons before v29.0 return an error if both set: "cannot have stream=true and one-shot=true" | |
| // | |
| // TODO(thaJeztah): consider making "stream=false" the default for the API as well, or using Accept Header to switch. | |
| query.Set("stream", "false") | |
| if !options.IncludePreviousSample { | |
| query.Set("one-shot", "true") | |
| } | |
| } | |
| resp, err := cli.get(ctx, "/containers/"+containerID+"/stats", query, nil) | |
| if err != nil { | |
| return ContainerStatsResult{}, err | |
| } | |
| return ContainerStatsResult{ | |
| Body: newCancelReadCloser(ctx, resp.Body), | |
| }, nil | |
| } |