diff --git a/CHANGELOG.md b/CHANGELOG.md
index cd5ea062582647869f18fdb885744a0f7345ce99..9d869325cb6c32aee6fc99d1e429efe540b46853 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,19 @@
 ## v0.13 [unreleased]
 
 ### Release Notes
+- **Breaking Change**: docker plugin tags. The cont_id tag no longer exists, it
+will now be a field, and be called container_id. Additionally, cont_image and
+cont_name are being renamed to container_image and container_name.
+- **Breaking Change**: docker plugin measurements. The `docker_cpu`, `docker_mem`,
+and `docker_net` measurements are being renamed to `docker_container_cpu`,
+`docker_container_mem`, and `docker_container_net`. Why? Because these metrics are
+specifically tracking per-container stats. The problem with per-container stats,
+in some use-cases, is that if containers are short-lived AND names are not
+kept consistent, then the series cardinality will balloon very quickly.
+So adding "container" to each metric will:
+(1) make it more clear that these metrics are per-container, and
+(2) allow users to easily drop per-container metrics if cardinality is an
+issue (`namedrop = ["docker_container_*"]`)
 - `tagexclude` and `tagexclude` are now available, which can be used to remove
 tags from measurements on inputs and outputs. See
 [the configuration doc](https://github.com/influxdata/telegraf/blob/master/docs/CONFIGURATION.md)
@@ -12,6 +25,7 @@ based on _prefix_ in addition to globs. This means that a filter like
 
 ### Features
 - [#1017](https://github.com/influxdata/telegraf/pull/1017): taginclude and tagexclude arguments.
+- [#1015](https://github.com/influxdata/telegraf/pull/1015): Docker plugin schema refactor.
 
 ### Bugfixes
 - [#921](https://github.com/influxdata/telegraf/pull/921): mqtt_consumer stops gathering metrics. Thanks @chaton78!
diff --git a/plugins/inputs/docker/docker.go b/plugins/inputs/docker/docker.go
index 094bad8ca71ed566bd18d47233415b887de3b4e4..897d4f1a508d652682705d7a54a3cbc76a3e8b15 100644
--- a/plugins/inputs/docker/docker.go
+++ b/plugins/inputs/docker/docker.go
@@ -111,7 +111,8 @@ func (d *Docker) Gather(acc telegraf.Accumulator) error {
 			defer wg.Done()
 			err := d.gatherContainer(c, acc)
 			if err != nil {
-				fmt.Println(err.Error())
+				log.Printf("Error gathering container %s stats: %s\n",
+					c.Names, err.Error())
 			}
 		}(container)
 	}
@@ -200,9 +201,8 @@ func (d *Docker) gatherContainer(
 	}
 
 	tags := map[string]string{
-		"cont_id":    container.ID,
-		"cont_name":  cname,
-		"cont_image": container.Image,
+		"container_name":  cname,
+		"container_image": container.Image,
 	}
 	if len(d.ContainerNames) > 0 {
 		if !sliceContains(cname, d.ContainerNames) {
@@ -217,15 +217,18 @@ func (d *Docker) gatherContainer(
 	defer r.Close()
 	dec := json.NewDecoder(r)
 	if err = dec.Decode(&v); err != nil {
-		log.Printf("Error decoding: %s\n", err.Error())
+		if err == io.EOF {
+			return nil
+		}
+		return fmt.Errorf("Error decoding: %s", err.Error())
 	}
 
 	// Add labels to tags
-	for k, v := range container.Labels {
-		tags[k] = v
+	for k, label := range container.Labels {
+		tags[k] = label
 	}
 
-	gatherContainerStats(v, acc, tags)
+	gatherContainerStats(v, acc, tags, container.ID)
 
 	return nil
 }
@@ -234,6 +237,7 @@ func gatherContainerStats(
 	stat *types.StatsJSON,
 	acc telegraf.Accumulator,
 	tags map[string]string,
+	id string,
 ) {
 	now := stat.Read
 
@@ -272,8 +276,9 @@ func gatherContainerStats(
 		"inactive_file":             stat.MemoryStats.Stats["inactive_file"],
 		"total_pgpgin":              stat.MemoryStats.Stats["total_pgpgin"],
 		"usage_percent":             calculateMemPercent(stat),
+		"container_id":              id,
 	}
-	acc.AddFields("docker_mem", memfields, tags, now)
+	acc.AddFields("docker_container_mem", memfields, tags, now)
 
 	cpufields := map[string]interface{}{
 		"usage_total":                  stat.CPUStats.CPUUsage.TotalUsage,
@@ -284,32 +289,34 @@ func gatherContainerStats(
 		"throttling_throttled_periods": stat.CPUStats.ThrottlingData.ThrottledPeriods,
 		"throttling_throttled_time":    stat.CPUStats.ThrottlingData.ThrottledTime,
 		"usage_percent":                calculateCPUPercent(stat),
+		"container_id":                 id,
 	}
 	cputags := copyTags(tags)
 	cputags["cpu"] = "cpu-total"
-	acc.AddFields("docker_cpu", cpufields, cputags, now)
+	acc.AddFields("docker_container_cpu", cpufields, cputags, now)
 
 	for i, percpu := range stat.CPUStats.CPUUsage.PercpuUsage {
 		percputags := copyTags(tags)
 		percputags["cpu"] = fmt.Sprintf("cpu%d", i)
-		acc.AddFields("docker_cpu", map[string]interface{}{"usage_total": percpu}, percputags, now)
+		acc.AddFields("docker_container_cpu", map[string]interface{}{"usage_total": percpu}, percputags, now)
 	}
 
 	for network, netstats := range stat.Networks {
 		netfields := map[string]interface{}{
-			"rx_dropped": netstats.RxDropped,
-			"rx_bytes":   netstats.RxBytes,
-			"rx_errors":  netstats.RxErrors,
-			"tx_packets": netstats.TxPackets,
-			"tx_dropped": netstats.TxDropped,
-			"rx_packets": netstats.RxPackets,
-			"tx_errors":  netstats.TxErrors,
-			"tx_bytes":   netstats.TxBytes,
+			"rx_dropped":   netstats.RxDropped,
+			"rx_bytes":     netstats.RxBytes,
+			"rx_errors":    netstats.RxErrors,
+			"tx_packets":   netstats.TxPackets,
+			"tx_dropped":   netstats.TxDropped,
+			"rx_packets":   netstats.RxPackets,
+			"tx_errors":    netstats.TxErrors,
+			"tx_bytes":     netstats.TxBytes,
+			"container_id": id,
 		}
 		// Create a new network tag dictionary for the "network" tag
 		nettags := copyTags(tags)
 		nettags["network"] = network
-		acc.AddFields("docker_net", netfields, nettags, now)
+		acc.AddFields("docker_container_net", netfields, nettags, now)
 	}
 
 	gatherBlockIOMetrics(stat, acc, tags, now)
diff --git a/plugins/inputs/docker/docker_test.go b/plugins/inputs/docker/docker_test.go
index c9fe6cea1792746dca57124f192cde8e32869007..05069ba5327b043f6b474c2e1d3bb5e38c7c5145 100644
--- a/plugins/inputs/docker/docker_test.go
+++ b/plugins/inputs/docker/docker_test.go
@@ -21,26 +21,26 @@ func TestDockerGatherContainerStats(t *testing.T) {
 	stats := testStats()
 
 	tags := map[string]string{
-		"cont_id":    "foobarbaz",
-		"cont_name":  "redis",
-		"cont_image": "redis/image",
+		"container_name":  "redis",
+		"container_image": "redis/image",
 	}
-	gatherContainerStats(stats, &acc, tags)
+	gatherContainerStats(stats, &acc, tags, "123456789")
 
-	// test docker_net measurement
+	// test docker_container_net measurement
 	netfields := map[string]interface{}{
-		"rx_dropped": uint64(1),
-		"rx_bytes":   uint64(2),
-		"rx_errors":  uint64(3),
-		"tx_packets": uint64(4),
-		"tx_dropped": uint64(1),
-		"rx_packets": uint64(2),
-		"tx_errors":  uint64(3),
-		"tx_bytes":   uint64(4),
+		"rx_dropped":   uint64(1),
+		"rx_bytes":     uint64(2),
+		"rx_errors":    uint64(3),
+		"tx_packets":   uint64(4),
+		"tx_dropped":   uint64(1),
+		"rx_packets":   uint64(2),
+		"tx_errors":    uint64(3),
+		"tx_bytes":     uint64(4),
+		"container_id": "123456789",
 	}
 	nettags := copyTags(tags)
 	nettags["network"] = "eth0"
-	acc.AssertContainsTaggedFields(t, "docker_net", netfields, nettags)
+	acc.AssertContainsTaggedFields(t, "docker_container_net", netfields, nettags)
 
 	// test docker_blkio measurement
 	blkiotags := copyTags(tags)
@@ -51,7 +51,7 @@ func TestDockerGatherContainerStats(t *testing.T) {
 	}
 	acc.AssertContainsTaggedFields(t, "docker_blkio", blkiofields, blkiotags)
 
-	// test docker_mem measurement
+	// test docker_container_mem measurement
 	memfields := map[string]interface{}{
 		"max_usage":                 uint64(1001),
 		"usage":                     uint64(1111),
@@ -87,11 +87,12 @@ func TestDockerGatherContainerStats(t *testing.T) {
 		"inactive_file":             uint64(3),
 		"total_pgpgin":              uint64(4),
 		"usage_percent":             float64(55.55),
+		"container_id":              "123456789",
 	}
 
-	acc.AssertContainsTaggedFields(t, "docker_mem", memfields, tags)
+	acc.AssertContainsTaggedFields(t, "docker_container_mem", memfields, tags)
 
-	// test docker_cpu measurement
+	// test docker_container_cpu measurement
 	cputags := copyTags(tags)
 	cputags["cpu"] = "cpu-total"
 	cpufields := map[string]interface{}{
@@ -103,20 +104,21 @@ func TestDockerGatherContainerStats(t *testing.T) {
 		"throttling_throttled_periods": uint64(0),
 		"throttling_throttled_time":    uint64(0),
 		"usage_percent":                float64(400.0),
+		"container_id":                 "123456789",
 	}
-	acc.AssertContainsTaggedFields(t, "docker_cpu", cpufields, cputags)
+	acc.AssertContainsTaggedFields(t, "docker_container_cpu", cpufields, cputags)
 
 	cputags["cpu"] = "cpu0"
 	cpu0fields := map[string]interface{}{
 		"usage_total": uint64(1),
 	}
-	acc.AssertContainsTaggedFields(t, "docker_cpu", cpu0fields, cputags)
+	acc.AssertContainsTaggedFields(t, "docker_container_cpu", cpu0fields, cputags)
 
 	cputags["cpu"] = "cpu1"
 	cpu1fields := map[string]interface{}{
 		"usage_total": uint64(1002),
 	}
-	acc.AssertContainsTaggedFields(t, "docker_cpu", cpu1fields, cputags)
+	acc.AssertContainsTaggedFields(t, "docker_container_cpu", cpu1fields, cputags)
 }
 
 func testStats() *types.StatsJSON {
@@ -367,19 +369,18 @@ func TestDockerGatherInfo(t *testing.T) {
 		},
 	)
 	acc.AssertContainsTaggedFields(t,
-		"docker_cpu",
+		"docker_container_cpu",
 		map[string]interface{}{
 			"usage_total": uint64(1231652),
 		},
 		map[string]string{
-			"cont_id":    "b7dfbb9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296e2173",
-			"cont_name":  "etcd2",
-			"cont_image": "quay.io/coreos/etcd:v2.2.2",
-			"cpu":        "cpu3",
+			"container_name":  "etcd2",
+			"container_image": "quay.io/coreos/etcd:v2.2.2",
+			"cpu":             "cpu3",
 		},
 	)
 	acc.AssertContainsTaggedFields(t,
-		"docker_mem",
+		"docker_container_mem",
 		map[string]interface{}{
 			"total_pgpgout":             uint64(0),
 			"usage_percent":             float64(0),
@@ -415,11 +416,11 @@ func TestDockerGatherInfo(t *testing.T) {
 			"pgfault":                   uint64(0),
 			"usage":                     uint64(0),
 			"limit":                     uint64(18935443456),
+			"container_id":              "b7dfbb9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296e2173",
 		},
 		map[string]string{
-			"cont_id":    "b7dfbb9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296e2173",
-			"cont_name":  "etcd2",
-			"cont_image": "quay.io/coreos/etcd:v2.2.2",
+			"container_name":  "etcd2",
+			"container_image": "quay.io/coreos/etcd:v2.2.2",
 		},
 	)