Browse code

Implement docker stats with standalone client lib.

Signed-off-by: David Calavera <david.calavera@gmail.com>

David Calavera authored on 2015/12/06 16:34:23
Showing 3 changed files
... ...
@@ -33,6 +33,7 @@ type apiClient interface {
33 33
 	ContainerRename(containerID, newContainerName string) error
34 34
 	ContainerRestart(containerID string, timeout int) error
35 35
 	ContainerStatPath(containerID, path string) (types.ContainerPathStat, error)
36
+	ContainerStats(containerID string, stream bool) (io.ReadCloser, error)
36 37
 	ContainerStart(containerID string) error
37 38
 	ContainerStop(containerID string, timeout int) error
38 39
 	ContainerTop(containerID string, arguments []string) (types.ContainerProcessList, error)
39 40
new file mode 100644
... ...
@@ -0,0 +1,22 @@
0
+package lib
1
+
2
+import (
3
+	"io"
4
+	"net/url"
5
+)
6
+
7
+// ContainerStats returns near realtime stats for a given container.
8
+// It's up to the caller to close the io.ReadCloser returned.
9
+func (cli *Client) ContainerStats(containerID string, stream bool) (io.ReadCloser, error) {
10
+	query := url.Values{}
11
+	query.Set("stream", "0")
12
+	if stream {
13
+		query.Set("stream", "1")
14
+	}
15
+
16
+	resp, err := cli.get("/containers/"+containerID+"/stats", query, nil)
17
+	if err != nil {
18
+		return nil, err
19
+	}
20
+	return resp.body, err
21
+}
... ...
@@ -4,7 +4,6 @@ import (
4 4
 	"encoding/json"
5 5
 	"fmt"
6 6
 	"io"
7
-	"net/url"
8 7
 	"sort"
9 8
 	"strings"
10 9
 	"sync"
... ...
@@ -37,26 +36,19 @@ type stats struct {
37 37
 }
38 38
 
39 39
 func (s *containerStats) Collect(cli *DockerCli, streamStats bool) {
40
-	v := url.Values{}
41
-	if streamStats {
42
-		v.Set("stream", "1")
43
-	} else {
44
-		v.Set("stream", "0")
45
-	}
46
-	serverResp, err := cli.call("GET", "/containers/"+s.Name+"/stats?"+v.Encode(), nil, nil)
40
+	responseBody, err := cli.client.ContainerStats(s.Name, streamStats)
47 41
 	if err != nil {
48 42
 		s.mu.Lock()
49 43
 		s.err = err
50 44
 		s.mu.Unlock()
51 45
 		return
52 46
 	}
53
-
54
-	defer serverResp.body.Close()
47
+	defer responseBody.Close()
55 48
 
56 49
 	var (
57 50
 		previousCPU    uint64
58 51
 		previousSystem uint64
59
-		dec            = json.NewDecoder(serverResp.body)
52
+		dec            = json.NewDecoder(responseBody)
60 53
 		u              = make(chan error, 1)
61 54
 	)
62 55
 	go func() {
... ...
@@ -156,18 +148,13 @@ func (cli *DockerCli) CmdStats(args ...string) error {
156 156
 	showAll := len(names) == 0
157 157
 
158 158
 	if showAll {
159
-		v := url.Values{}
160
-		if *all {
161
-			v.Set("all", "1")
159
+		options := types.ContainerListOptions{
160
+			All: *all,
162 161
 		}
163
-		body, _, err := readBody(cli.call("GET", "/containers/json?"+v.Encode(), nil, nil))
162
+		cs, err := cli.client.ContainerList(options)
164 163
 		if err != nil {
165 164
 			return err
166 165
 		}
167
-		var cs []types.Container
168
-		if err := json.Unmarshal(body, &cs); err != nil {
169
-			return err
170
-		}
171 166
 		for _, c := range cs {
172 167
 			names = append(names, c.ID[:12])
173 168
 		}
... ...
@@ -202,14 +189,15 @@ func (cli *DockerCli) CmdStats(args ...string) error {
202 202
 			err   error
203 203
 		}
204 204
 		getNewContainers := func(c chan<- watch) {
205
-			res, err := cli.call("GET", "/events", nil, nil)
205
+			options := types.EventsOptions{}
206
+			resBody, err := cli.client.Events(options)
206 207
 			if err != nil {
207 208
 				c <- watch{err: err}
208 209
 				return
209 210
 			}
210
-			defer res.body.Close()
211
+			defer resBody.Close()
211 212
 
212
-			dec := json.NewDecoder(res.body)
213
+			dec := json.NewDecoder(resBody)
213 214
 			for {
214 215
 				var j *jsonmessage.JSONMessage
215 216
 				if err := dec.Decode(&j); err != nil {