Kaynağa Gözat

Merge pull request #13443 from duglin/CleanupEvents

Cleanup container LogEvent calls
Alexander Morozov 10 yıl önce
ebeveyn
işleme
cd80a61cc1

+ 1 - 0
daemon/commit.go

@@ -61,5 +61,6 @@ func (daemon *Daemon) Commit(container *Container, repository, tag, comment, aut
 			return img, err
 			return img, err
 		}
 		}
 	}
 	}
+	container.LogEvent("commit")
 	return img, nil
 	return img, nil
 }
 }

+ 39 - 16
daemon/container.go

@@ -242,6 +242,7 @@ func (container *Container) Start() (err error) {
 			}
 			}
 			container.toDisk()
 			container.toDisk()
 			container.cleanup()
 			container.cleanup()
+			container.LogEvent("die")
 		}
 		}
 	}()
 	}()
 
 
@@ -375,7 +376,11 @@ func (container *Container) KillSig(sig int) error {
 		return nil
 		return nil
 	}
 	}
 
 
-	return container.daemon.Kill(container, sig)
+	if err := container.daemon.Kill(container, sig); err != nil {
+		return err
+	}
+	container.LogEvent("kill")
+	return nil
 }
 }
 
 
 // Wrapper aroung KillSig() suppressing "no such process" error.
 // Wrapper aroung KillSig() suppressing "no such process" error.
@@ -406,6 +411,7 @@ func (container *Container) Pause() error {
 		return err
 		return err
 	}
 	}
 	container.Paused = true
 	container.Paused = true
+	container.LogEvent("pause")
 	return nil
 	return nil
 }
 }
 
 
@@ -427,6 +433,7 @@ func (container *Container) Unpause() error {
 		return err
 		return err
 	}
 	}
 	container.Paused = false
 	container.Paused = false
+	container.LogEvent("unpause")
 	return nil
 	return nil
 }
 }
 
 
@@ -488,6 +495,7 @@ func (container *Container) Stop(seconds int) error {
 		}
 		}
 	}
 	}
 
 
+	container.LogEvent("stop")
 	return nil
 	return nil
 }
 }
 
 
@@ -502,14 +510,24 @@ func (container *Container) Restart(seconds int) error {
 	if err := container.Stop(seconds); err != nil {
 	if err := container.Stop(seconds); err != nil {
 		return err
 		return err
 	}
 	}
-	return container.Start()
+
+	if err := container.Start(); err != nil {
+		return err
+	}
+
+	container.LogEvent("restart")
+	return nil
 }
 }
 
 
 func (container *Container) Resize(h, w int) error {
 func (container *Container) Resize(h, w int) error {
 	if !container.IsRunning() {
 	if !container.IsRunning() {
 		return fmt.Errorf("Cannot resize container %s, container is not running", container.ID)
 		return fmt.Errorf("Cannot resize container %s, container is not running", container.ID)
 	}
 	}
-	return container.command.ProcessConfig.Terminal.Resize(h, w)
+	if err := container.command.ProcessConfig.Terminal.Resize(h, w); err != nil {
+		return err
+	}
+	container.LogEvent("resize")
+	return nil
 }
 }
 
 
 func (container *Container) Export() (archive.Archive, error) {
 func (container *Container) Export() (archive.Archive, error) {
@@ -522,12 +540,13 @@ func (container *Container) Export() (archive.Archive, error) {
 		container.Unmount()
 		container.Unmount()
 		return nil, err
 		return nil, err
 	}
 	}
-	return ioutils.NewReadCloserWrapper(archive, func() error {
-			err := archive.Close()
-			container.Unmount()
-			return err
-		}),
-		nil
+	arch := ioutils.NewReadCloserWrapper(archive, func() error {
+		err := archive.Close()
+		container.Unmount()
+		return err
+	})
+	container.LogEvent("export")
+	return arch, err
 }
 }
 
 
 func (container *Container) Mount() error {
 func (container *Container) Mount() error {
@@ -628,13 +647,14 @@ func (container *Container) Copy(resource string) (io.ReadCloser, error) {
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	return ioutils.NewReadCloserWrapper(archive, func() error {
-			err := archive.Close()
-			container.UnmountVolumes(true)
-			container.Unmount()
-			return err
-		}),
-		nil
+	reader := ioutils.NewReadCloserWrapper(archive, func() error {
+		err := archive.Close()
+		container.UnmountVolumes(true)
+		container.Unmount()
+		return err
+	})
+	container.LogEvent("copy")
+	return reader, nil
 }
 }
 
 
 // Returns true if the container exposes a certain port
 // Returns true if the container exposes a certain port
@@ -826,6 +846,7 @@ func (c *Container) Attach(stdin io.ReadCloser, stdout io.Writer, stderr io.Writ
 }
 }
 
 
 func (c *Container) AttachWithLogs(stdin io.ReadCloser, stdout, stderr io.Writer, logs, stream bool) error {
 func (c *Container) AttachWithLogs(stdin io.ReadCloser, stdout, stderr io.Writer, logs, stream bool) error {
+
 	if logs {
 	if logs {
 		logDriver, err := c.getLogger()
 		logDriver, err := c.getLogger()
 		cLog, err := logDriver.GetReader()
 		cLog, err := logDriver.GetReader()
@@ -855,6 +876,8 @@ func (c *Container) AttachWithLogs(stdin io.ReadCloser, stdout, stderr io.Writer
 		}
 		}
 	}
 	}
 
 
+	c.LogEvent("attach")
+
 	//stream
 	//stream
 	if stream {
 	if stream {
 		var stdinPipe io.ReadCloser
 		var stdinPipe io.ReadCloser

+ 1 - 1
daemon/create.go

@@ -39,7 +39,6 @@ func (daemon *Daemon) ContainerCreate(name string, config *runconfig.Config, hos
 		return "", warnings, err
 		return "", warnings, err
 	}
 	}
 
 
-	container.LogEvent("create")
 	warnings = append(warnings, buildWarnings...)
 	warnings = append(warnings, buildWarnings...)
 
 
 	return container.ID, warnings, nil
 	return container.ID, warnings, nil
@@ -142,6 +141,7 @@ func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.Hos
 	if err := container.ToDisk(); err != nil {
 	if err := container.ToDisk(); err != nil {
 		return nil, nil, err
 		return nil, nil, err
 	}
 	}
+	container.LogEvent("create")
 	return container, warnings, nil
 	return container, warnings, nil
 }
 }
 
 

