Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
| ... | ... |
@@ -2687,7 +2687,7 @@ func (s *containerStats) Display(w io.Writer) {
|
| 2687 | 2687 |
} |
| 2688 | 2688 |
|
| 2689 | 2689 |
func (cli *DockerCli) CmdStats(args ...string) error {
|
| 2690 |
- cmd := cli.Subcmd("stats", "CONTAINER", "Stream the stats of a container", true)
|
|
| 2690 |
+ cmd := cli.Subcmd("stats", "CONTAINER", "Display live container stats based on resource usage", true)
|
|
| 2691 | 2691 |
cmd.Require(flag.Min, 1) |
| 2692 | 2692 |
utils.ParseFlags(cmd, args, true) |
| 2693 | 2693 |
|
| ... | ... |
@@ -98,7 +98,7 @@ func init() {
|
| 98 | 98 |
{"save", "Save an image to a tar archive"},
|
| 99 | 99 |
{"search", "Search for an image on the Docker Hub"},
|
| 100 | 100 |
{"start", "Start a stopped container"},
|
| 101 |
- {"stats", "Receive container stats"},
|
|
| 101 |
+ {"stats", "Display live container stats based on resource usage"},
|
|
| 102 | 102 |
{"stop", "Stop a running container"},
|
| 103 | 103 |
{"tag", "Tag an image into a repository"},
|
| 104 | 104 |
{"top", "Lookup the running processes of a container"},
|
| 105 | 105 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,32 @@ |
| 0 |
+% DOCKER(1) Docker User Manuals |
|
| 1 |
+% Docker Community |
|
| 2 |
+% JUNE 2014 |
|
| 3 |
+# NAME |
|
| 4 |
+docker-stats - Display live container stats based on resource usage. |
|
| 5 |
+ |
|
| 6 |
+# SYNOPSIS |
|
| 7 |
+**docker top** |
|
| 8 |
+[**--help**] |
|
| 9 |
+[CONTAINERS] |
|
| 10 |
+ |
|
| 11 |
+# DESCRIPTION |
|
| 12 |
+ |
|
| 13 |
+Display live container stats based on resource usage. |
|
| 14 |
+ |
|
| 15 |
+# OPTIONS |
|
| 16 |
+**--help** |
|
| 17 |
+ Print usage statement |
|
| 18 |
+ |
|
| 19 |
+# EXAMPLES |
|
| 20 |
+ |
|
| 21 |
+Run **docker stats** with multiple containers. |
|
| 22 |
+ |
|
| 23 |
+ $ sudo docker stats redis1 redis2 |
|
| 24 |
+ CONTAINER CPU % MEM USAGE/LIMIT MEM % NET I/O |
|
| 25 |
+ redis1 0.07% 796 KiB/64 MiB 1.21% 788 B/648 B |
|
| 26 |
+ redis2 0.07% 2.746 MiB/64 MiB 4.29% 1.266 KiB/648 B |
|
| 27 |
+ |
|
| 28 |
+# HISTORY |
|
| 29 |
+April 2014, Originally compiled by William Henry (whenry at redhat dot com) |
|
| 30 |
+based on docker.com source material and internal work. |
|
| 31 |
+June 2014, updated by Sven Dowideit <SvenDowideit@home.org.au> |
| ... | ... |
@@ -68,6 +68,12 @@ New endpoint to rename a container `id` to a new name. |
| 68 | 68 |
(`ReadonlyRootfs`) can be passed in the host config to mount the container's |
| 69 | 69 |
root filesystem as read only. |
| 70 | 70 |
|
| 71 |
+`GET /containers/(id)/stats` |
|
| 72 |
+ |
|
| 73 |
+**New!** |
|
| 74 |
+This endpoint returns a stream of container stats based on resource usage. |
|
| 75 |
+ |
|
| 76 |
+ |
|
| 71 | 77 |
## v1.16 |
| 72 | 78 |
|
| 73 | 79 |
### Full Documentation |
| ... | ... |
@@ -514,6 +514,94 @@ Status Codes: |
| 514 | 514 |
- **404** – no such container |
| 515 | 515 |
- **500** – server error |
| 516 | 516 |
|
| 517 |
+### Get container stats based on resource usage |
|
| 518 |
+ |
|
| 519 |
+`GET /containers/(id)/stats` |
|
| 520 |
+ |
|
| 521 |
+Returns a stream of json objects of the container's stats |
|
| 522 |
+ |
|
| 523 |
+**Example request**: |
|
| 524 |
+ |
|
| 525 |
+ GET /containers/redis1/stats HTTP/1.1 |
|
| 526 |
+ |
|
| 527 |
+**Example response**: |
|
| 528 |
+ |
|
| 529 |
+ HTTP/1.1 200 OK |
|
| 530 |
+ Content-Type: application/json |
|
| 531 |
+ |
|
| 532 |
+ {
|
|
| 533 |
+ "read" : "2015-01-08T22:57:31.547920715Z", |
|
| 534 |
+ "network" : {
|
|
| 535 |
+ "rx_dropped" : 0, |
|
| 536 |
+ "rx_bytes" : 648, |
|
| 537 |
+ "rx_errors" : 0, |
|
| 538 |
+ "tx_packets" : 8, |
|
| 539 |
+ "tx_dropped" : 0, |
|
| 540 |
+ "rx_packets" : 8, |
|
| 541 |
+ "tx_errors" : 0, |
|
| 542 |
+ "tx_bytes" : 648 |
|
| 543 |
+ }, |
|
| 544 |
+ "memory_stats" : {
|
|
| 545 |
+ "stats" : {
|
|
| 546 |
+ "total_pgmajfault" : 0, |
|
| 547 |
+ "cache" : 0, |
|
| 548 |
+ "mapped_file" : 0, |
|
| 549 |
+ "total_inactive_file" : 0, |
|
| 550 |
+ "pgpgout" : 414, |
|
| 551 |
+ "rss" : 6537216, |
|
| 552 |
+ "total_mapped_file" : 0, |
|
| 553 |
+ "writeback" : 0, |
|
| 554 |
+ "unevictable" : 0, |
|
| 555 |
+ "pgpgin" : 477, |
|
| 556 |
+ "total_unevictable" : 0, |
|
| 557 |
+ "pgmajfault" : 0, |
|
| 558 |
+ "total_rss" : 6537216, |
|
| 559 |
+ "total_rss_huge" : 6291456, |
|
| 560 |
+ "total_writeback" : 0, |
|
| 561 |
+ "total_inactive_anon" : 0, |
|
| 562 |
+ "rss_huge" : 6291456, |
|
| 563 |
+ "hierarchical_memory_limit" : 67108864, |
|
| 564 |
+ "total_pgfault" : 964, |
|
| 565 |
+ "total_active_file" : 0, |
|
| 566 |
+ "active_anon" : 6537216, |
|
| 567 |
+ "total_active_anon" : 6537216, |
|
| 568 |
+ "total_pgpgout" : 414, |
|
| 569 |
+ "total_cache" : 0, |
|
| 570 |
+ "inactive_anon" : 0, |
|
| 571 |
+ "active_file" : 0, |
|
| 572 |
+ "pgfault" : 964, |
|
| 573 |
+ "inactive_file" : 0, |
|
| 574 |
+ "total_pgpgin" : 477 |
|
| 575 |
+ }, |
|
| 576 |
+ "max_usage" : 6651904, |
|
| 577 |
+ "usage" : 6537216, |
|
| 578 |
+ "failcnt" : 0, |
|
| 579 |
+ "limit" : 67108864 |
|
| 580 |
+ }, |
|
| 581 |
+ "blkio_stats" : {},
|
|
| 582 |
+ "cpu_stats" : {
|
|
| 583 |
+ "cpu_usage" : {
|
|
| 584 |
+ "percpu_usage" : [ |
|
| 585 |
+ 16970827, |
|
| 586 |
+ 1839451, |
|
| 587 |
+ 7107380, |
|
| 588 |
+ 10571290 |
|
| 589 |
+ ], |
|
| 590 |
+ "usage_in_usermode" : 10000000, |
|
| 591 |
+ "total_usage" : 36488948, |
|
| 592 |
+ "usage_in_kernelmode" : 20000000 |
|
| 593 |
+ }, |
|
| 594 |
+ "system_cpu_usage" : 20091722000000000, |
|
| 595 |
+ "throttling_data" : {}
|
|
| 596 |
+ } |
|
| 597 |
+ } |
|
| 598 |
+ |
|
| 599 |
+Status Codes: |
|
| 600 |
+ |
|
| 601 |
+- **200** – no error |
|
| 602 |
+- **404** – no such container |
|
| 603 |
+- **500** – server error |
|
| 604 |
+ |
|
| 517 | 605 |
### Resize a container TTY |
| 518 | 606 |
|
| 519 | 607 |
`POST /containers/(id)/resize?h=<height>&w=<width>` |
| ... | ... |
@@ -2001,8 +2001,28 @@ more details on finding shared images from the command line. |
| 2001 | 2001 |
-a, --attach=false Attach container's STDOUT and STDERR and forward all signals to the process |
| 2002 | 2002 |
-i, --interactive=false Attach container's STDIN |
| 2003 | 2003 |
|
| 2004 |
-When run on a container that has already been started, |
|
| 2005 |
-takes no action and succeeds unconditionally. |
|
| 2004 |
+## stats |
|
| 2005 |
+ |
|
| 2006 |
+ Usage: docker stats [CONTAINERS] |
|
| 2007 |
+ |
|
| 2008 |
+ Display live container stats based on resource usage |
|
| 2009 |
+ |
|
| 2010 |
+ --help=false Print usage |
|
| 2011 |
+ |
|
| 2012 |
+Running `docker stats` on two redis containers |
|
| 2013 |
+ |
|
| 2014 |
+ $ sudo docker stats redis1 redis2 |
|
| 2015 |
+ CONTAINER CPU % MEM USAGE/LIMIT MEM % NET I/O |
|
| 2016 |
+ redis1 0.07% 796 KiB/64 MiB 1.21% 788 B/648 B |
|
| 2017 |
+ redis2 0.07% 2.746 MiB/64 MiB 4.29% 1.266 KiB/648 B |
|
| 2018 |
+ |
|
| 2019 |
+ |
|
| 2020 |
+When run on running containers live container stats will be streamed |
|
| 2021 |
+back and displayed to the client. Stopped containers will not |
|
| 2022 |
+receive any updates to their stats unless the container is started again. |
|
| 2023 |
+ |
|
| 2024 |
+> **Note:** |
|
| 2025 |
+> If you want more in depth resource usage for a container use the API endpoint |
|
| 2006 | 2026 |
|
| 2007 | 2027 |
## stop |
| 2008 | 2028 |
|
| ... | ... |
@@ -9,7 +9,9 @@ import ( |
| 9 | 9 |
"os/exec" |
| 10 | 10 |
"strings" |
| 11 | 11 |
"testing" |
| 12 |
+ "time" |
|
| 12 | 13 |
|
| 14 |
+ "github.com/docker/docker/api/stats" |
|
| 13 | 15 |
"github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar" |
| 14 | 16 |
) |
| 15 | 17 |
|
| ... | ... |
@@ -251,3 +253,31 @@ func TestVolumesFromHasPriority(t *testing.T) {
|
| 251 | 251 |
|
| 252 | 252 |
logDone("container REST API - check VolumesFrom has priority")
|
| 253 | 253 |
} |
| 254 |
+ |
|
| 255 |
+func TestGetContainerStats(t *testing.T) {
|
|
| 256 |
+ defer deleteAllContainers() |
|
| 257 |
+ name := "statscontainer" |
|
| 258 |
+ |
|
| 259 |
+ runCmd := exec.Command(dockerBinary, "run", "-d", "--name", name, "busybox", "top") |
|
| 260 |
+ out, _, err := runCommandWithOutput(runCmd) |
|
| 261 |
+ if err != nil {
|
|
| 262 |
+ t.Fatalf("Error on container creation: %v, output: %q", err, out)
|
|
| 263 |
+ } |
|
| 264 |
+ go func() {
|
|
| 265 |
+ time.Sleep(4 * time.Second) |
|
| 266 |
+ runCommand(exec.Command(dockerBinary, "kill", name)) |
|
| 267 |
+ runCommand(exec.Command(dockerBinary, "rm", name)) |
|
| 268 |
+ }() |
|
| 269 |
+ |
|
| 270 |
+ body, err := sockRequest("GET", "/containers/"+name+"/stats", nil)
|
|
| 271 |
+ if err != nil {
|
|
| 272 |
+ t.Fatalf("GET containers/stats sockRequest failed: %v", err)
|
|
| 273 |
+ } |
|
| 274 |
+ |
|
| 275 |
+ var s *stats.Stats |
|
| 276 |
+ if err := json.Unmarshal(body, &s); err != nil {
|
|
| 277 |
+ t.Fatal(err) |
|
| 278 |
+ } |
|
| 279 |
+ |
|
| 280 |
+ logDone("container REST API - check GET containers/stats")
|
|
| 281 |
+} |