Implement docker stats with standalone client lib.

Signed-off-by: David Calavera <david.calavera@gmail.com>
This commit is contained in:
David Calavera 2015-12-06 02:34:23 -05:00
parent 3f9f23114f
commit e59d54bd99
3 changed files with 33 additions and 22 deletions

View File

@ -33,6 +33,7 @@ type apiClient interface {
ContainerRename(containerID, newContainerName string) error ContainerRename(containerID, newContainerName string) error
ContainerRestart(containerID string, timeout int) error ContainerRestart(containerID string, timeout int) error
ContainerStatPath(containerID, path string) (types.ContainerPathStat, error) ContainerStatPath(containerID, path string) (types.ContainerPathStat, error)
ContainerStats(containerID string, stream bool) (io.ReadCloser, error)
ContainerStart(containerID string) error ContainerStart(containerID string) error
ContainerStop(containerID string, timeout int) error ContainerStop(containerID string, timeout int) error
ContainerTop(containerID string, arguments []string) (types.ContainerProcessList, error) ContainerTop(containerID string, arguments []string) (types.ContainerProcessList, error)

View File

@ -0,0 +1,22 @@
package lib
import (
"io"
"net/url"
)
// ContainerStats returns near realtime stats for a given container.
// It's up to the caller to close the io.ReadCloser returned.
func (cli *Client) ContainerStats(containerID string, stream bool) (io.ReadCloser, error) {
query := url.Values{}
query.Set("stream", "0")
if stream {
query.Set("stream", "1")
}
resp, err := cli.get("/containers/"+containerID+"/stats", query, nil)
if err != nil {
return nil, err
}
return resp.body, err
}

View File

@ -4,7 +4,6 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"net/url"
"sort" "sort"
"strings" "strings"
"sync" "sync"
@ -37,26 +36,19 @@ type stats struct {
} }
func (s *containerStats) Collect(cli *DockerCli, streamStats bool) { func (s *containerStats) Collect(cli *DockerCli, streamStats bool) {
v := url.Values{} responseBody, err := cli.client.ContainerStats(s.Name, streamStats)
if streamStats {
v.Set("stream", "1")
} else {
v.Set("stream", "0")
}
serverResp, err := cli.call("GET", "/containers/"+s.Name+"/stats?"+v.Encode(), nil, nil)
if err != nil { if err != nil {
s.mu.Lock() s.mu.Lock()
s.err = err s.err = err
s.mu.Unlock() s.mu.Unlock()
return return
} }
defer responseBody.Close()
defer serverResp.body.Close()
var ( var (
previousCPU uint64 previousCPU uint64
previousSystem uint64 previousSystem uint64
dec = json.NewDecoder(serverResp.body) dec = json.NewDecoder(responseBody)
u = make(chan error, 1) u = make(chan error, 1)
) )
go func() { go func() {
@ -156,18 +148,13 @@ func (cli *DockerCli) CmdStats(args ...string) error {
showAll := len(names) == 0 showAll := len(names) == 0
if showAll { if showAll {
v := url.Values{} options := types.ContainerListOptions{
if *all { All: *all,
v.Set("all", "1")
} }
body, _, err := readBody(cli.call("GET", "/containers/json?"+v.Encode(), nil, nil)) cs, err := cli.client.ContainerList(options)
if err != nil { if err != nil {
return err return err
} }
var cs []types.Container
if err := json.Unmarshal(body, &cs); err != nil {
return err
}
for _, c := range cs { for _, c := range cs {
names = append(names, c.ID[:12]) names = append(names, c.ID[:12])
} }
@ -202,14 +189,15 @@ func (cli *DockerCli) CmdStats(args ...string) error {
err error err error
} }
getNewContainers := func(c chan<- watch) { getNewContainers := func(c chan<- watch) {
res, err := cli.call("GET", "/events", nil, nil) options := types.EventsOptions{}
resBody, err := cli.client.Events(options)
if err != nil { if err != nil {
c <- watch{err: err} c <- watch{err: err}
return return
} }
defer res.body.Close() defer resBody.Close()
dec := json.NewDecoder(res.body) dec := json.NewDecoder(resBody)
for { for {
var j *jsonmessage.JSONMessage var j *jsonmessage.JSONMessage
if err := dec.Decode(&j); err != nil { if err := dec.Decode(&j); err != nil {