+ 2 - 2
daemon/delete.go

@@ -48,8 +48,6 @@ func (daemon *Daemon) ContainerRm(name string, config *ContainerRmConfig) error
 		return fmt.Errorf("Cannot destroy container %s: %v", name, err)
 		return fmt.Errorf("Cannot destroy container %s: %v", name, err)
 	}
 	}
 
 
-	container.LogEvent("destroy")
-
 	if config.RemoveVolume {
 	if config.RemoveVolume {
 		container.removeMountPoints()
 		container.removeMountPoints()
 	}
 	}
@@ -102,6 +100,7 @@ func (daemon *Daemon) rm(container *Container, forceRemove bool) (err error) {
 			daemon.idIndex.Delete(container.ID)
 			daemon.idIndex.Delete(container.ID)
 			daemon.containers.Delete(container.ID)
 			daemon.containers.Delete(container.ID)
 			os.RemoveAll(container.root)
 			os.RemoveAll(container.root)
+			container.LogEvent("destroy")
 		}
 		}
 	}()
 	}()
 
 
@@ -130,6 +129,7 @@ func (daemon *Daemon) rm(container *Container, forceRemove bool) (err error) {
 	daemon.idIndex.Delete(container.ID)
 	daemon.idIndex.Delete(container.ID)
 	daemon.containers.Delete(container.ID)
 	daemon.containers.Delete(container.ID)
 
 
+	container.LogEvent("destroy")
 	return nil
 	return nil
 }
 }
 
 

+ 2 - 2
daemon/exec.go

@@ -141,10 +141,10 @@ func (d *Daemon) ContainerExecCreate(config *runconfig.ExecConfig) (string, erro
 		Running:       false,
 		Running:       false,
 	}
 	}
 
 
-	container.LogEvent("exec_create: " + execConfig.ProcessConfig.Entrypoint + " " + strings.Join(execConfig.ProcessConfig.Arguments, " "))
-
 	d.registerExecCommand(execConfig)
 	d.registerExecCommand(execConfig)
 
 
+	container.LogEvent("exec_create: " + execConfig.ProcessConfig.Entrypoint + " " + strings.Join(execConfig.ProcessConfig.Arguments, " "))
+
 	return execConfig.ID, nil
 	return execConfig.ID, nil
 
 
 }
 }

+ 0 - 2
daemon/export.go

