From 53f40063b31fd9ef3d92e7fc22e821d0f71ac46d Mon Sep 17 00:00:00 2001
From: Sebastian Borza <sborza@alumni.princeton.edu>
Date: Thu, 14 Jul 2016 15:18:55 -0500
Subject: [PATCH] Moving cgroup path name to field from tag to reduce
 cardinality (#1457)

adding assertContainsFields function to cgroup_test for custom validation
---
 plugins/inputs/cgroup/README.md       |  5 +-
 plugins/inputs/cgroup/cgroup_linux.go |  5 +-
 plugins/inputs/cgroup/cgroup_test.go  | 84 +++++++++++++++------------
 3 files changed, 53 insertions(+), 41 deletions(-)

diff --git a/plugins/inputs/cgroup/README.md b/plugins/inputs/cgroup/README.md
index ab06342b..feb332dd 100644
--- a/plugins/inputs/cgroup/README.md
+++ b/plugins/inputs/cgroup/README.md
@@ -33,8 +33,9 @@ KEY1 VAL1\n
 
 ### Tags:
 
-All measurements have the following tags:
-  - path
+Measurements don't have any specific tags unless you define them at the telegraf level (defaults). We
+used to have the path listed as a tag, but to keep cardinality in check it's easier to move this 
+value to a field. Thanks @sebito91!
 
 
 ### Configuration:
diff --git a/plugins/inputs/cgroup/cgroup_linux.go b/plugins/inputs/cgroup/cgroup_linux.go
index e8ba6f88..ecaf8126 100644
--- a/plugins/inputs/cgroup/cgroup_linux.go
+++ b/plugins/inputs/cgroup/cgroup_linux.go
@@ -56,10 +56,9 @@ func (g *CGroup) gatherDir(dir string, acc telegraf.Accumulator) error {
 			return err
 		}
 	}
+	fields["path"] = dir
 
-	tags := map[string]string{"path": dir}
-
-	acc.AddFields(metricName, fields, tags)
+	acc.AddFields(metricName, fields, nil)
 
 	return nil
 }
diff --git a/plugins/inputs/cgroup/cgroup_test.go b/plugins/inputs/cgroup/cgroup_test.go
index 206b51f6..ff9b8d7a 100644
--- a/plugins/inputs/cgroup/cgroup_test.go
+++ b/plugins/inputs/cgroup/cgroup_test.go
@@ -3,10 +3,13 @@
 package cgroup
 
 import (
+	"fmt"
 	"testing"
 
 	"github.com/influxdata/telegraf/testutil"
+	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"reflect"
 )
 
 var cg1 = &CGroup{
@@ -21,15 +24,32 @@ var cg1 = &CGroup{
 	},
 }
 
