| 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 |
| } |