@@ -21,7 +21,5 @@ func (daemon *Daemon) ContainerExport(name string, out io.Writer) error {
 	if _, err := io.Copy(out, data); err != nil {
 	if _, err := io.Copy(out, data); err != nil {
 		return fmt.Errorf("%s: %s", name, err)
 		return fmt.Errorf("%s: %s", name, err)
 	}
 	}
-	// FIXME: factor job-specific LogEvent to engine.Job.Run()
-	container.LogEvent("export")
 	return nil
 	return nil
 }
 }

+ 0 - 1
daemon/kill.go

@@ -26,6 +26,5 @@ func (daemon *Daemon) ContainerKill(name string, sig uint64) error {
 			return fmt.Errorf("Cannot kill container %s: %s", name, err)
 			return fmt.Errorf("Cannot kill container %s: %s", name, err)
 		}
 		}
 	}
 	}
-	container.LogEvent("kill")
 	return nil
 	return nil
 }
 }

+ 0 - 1
daemon/pause.go

@@ -12,7 +12,6 @@ func (daemon *Daemon) ContainerPause(name string) error {
 	if err := container.Pause(); err != nil {
 	if err := container.Pause(); err != nil {
 		return fmt.Errorf("Cannot pause container %s: %s", name, err)
 		return fmt.Errorf("Cannot pause container %s: %s", name, err)
 	}
 	}
-	container.LogEvent("pause")
 
 
 	return nil
 	return nil
 }
 }

+ 1 - 0
daemon/rename.go

@@ -40,5 +40,6 @@ func (daemon *Daemon) ContainerRename(oldName, newName string) error {
 		return err
 		return err
 	}
 	}
 
 
+	container.LogEvent("rename")
 	return nil
 	return nil
 }
 }

+ 0 - 1
daemon/restart.go

@@ -10,6 +10,5 @@ func (daemon *Daemon) ContainerRestart(name string, seconds int) error {
 	if err := container.Restart(seconds); err != nil {
 	if err := container.Restart(seconds); err != nil {
 		return fmt.Errorf("Cannot restart container %s: %s\n", name, err)
 		return fmt.Errorf("Cannot restart container %s: %s\n", name, err)
 	}
 	}
-	container.LogEvent("restart")
 	return nil
 	return nil
 }
 }

+ 0 - 1
daemon/start.go

@@ -33,7 +33,6 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *runconfig.HostConf
 	}
 	}
 
 
 	if err := container.Start(); err != nil {
 	if err := container.Start(); err != nil {
-		container.LogEvent("die")
 		return fmt.Errorf("Cannot start container %s: %s", name, err)
 		return fmt.Errorf("Cannot start container %s: %s", name, err)
 	}
 	}
 
 

+ 0 - 1
daemon/stop.go

@@ -13,6 +13,5 @@ func (daemon *Daemon) ContainerStop(name string, seconds int) error {
 	if err := container.Stop(seconds); err != nil {
 	if err := container.Stop(seconds); err != nil {
 		return fmt.Errorf("Cannot stop container %s: %s\n", name, err)
 		return fmt.Errorf("Cannot stop container %s: %s\n", name, err)
 	}
 	}
-	container.LogEvent("stop")
 	return nil
 	return nil
 }
 }

+ 1 - 0
daemon/top.go

@@ -68,5 +68,6 @@ func (daemon *Daemon) ContainerTop(name string, psArgs string) (*types.Container
 			}
 			}
 		}
 		}
 	}
 	}
+	container.LogEvent("top")
 	return procList, nil
 	return procList, nil
 }
 }

+ 0 - 1
daemon/unpause.go

@@ -12,7 +12,6 @@ func (daemon *Daemon) ContainerUnpause(name string) error {
 	if err := container.Unpause(); err != nil {
 	if err := container.Unpause(); err != nil {
 		return fmt.Errorf("Cannot unpause container %s: %s", name, err)
 		return fmt.Errorf("Cannot unpause container %s: %s", name, err)
 	}
 	}
-	container.LogEvent("unpause")
 
 
 	return nil
 	return nil
 }
 }

+ 1 - 1
docs/sources/reference/api/docker_remote_api_v1.19.md

@@ -1722,7 +1722,7 @@ polling (using since).
 
 
 Docker containers report the following events:
 Docker containers report the following events:
 
 