+func assertContainsFields(a *testutil.Accumulator, t *testing.T, measurement string, fieldSet []map[string]interface{}) {
+	a.Lock()
+	defer a.Unlock()
+
+	numEquals := 0
+	for _, p := range a.Metrics {
+		if p.Measurement == measurement {
+			for _, fields := range fieldSet {
+				if reflect.DeepEqual(fields, p.Fields) {
+					numEquals++
+				}
+			}
+		}
+	}
+
+	if numEquals != len(fieldSet) {
+		assert.Fail(t, fmt.Sprintf("only %d of %d are equal", numEquals, len(fieldSet)))
+	}
+}
+
 func TestCgroupStatistics_1(t *testing.T) {
 	var acc testutil.Accumulator
 
 	err := cg1.Gather(&acc)
 	require.NoError(t, err)
 
-	tags := map[string]string{
-		"path": "testdata/memory",
-	}
 	fields := map[string]interface{}{
 		"memory.stat.cache":           1739362304123123123,
 		"memory.stat.rss":             1775325184,
@@ -42,8 +62,9 @@ func TestCgroupStatistics_1(t *testing.T) {
 		"memory.limit_in_bytes":       223372036854771712,
 		"memory.use_hierarchy":        "12-781",
 		"notify_on_release":           0,
+		"path":                        "testdata/memory",
 	}
-	acc.AssertContainsTaggedFields(t, "cgroup", fields, tags)
+	assertContainsFields(&acc, t, "cgroup", []map[string]interface{}{fields})
 }
 
 // ======================================================================
@@ -59,16 +80,14 @@ func TestCgroupStatistics_2(t *testing.T) {
 	err := cg2.Gather(&acc)
 	require.NoError(t, err)
 
-	tags := map[string]string{
-		"path": "testdata/cpu",
-	}
 	fields := map[string]interface{}{
 		"cpuacct.usage_percpu.0": -1452543795404,
 		"cpuacct.usage_percpu.1": 1376681271659,
 		"cpuacct.usage_percpu.2": 1450950799997,
 		"cpuacct.usage_percpu.3": -1473113374257,
+		"path": "testdata/cpu",
 	}
-	acc.AssertContainsTaggedFields(t, "cgroup", fields, tags)
+	assertContainsFields(&acc, t, "cgroup", []map[string]interface{}{fields})
 }
 
 // ======================================================================
@@ -84,18 +103,16 @@ func TestCgroupStatistics_3(t *testing.T) {
 	err := cg3.Gather(&acc)
 	require.NoError(t, err)
 
-	tags := map[string]string{
-		"path": "testdata/memory/group_1",
-	}
 	fields := map[string]interface{}{
 		"memory.limit_in_bytes": 223372036854771712,
+		"path":                  "testdata/memory/group_1",
 	}
-	acc.AssertContainsTaggedFields(t, "cgroup", fields, tags)
 
-	tags = map[string]string{
-		"path": "testdata/memory/group_2",
+	fieldsTwo := map[string]interface{}{
+		"memory.limit_in_bytes": 223372036854771712,
+		"path":                  "testdata/memory/group_2",
 	}
-	acc.AssertContainsTaggedFields(t, "cgroup", fields, tags)
+	assertContainsFields(&acc, t, "cgroup", []map[string]interface{}{fields, fieldsTwo})
 }
 
 // ======================================================================
@@ -111,23 +128,22 @@ func TestCgroupStatistics_4(t *testing.T) {
 	err := cg4.Gather(&acc)
 	require.NoError(t, err)
 
-	tags := map[string]string{
-		"path": "testdata/memory/group_1/group_1_1",
-	}
 	fields := map[string]interface{}{
 		"memory.limit_in_bytes": 223372036854771712,
+		"path":                  "testdata/memory/group_1/group_1_1",
 	}
-	acc.AssertContainsTaggedFields(t, "cgroup", fields, tags)
 
-	tags = map[string]string{
-		"path": "testdata/memory/group_1/group_1_2",
+	fieldsTwo := map[string]interface{}{
+		"memory.limit_in_bytes": 223372036854771712,
+		"path":                  "testdata/memory/group_1/group_1_2",
 	}
-	acc.AssertContainsTaggedFields(t, "cgroup", fields, tags)
 
-	tags = map[string]string{
-		"path": "testdata/memory/group_2",
+	fieldsThree := map[string]interface{}{
+		"memory.limit_in_bytes": 223372036854771712,
+		"path":                  "testdata/memory/group_2",
 	}
-	acc.AssertContainsTaggedFields(t, "cgroup", fields, tags)
+
+	assertContainsFields(&acc, t, "cgroup", []map[string]interface{}{fields, fieldsTwo, fieldsThree})
 }
 
 // ======================================================================
@@ -143,18 +159,16 @@ func TestCgroupStatistics_5(t *testing.T) {
 	err := cg5.Gather(&acc)
 	require.NoError(t, err)
 
-	tags := map[string]string{
-		"path": "testdata/memory/group_1/group_1_1",
-	}
 	fields := map[string]interface{}{
 		"memory.limit_in_bytes": 223372036854771712,
+		"path":                  "testdata/memory/group_1/group_1_1",
 	}
-	acc.AssertContainsTaggedFields(t, "cgroup", fields, tags)
 
-	tags = map[string]string{
-		"path": "testdata/memory/group_2/group_1_1",
+	fieldsTwo := map[string]interface{}{
+		"memory.limit_in_bytes": 223372036854771712,
+		"path":                  "testdata/memory/group_2/group_1_1",
 	}
-	acc.AssertContainsTaggedFields(t, "cgroup", fields, tags)
+	assertContainsFields(&acc, t, "cgroup", []map[string]interface{}{fields, fieldsTwo})
 }
 
 // ======================================================================
@@ -170,13 +184,11 @@ func TestCgroupStatistics_6(t *testing.T) {
 	err := cg6.Gather(&acc)
 	require.NoError(t, err)
 
-	tags := map[string]string{
-		"path": "testdata/memory",
-	}
 	fields := map[string]interface{}{
 		"memory.usage_in_bytes":      3513667584,
 		"memory.use_hierarchy":       "12-781",
 		"memory.kmem.limit_in_bytes": 9223372036854771712,
+		"path": "testdata/memory",
 	}
-	acc.AssertContainsTaggedFields(t, "cgroup", fields, tags)
+	assertContainsFields(&acc, t, "cgroup", []map[string]interface{}{fields})
 }
-- 
GitLab