-    create, destroy, die, exec_create, exec_start, export, kill, oom, pause, restart, start, stop, unpause
+    attach, commit, copy, create, destroy, die, exec_create, exec_start, export, kill, oom, pause, rename, resize, restart, start, stop, top, unpause
 
 
 and Docker images report:
 and Docker images report:
 
 

+ 219 - 5
integration-cli/docker_cli_events_test.go

@@ -3,6 +3,7 @@ package main
 import (
 import (
 	"bufio"
 	"bufio"
 	"fmt"
 	"fmt"
+	"net/http"
 	"os/exec"
 	"os/exec"
 	"regexp"
 	"regexp"
 	"strconv"
 	"strconv"
@@ -141,16 +142,20 @@ func (s *DockerSuite) TestEventsContainerEvents(c *check.C) {
 	}
 	}
 	events := strings.Split(out, "\n")
 	events := strings.Split(out, "\n")
 	events = events[:len(events)-1]
 	events = events[:len(events)-1]
-	if len(events) < 4 {
+	if len(events) < 5 {
 		c.Fatalf("Missing expected event")
 		c.Fatalf("Missing expected event")
 	}
 	}
-	createEvent := strings.Fields(events[len(events)-4])
+	createEvent := strings.Fields(events[len(events)-5])
+	attachEvent := strings.Fields(events[len(events)-4])
 	startEvent := strings.Fields(events[len(events)-3])
 	startEvent := strings.Fields(events[len(events)-3])
 	dieEvent := strings.Fields(events[len(events)-2])
 	dieEvent := strings.Fields(events[len(events)-2])
 	destroyEvent := strings.Fields(events[len(events)-1])
 	destroyEvent := strings.Fields(events[len(events)-1])
 	if createEvent[len(createEvent)-1] != "create" {
 	if createEvent[len(createEvent)-1] != "create" {
 		c.Fatalf("event should be create, not %#v", createEvent)
 		c.Fatalf("event should be create, not %#v", createEvent)
 	}
 	}
+	if attachEvent[len(createEvent)-1] != "attach" {
+		c.Fatalf("event should be attach, not %#v", attachEvent)
+	}
 	if startEvent[len(startEvent)-1] != "start" {
 	if startEvent[len(startEvent)-1] != "start" {
 		c.Fatalf("event should be start, not %#v", startEvent)
 		c.Fatalf("event should be start, not %#v", startEvent)
 	}
 	}
@@ -175,16 +180,20 @@ func (s *DockerSuite) TestEventsContainerEventsSinceUnixEpoch(c *check.C) {
 	}
 	}
 	events := strings.Split(out, "\n")
 	events := strings.Split(out, "\n")
 	events = events[:len(events)-1]
 	events = events[:len(events)-1]
-	if len(events) < 4 {
+	if len(events) < 5 {
 		c.Fatalf("Missing expected event")
 		c.Fatalf("Missing expected event")
 	}
 	}
-	createEvent := strings.Fields(events[len(events)-4])
+	createEvent := strings.Fields(events[len(events)-5])
+	attachEvent := strings.Fields(events[len(events)-4])
 	startEvent := strings.Fields(events[len(events)-3])
 	startEvent := strings.Fields(events[len(events)-3])
 	dieEvent := strings.Fields(events[len(events)-2])
 	dieEvent := strings.Fields(events[len(events)-2])
 	destroyEvent := strings.Fields(events[len(events)-1])
 	destroyEvent := strings.Fields(events[len(events)-1])
 	if createEvent[len(createEvent)-1] != "create" {
 	if createEvent[len(createEvent)-1] != "create" {
 		c.Fatalf("event should be create, not %#v", createEvent)
 		c.Fatalf("event should be create, not %#v", createEvent)
 	}
 	}
+	if attachEvent[len(attachEvent)-1] != "attach" {
+		c.Fatalf("event should be attach, not %#v", attachEvent)
+	}
 	if startEvent[len(startEvent)-1] != "start" {
 	if startEvent[len(startEvent)-1] != "start" {
 		c.Fatalf("event should be start, not %#v", startEvent)
 		c.Fatalf("event should be start, not %#v", startEvent)
 	}
 	}
@@ -433,7 +442,7 @@ func (s *DockerSuite) TestEventsFilterContainer(c *check.C) {
 	until := fmt.Sprintf("%d", daemonTime(c).Unix())
 	until := fmt.Sprintf("%d", daemonTime(c).Unix())
 
 
 	checkEvents := func(id string, events []string) error {
 	checkEvents := func(id string, events []string) error {
-		if len(events) != 3 { // create, start, die
+		if len(events) != 4 { // create, attach, start, die
 			return fmt.Errorf("expected 3 events, got %v", events)
 			return fmt.Errorf("expected 3 events, got %v", events)
 		}
 		}
 		for _, event := range events {
 		for _, event := range events {
@@ -563,3 +572,208 @@ func (s *DockerSuite) TestEventsStreaming(c *check.C) {
 		// ignore, done
 		// ignore, done
 	}
 	}
 }
 }
+
+func (s *DockerSuite) TestEventsCommit(c *check.C) {
+	since := daemonTime(c).Unix()
+
+	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
+	out, _, err := runCommandWithOutput(runCmd)
+	if err != nil {
+		c.Fatalf("Couldn't run top: %s\n%q", out, err)
+	}
+	cID := strings.TrimSpace(out)
+	c.Assert(waitRun(cID), check.IsNil)
+
+	cmd := exec.Command(dockerBinary, "commit", "-m", "test", cID)
+	out, _, err = runCommandWithOutput(cmd)
+	if err != nil {
+		c.Fatalf("Couldn't commit: %s\n%q", out, err)
+	}
+
+	cmd = exec.Command(dockerBinary, "stop", cID)
+	out, _, err = runCommandWithOutput(cmd)
+	if err != nil {
+		c.Fatalf("Couldn't stop: %s\n%q", out, err)
+	}
+
+	cmd = exec.Command(dockerBinary, "events", "-f", "container="+cID, "--until="+strconv.Itoa(int(since)))
+	out, _, err = runCommandWithOutput(cmd)
+	if err != nil {
+		c.Fatalf("Couldn't get events: %s\n%q", out, err)
+	}
+
+	if !strings.Contains(out, " commit\n") {
+		c.Fatalf("Missing 'commit' log event\n%s", out)
+	}
+}
+
+func (s *DockerSuite) TestEventsCopy(c *check.C) {
+	since := daemonTime(c).Unix()
+
+	id, err := buildImage("cpimg", `
+		  FROM busybox
+		  RUN echo HI > /tmp/file`, true)
+	if err != nil {
+		c.Fatalf("Couldn't create image: %q", err)
+	}
+
+	runCmd := exec.Command(dockerBinary, "run", "--name=cptest", id, "true")
+	out, _, err := runCommandWithOutput(runCmd)
+	if err != nil {
+		c.Fatalf("Couldn't run top: %s\n%q", out, err)
+	}
+
+	cmd := exec.Command(dockerBinary, "cp", "cptest:/tmp/file", "-")
+	out, _, err = runCommandWithOutput(cmd)
+	if err != nil {
+		c.Fatalf("Failed getting file:%q\n%q", out, err)
+	}
+
+	cmd = exec.Command(dockerBinary, "events", "-f", "container=cptest", "--until="+strconv.Itoa(int(since)))
+	out, _, err = runCommandWithOutput(cmd)
+	if err != nil {
+		c.Fatalf("Couldn't get events: %s\n%q", out, err)
+	}
+
+	if !strings.Contains(out, " copy\n") {
+		c.Fatalf("Missing 'copy' log event\n%s", out)
+	}
+}
+
+func (s *DockerSuite) TestEventsResize(c *check.C) {
+	since := daemonTime(c).Unix()
+
+	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
+	out, _, err := runCommandWithOutput(runCmd)
+	if err != nil {
+		c.Fatalf("Couldn't run top: %s\n%q", out, err)
+	}
+	cID := strings.TrimSpace(out)
+	c.Assert(waitRun(cID), check.IsNil)
+
+	endpoint := "/containers/" + cID + "/resize?h=80&w=24"
+	status, _, err := sockRequest("POST", endpoint, nil)
+	c.Assert(status, check.Equals, http.StatusOK)
+	c.Assert(err, check.IsNil)
+
+	cmd := exec.Command(dockerBinary, "stop", cID)
+	out, _, err = runCommandWithOutput(cmd)
+	if err != nil {
+		c.Fatalf("Couldn't stop: %s\n%q", out, err)
+	}
+
+	cmd = exec.Command(dockerBinary, "events", "-f", "container="+cID, "--until="+strconv.Itoa(int(since)))
+	out, _, err = runCommandWithOutput(cmd)
+	if err != nil {
+		c.Fatalf("Couldn't get events: %s\n%q", out, err)
+	}
+
+	if !strings.Contains(out, " resize\n") {
+		c.Fatalf("Missing 'resize' log event\n%s", out)
+	}
+}
+
+func (s *DockerSuite) TestEventsAttach(c *check.C) {
+	since := daemonTime(c).Unix()
+
+	out, _ := dockerCmd(c, "run", "-di", "busybox", "/bin/cat")
+	cID := strings.TrimSpace(out)
+
+	cmd := exec.Command(dockerBinary, "attach", cID)
+	stdin, err := cmd.StdinPipe()
+	c.Assert(err, check.IsNil)
+	defer stdin.Close()
+	stdout, err := cmd.StdoutPipe()
+	c.Assert(err, check.IsNil)
+	defer stdout.Close()
+	c.Assert(cmd.Start(), check.IsNil)
+	defer cmd.Process.Kill()
+
+	// Make sure we're done attaching by writing/reading some stuff
+	if _, err := stdin.Write([]byte("hello\n")); err != nil {
+		c.Fatal(err)
+	}
+	out, err = bufio.NewReader(stdout).ReadString('\n')
+	c.Assert(err, check.IsNil)
+	if strings.TrimSpace(out) != "hello" {
+		c.Fatalf("expected 'hello', got %q", out)
+	}
+
+	c.Assert(stdin.Close(), check.IsNil)
+
+	cmd = exec.Command(dockerBinary, "stop", cID)
+	out, _, err = runCommandWithOutput(cmd)
+	if err != nil {
+		c.Fatalf("Couldn't stop: %s\n%q", out, err)
+	}
+
+	cmd = exec.Command(dockerBinary, "events", "-f", "container="+cID, "--until="+strconv.Itoa(int(since)))
+	out, _, err = runCommandWithOutput(cmd)
+	if err != nil {
+		c.Fatalf("Couldn't get events: %s\n%q", out, err)
+	}
+
+	if !strings.Contains(out, " attach\n") {
+		c.Fatalf("Missing 'attach' log event\n%s", out)
+	}
+}
+
+func (s *DockerSuite) TestEventsRename(c *check.C) {
+	since := daemonTime(c).Unix()
+
+	runCmd := exec.Command(dockerBinary, "run", "--name", "oldName", "busybox", "true")
+	out, _, err := runCommandWithOutput(runCmd)
+	if err != nil {
+		c.Fatalf("Couldn't run true: %s\n%q", out, err)
+	}
+
+	renameCmd := exec.Command(dockerBinary, "rename", "oldName", "newName")
+	out, _, err = runCommandWithOutput(renameCmd)
+	if err != nil {
+		c.Fatalf("Couldn't rename: %s\n%q", out, err)
+	}
+
+	cmd := exec.Command(dockerBinary, "events", "-f", "container=newName", "--until="+strconv.Itoa(int(since)))
+	out, _, err = runCommandWithOutput(cmd)
+	if err != nil {
+		c.Fatalf("Couldn't get events: %s\n%q", out, err)
+	}
+
+	if !strings.Contains(out, " rename\n") {
+		c.Fatalf("Missing 'rename' log event\n%s", out)
+	}
+}
+
+func (s *DockerSuite) TestEventsTop(c *check.C) {
+	since := daemonTime(c).Unix()
+
+	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "top")
+	out, _, err := runCommandWithOutput(runCmd)
+	if err != nil {
+		c.Fatalf("Couldn't run true: %s\n%q", out, err)
+	}
+	cID := strings.TrimSpace(out)
+	c.Assert(waitRun(cID), check.IsNil)
+
+	cmd := exec.Command(dockerBinary, "top", cID)
+	out, _, err = runCommandWithOutput(cmd)
+	if err != nil {
+		c.Fatalf("Couldn't run docker top: %s\n%q", out, err)
+	}
+
+	cmd = exec.Command(dockerBinary, "stop", cID)
+	out, _, err = runCommandWithOutput(cmd)
+	if err != nil {
+		c.Fatalf("Couldn't stop: %s\n%q", out, err)
+	}
+
+	cmd = exec.Command(dockerBinary, "events", "-f", "container="+cID, "--until="+strconv.Itoa(int(since)))
+	out, _, err = runCommandWithOutput(cmd)
+	if err != nil {
+		c.Fatalf("Couldn't get events: %s\n%q", out, err)
+	}
+
+	if !strings.Contains(out, " top\n") {
+		c.Fatalf("Missing 'top' log event\n%s", out)
+	}
+}