From 16fd48154af8ae87ca955eb6bcc277ed9a5fd70f Mon Sep 17 00:00:00 2001 From: Shakeel Sorathia Date: Fri, 17 Feb 2017 14:33:01 -0800 Subject: [PATCH 01/10] - allow ability to not add labels as tags or only add specific labels --- plugins/inputs/docker/docker.go | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/plugins/inputs/docker/docker.go b/plugins/inputs/docker/docker.go index ec192efd5e5d3..029fd966d9109 100644 --- a/plugins/inputs/docker/docker.go +++ b/plugins/inputs/docker/docker.go @@ -27,6 +27,8 @@ type Docker struct { Timeout internal.Duration PerDevice bool `toml:"perdevice"` Total bool `toml:"total"` + AddLabels bool `toml:"addlabels"` + LabelNames []string `toml:"label_names"` client *client.Client engine_host string @@ -99,6 +101,12 @@ var sampleConfig = ` ## Whether to report for each container total blkio and network stats or not total = false + ## Whether to add docker labels as tags + addlabels = true + + ## If addlabels is set to true, optionally create an array of labels that are to be added + ## An empty array adds all labels + label_names = [] ` // Description returns input description @@ -291,9 +299,16 @@ func (d *Docker) gatherContainer( return fmt.Errorf("Error decoding: %s", err.Error()) } - // Add labels to tags - for k, label := range container.Labels { - tags[k] = label + // Add labels to tags if addlabels is true + //fmt.Printf("AddLabels is %t: len of labelnames is %d\n", d.AddLabels, len(d.LabelNames)) + if d.AddLabels { + for k, label := range container.Labels { + // fmt.Printf("Checking tag %s with value %s\n", k, label) + if (len(d.LabelNames) == 0 ) || (len(d.LabelNames) > 0 && sliceContains(k, d.LabelNames)) { + // fmt.Printf("Adding tag %s with value %s\n", k, label) + tags[k] = label + } + } } gatherContainerStats(v, acc, tags, container.ID, d.PerDevice, d.Total) @@ -604,6 +619,7 @@ func init() { return &Docker{ PerDevice: true, Timeout: internal.Duration{Duration: time.Second * 5}, + AddLabels: true, } }) } From aa6328fb6e9f1ca12df64f34b0c36fcf9a42e1c1 Mon Sep 17 00:00:00 2001 From: Shakeel Sorathia Date: Fri, 17 Feb 2017 14:33:25 -0800 Subject: [PATCH 02/10] - tests and documentation updated --- plugins/inputs/docker/README.md | 5 +++ plugins/inputs/docker/docker_test.go | 56 ++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/plugins/inputs/docker/README.md b/plugins/inputs/docker/README.md index 94965213ff3c6..791ba342b703e 100644 --- a/plugins/inputs/docker/README.md +++ b/plugins/inputs/docker/README.md @@ -30,6 +30,11 @@ for the stat structure can be found perdevice = true ## Whether to report for each container total blkio and network stats or not total = false + # Add container labels as tags + addlabels = true + # If addlabels is set to true, optional array to add specific lables. + # Empty array adds all labels + label_names = [] ``` ### Measurements & Fields: diff --git a/plugins/inputs/docker/docker_test.go b/plugins/inputs/docker/docker_test.go index f0add03ea20c4..de012303aac05 100644 --- a/plugins/inputs/docker/docker_test.go +++ b/plugins/inputs/docker/docker_test.go @@ -244,6 +244,58 @@ func testStats() *types.StatsJSON { return stats } +func TestDockerGatherLabels(t *testing.T) { + var acc testutil.Accumulator + d := Docker{ + client: nil, + testing: true, + } + + d.AddLabels = true + + err := d.Gather(&acc) + + require.NoError(t, err) + + acc.AssertContainsTaggedFields(t, + "docker_container_cpu", + map[string]interface{}{ + "usage_total": uint64(1231652), + "container_id": "b7dfbb9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296e2173", + }, + map[string]string{ + "container_name": "etcd2", + "container_image": "quay.io:4443/coreos/etcd", + "cpu": "cpu3", + "container_version": "v2.2.2", + "engine_host": "absol", + "label1": "test_value_1", + "label2": "test_value_2", + }, + ) + + d.LabelNames = append(d.LabelNames, "label1") + err1 := d.Gather(&acc) + require.NoError(t, err1) + + acc.AssertContainsTaggedFields(t, + "docker_container_cpu", + map[string]interface{}{ + "usage_total": uint64(1231652), + "container_id": "b7dfbb9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296e2173", + }, + map[string]string{ + "container_name": "etcd2", + "container_image": "quay.io:4443/coreos/etcd", + "cpu": "cpu3", + "container_version": "v2.2.2", + "engine_host": "absol", + "label1": "test_value_1", + }, + ) + +} + func TestDockerGatherInfo(t *testing.T) { var acc testutil.Accumulator d := Docker{ @@ -251,6 +303,10 @@ func TestDockerGatherInfo(t *testing.T) { testing: true, } + /* In order to not modify code here, we set this to false since the container structure now has + labels and the default is true. + */ + d.AddLabels = false err := d.Gather(&acc) require.NoError(t, err) From b347bb38558af8b73048c4ad59f2ffb7efbae97f Mon Sep 17 00:00:00 2001 From: Shakeel Sorathia Date: Fri, 17 Feb 2017 14:48:41 -0800 Subject: [PATCH 03/10] - go fmt ./... - removed some commented out debug code --- plugins/inputs/docker/docker.go | 11 ++++------- plugins/inputs/docker/docker_test.go | 8 ++++---- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/plugins/inputs/docker/docker.go b/plugins/inputs/docker/docker.go index 029fd966d9109..fdceede2cfaea 100644 --- a/plugins/inputs/docker/docker.go +++ b/plugins/inputs/docker/docker.go @@ -25,9 +25,9 @@ type Docker struct { Endpoint string ContainerNames []string Timeout internal.Duration - PerDevice bool `toml:"perdevice"` - Total bool `toml:"total"` - AddLabels bool `toml:"addlabels"` + PerDevice bool `toml:"perdevice"` + Total bool `toml:"total"` + AddLabels bool `toml:"addlabels"` LabelNames []string `toml:"label_names"` client *client.Client @@ -300,12 +300,9 @@ func (d *Docker) gatherContainer( } // Add labels to tags if addlabels is true - //fmt.Printf("AddLabels is %t: len of labelnames is %d\n", d.AddLabels, len(d.LabelNames)) if d.AddLabels { for k, label := range container.Labels { - // fmt.Printf("Checking tag %s with value %s\n", k, label) - if (len(d.LabelNames) == 0 ) || (len(d.LabelNames) > 0 && sliceContains(k, d.LabelNames)) { - // fmt.Printf("Adding tag %s with value %s\n", k, label) + if (len(d.LabelNames) == 0) || (len(d.LabelNames) > 0 && sliceContains(k, d.LabelNames)) { tags[k] = label } } diff --git a/plugins/inputs/docker/docker_test.go b/plugins/inputs/docker/docker_test.go index de012303aac05..6eec17cb7246f 100644 --- a/plugins/inputs/docker/docker_test.go +++ b/plugins/inputs/docker/docker_test.go @@ -269,8 +269,8 @@ func TestDockerGatherLabels(t *testing.T) { "cpu": "cpu3", "container_version": "v2.2.2", "engine_host": "absol", - "label1": "test_value_1", - "label2": "test_value_2", + "label1": "test_value_1", + "label2": "test_value_2", }, ) @@ -290,7 +290,7 @@ func TestDockerGatherLabels(t *testing.T) { "cpu": "cpu3", "container_version": "v2.2.2", "engine_host": "absol", - "label1": "test_value_1", + "label1": "test_value_1", }, ) @@ -305,7 +305,7 @@ func TestDockerGatherInfo(t *testing.T) { /* In order to not modify code here, we set this to false since the container structure now has labels and the default is true. - */ + */ d.AddLabels = false err := d.Gather(&acc) require.NoError(t, err) From 9ac0616784d4ceb6ea69d2a7706da6a6b22022bd Mon Sep 17 00:00:00 2001 From: Shakeel Sorathia Date: Sat, 25 Feb 2017 10:11:01 -0800 Subject: [PATCH 04/10] - readme updates to add tags that were not documented --- plugins/inputs/docker/README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/plugins/inputs/docker/README.md b/plugins/inputs/docker/README.md index 791ba342b703e..2ceb476a0b2a6 100644 --- a/plugins/inputs/docker/README.md +++ b/plugins/inputs/docker/README.md @@ -135,30 +135,31 @@ based on the availability of per-cpu stats on your system. ### Tags: - +#### Docker Engine tags - docker (memory_total) - unit=bytes + - engine_host - docker (pool_blocksize) - unit=bytes + - engine_host - docker_data - unit=bytes + - engine_host - docker_metadata - unit=bytes -- docker_container_mem specific: +#### Docker Container tags +- Tags on all containers: + - engine_host - container_image - container_name + - container_version +- docker_container_mem specific: - docker_container_cpu specific: - - container_image - - container_name - cpu - docker_container_net specific: - - container_image - - container_name - network - docker_container_blkio specific: - - container_image - - container_name - device ### Example Output: From f5296dcdb631ed61ae2b532a2a52c073198b1f9c Mon Sep 17 00:00:00 2001 From: Shakeel Sorathia Date: Sat, 25 Feb 2017 10:40:50 -0800 Subject: [PATCH 05/10] - merge master - resolve conflicts --- plugins/inputs/docker/docker_test.go | 2 +- plugins/inputs/docker/fake_client.go | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/plugins/inputs/docker/docker_test.go b/plugins/inputs/docker/docker_test.go index 6eec17cb7246f..3f1adafe0bf11 100644 --- a/plugins/inputs/docker/docker_test.go +++ b/plugins/inputs/docker/docker_test.go @@ -247,7 +247,7 @@ func testStats() *types.StatsJSON { func TestDockerGatherLabels(t *testing.T) { var acc testutil.Accumulator d := Docker{ - client: nil, + client: nil, testing: true, } diff --git a/plugins/inputs/docker/fake_client.go b/plugins/inputs/docker/fake_client.go index 03da23198a890..dcca6f235ac25 100644 --- a/plugins/inputs/docker/fake_client.go +++ b/plugins/inputs/docker/fake_client.go @@ -92,6 +92,10 @@ func (d FakeDockerClient) ContainerList(octx context.Context, options types.Cont IP: "0.0.0.0", }, }, + Labels: map[string]string{ + "label1": "test_value_1", + "label2": "test_value_2", + }, SizeRw: 0, SizeRootFs: 0, } @@ -125,6 +129,10 @@ func (d FakeDockerClient) ContainerList(octx context.Context, options types.Cont IP: "0.0.0.0", }, }, + Labels: map[string]string{ + "label1": "test_value_1", + "label2": "test_value_2", + }, SizeRw: 0, SizeRootFs: 0, } From bc9625fe738cc8ddf4ef4418ef20a263226a8faa Mon Sep 17 00:00:00 2001 From: Shakeel Sorathia Date: Tue, 14 Mar 2017 16:17:47 -0700 Subject: [PATCH 06/10] - changed the way labels are added to be inline with taginclude and tagexclude - updated tests - updated readme to reflect new parameter names --- plugins/inputs/docker/README.md | 11 ++++---- plugins/inputs/docker/docker.go | 41 +++++++++++++++++++--------- plugins/inputs/docker/docker_test.go | 32 ++++++++++++++++++---- 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/plugins/inputs/docker/README.md b/plugins/inputs/docker/README.md index 2ceb476a0b2a6..31fe2aa612262 100644 --- a/plugins/inputs/docker/README.md +++ b/plugins/inputs/docker/README.md @@ -30,11 +30,12 @@ for the stat structure can be found perdevice = true ## Whether to report for each container total blkio and network stats or not total = false - # Add container labels as tags - addlabels = true - # If addlabels is set to true, optional array to add specific lables. - # Empty array adds all labels - label_names = [] + + ## docker labels to include and exclude as tags. Globs accepted. + ## Note that an empty array for both will include all labels as tags + docker_label_include = [] + docker_label_exclude = [] + ``` ### Measurements & Fields: diff --git a/plugins/inputs/docker/docker.go b/plugins/inputs/docker/docker.go index fdceede2cfaea..01e508b217df9 100644 --- a/plugins/inputs/docker/docker.go +++ b/plugins/inputs/docker/docker.go @@ -14,12 +14,17 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/client" - + "github.com/influxdata/telegraf/filter" "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/internal" "github.com/influxdata/telegraf/plugins/inputs" ) +type DockerLabelFilter struct { + labelInclude filter.Filter + labelExclude filter.Filter +} + // Docker object type Docker struct { Endpoint string @@ -27,8 +32,10 @@ type Docker struct { Timeout internal.Duration PerDevice bool `toml:"perdevice"` Total bool `toml:"total"` - AddLabels bool `toml:"addlabels"` - LabelNames []string `toml:"label_names"` + LabelInclude []string `toml:"docker_label_include"` + LabelExclude []string `toml:"docker_label_exclude"` + + LabelFilter DockerLabelFilter client *client.Client engine_host string @@ -101,12 +108,11 @@ var sampleConfig = ` ## Whether to report for each container total blkio and network stats or not total = false - ## Whether to add docker labels as tags - addlabels = true + ## docker labels to include and exclude as tags. Globs accepted. + ## Note that an empty array for both will include all labels as tags + docker_label_include = [] + docker_label_exclude = [] - ## If addlabels is set to true, optionally create an array of labels that are to be added - ## An empty array adds all labels - label_names = [] ` // Description returns input description @@ -142,6 +148,15 @@ func (d *Docker) Gather(acc telegraf.Accumulator) error { d.client = c } + // Create label filters + if len(d.LabelInclude) != 0 { + d.LabelFilter.labelInclude, _ = filter.Compile(d.LabelInclude) + } + + if len(d.LabelExclude) != 0 { + d.LabelFilter.labelExclude, _ = filter.Compile(d.LabelExclude) + } + // Get daemon info err := d.gatherInfo(acc) if err != nil { @@ -299,10 +314,10 @@ func (d *Docker) gatherContainer( return fmt.Errorf("Error decoding: %s", err.Error()) } - // Add labels to tags if addlabels is true - if d.AddLabels { - for k, label := range container.Labels { - if (len(d.LabelNames) == 0) || (len(d.LabelNames) > 0 && sliceContains(k, d.LabelNames)) { + // Add labels to tags + for k, label := range container.Labels { + if len(d.LabelInclude) == 0 || d.LabelFilter.labelInclude.Match(k) { + if len(d.LabelExclude) == 0 || !d.LabelFilter.labelExclude.Match(k) { tags[k] = label } } @@ -616,7 +631,7 @@ func init() { return &Docker{ PerDevice: true, Timeout: internal.Duration{Duration: time.Second * 5}, - AddLabels: true, + //AddLabels: true, } }) } diff --git a/plugins/inputs/docker/docker_test.go b/plugins/inputs/docker/docker_test.go index 3f1adafe0bf11..cd67250854900 100644 --- a/plugins/inputs/docker/docker_test.go +++ b/plugins/inputs/docker/docker_test.go @@ -251,10 +251,8 @@ func TestDockerGatherLabels(t *testing.T) { testing: true, } - d.AddLabels = true - + // Default case should include both labels err := d.Gather(&acc) - require.NoError(t, err) acc.AssertContainsTaggedFields(t, @@ -274,7 +272,8 @@ func TestDockerGatherLabels(t *testing.T) { }, ) - d.LabelNames = append(d.LabelNames, "label1") + // Include should only include label1 + d.LabelInclude = append(d.LabelInclude, "label1") err1 := d.Gather(&acc) require.NoError(t, err1) @@ -294,6 +293,28 @@ func TestDockerGatherLabels(t *testing.T) { }, ) + // Exclude should only include label2. + d.LabelInclude[0] = "*" + d.LabelExclude = append(d.LabelExclude, "label1") + err2 := d.Gather(&acc) + require.NoError(t, err2) + + acc.AssertContainsTaggedFields(t, + "docker_container_cpu", + map[string]interface{}{ + "usage_total": uint64(1231652), + "container_id": "b7dfbb9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296e2173", + }, + map[string]string{ + "container_name": "etcd2", + "container_image": "quay.io:4443/coreos/etcd", + "cpu": "cpu3", + "container_version": "v2.2.2", + "engine_host": "absol", + "label2": "test_value_2", + }, + ) + } func TestDockerGatherInfo(t *testing.T) { @@ -306,7 +327,8 @@ func TestDockerGatherInfo(t *testing.T) { /* In order to not modify code here, we set this to false since the container structure now has labels and the default is true. */ - d.AddLabels = false + + d.LabelExclude = append(d.LabelExclude, "*") err := d.Gather(&acc) require.NoError(t, err) From 5708b2165fa2639d0a2444b4b123c7b36ac23d9c Mon Sep 17 00:00:00 2001 From: Shakeel Sorathia Date: Tue, 14 Mar 2017 16:19:32 -0700 Subject: [PATCH 07/10] - go fmt --- plugins/inputs/docker/docker.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/inputs/docker/docker.go b/plugins/inputs/docker/docker.go index 01e508b217df9..57960a6590ee2 100644 --- a/plugins/inputs/docker/docker.go +++ b/plugins/inputs/docker/docker.go @@ -14,15 +14,15 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/client" - "github.com/influxdata/telegraf/filter" "github.com/influxdata/telegraf" + "github.com/influxdata/telegraf/filter" "github.com/influxdata/telegraf/internal" "github.com/influxdata/telegraf/plugins/inputs" ) type DockerLabelFilter struct { - labelInclude filter.Filter - labelExclude filter.Filter + labelInclude filter.Filter + labelExclude filter.Filter } // Docker object @@ -35,7 +35,7 @@ type Docker struct { LabelInclude []string `toml:"docker_label_include"` LabelExclude []string `toml:"docker_label_exclude"` - LabelFilter DockerLabelFilter + LabelFilter DockerLabelFilter client *client.Client engine_host string @@ -153,7 +153,7 @@ func (d *Docker) Gather(acc telegraf.Accumulator) error { d.LabelFilter.labelInclude, _ = filter.Compile(d.LabelInclude) } - if len(d.LabelExclude) != 0 { + if len(d.LabelExclude) != 0 { d.LabelFilter.labelExclude, _ = filter.Compile(d.LabelExclude) } From b596356f38c6d12770f39b9525e592b5b1a29110 Mon Sep 17 00:00:00 2001 From: Shakeel Sorathia Date: Mon, 27 Mar 2017 16:39:59 -0700 Subject: [PATCH 08/10] - updates based on code review --- plugins/inputs/docker/README.md | 1 + plugins/inputs/docker/docker.go | 14 ++- plugins/inputs/docker/docker_test.go | 131 ++++++++++++--------------- 3 files changed, 68 insertions(+), 78 deletions(-) diff --git a/plugins/inputs/docker/README.md b/plugins/inputs/docker/README.md index 31fe2aa612262..849450b33cd40 100644 --- a/plugins/inputs/docker/README.md +++ b/plugins/inputs/docker/README.md @@ -148,6 +148,7 @@ based on the availability of per-cpu stats on your system. - engine_host - docker_metadata - unit=bytes + - engine_host #### Docker Container tags - Tags on all containers: diff --git a/plugins/inputs/docker/docker.go b/plugins/inputs/docker/docker.go index 57960a6590ee2..c333d57010828 100644 --- a/plugins/inputs/docker/docker.go +++ b/plugins/inputs/docker/docker.go @@ -112,7 +112,6 @@ var sampleConfig = ` ## Note that an empty array for both will include all labels as tags docker_label_include = [] docker_label_exclude = [] - ` // Description returns input description @@ -150,11 +149,19 @@ func (d *Docker) Gather(acc telegraf.Accumulator) error { // Create label filters if len(d.LabelInclude) != 0 { - d.LabelFilter.labelInclude, _ = filter.Compile(d.LabelInclude) + var err error + d.LabelFilter.labelInclude, err = filter.Compile(d.LabelInclude) + if err != nil { + return err + } } if len(d.LabelExclude) != 0 { - d.LabelFilter.labelExclude, _ = filter.Compile(d.LabelExclude) + var err error + d.LabelFilter.labelExclude, err = filter.Compile(d.LabelExclude) + if err != nil { + return err + } } // Get daemon info @@ -631,7 +638,6 @@ func init() { return &Docker{ PerDevice: true, Timeout: internal.Duration{Duration: time.Second * 5}, - //AddLabels: true, } }) } diff --git a/plugins/inputs/docker/docker_test.go b/plugins/inputs/docker/docker_test.go index cd67250854900..f606dc70a504f 100644 --- a/plugins/inputs/docker/docker_test.go +++ b/plugins/inputs/docker/docker_test.go @@ -8,6 +8,7 @@ import ( "github.com/docker/docker/api/types" "github.com/stretchr/testify/require" + "fmt" ) func TestDockerGatherContainerStats(t *testing.T) { @@ -244,77 +245,60 @@ func testStats() *types.StatsJSON { return stats } -func TestDockerGatherLabels(t *testing.T) { - var acc testutil.Accumulator - d := Docker{ - client: nil, - testing: true, - } - - // Default case should include both labels - err := d.Gather(&acc) - require.NoError(t, err) - - acc.AssertContainsTaggedFields(t, - "docker_container_cpu", - map[string]interface{}{ - "usage_total": uint64(1231652), - "container_id": "b7dfbb9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296e2173", - }, - map[string]string{ - "container_name": "etcd2", - "container_image": "quay.io:4443/coreos/etcd", - "cpu": "cpu3", - "container_version": "v2.2.2", - "engine_host": "absol", - "label1": "test_value_1", - "label2": "test_value_2", - }, - ) +var gatherLabelsTests = []struct { + include []string + exclude []string + expected []string + notexpected []string +}{ + {[]string{}, []string{}, []string{"label1","label2"}, []string{}}, + {[]string{"*"}, []string{}, []string{"label1","label2"}, []string{}}, + {[]string{"lab*"}, []string{}, []string{"label1","label2"}, []string{}}, + {[]string{"label1"}, []string{}, []string{"label1"}, []string{"label2"}}, + {[]string{"label1*"}, []string{}, []string{"label1"}, []string{"label2"}}, + {[]string{}, []string{"*"}, []string{}, []string{"label1","label2"}}, + {[]string{}, []string{"lab*"}, []string{}, []string{"label1","label2"}}, + {[]string{}, []string{"label1"}, []string{"label2"}, []string{"label1"}}, + {[]string{"*"}, []string{"*"}, []string{}, []string{"label1","label2"}}, - // Include should only include label1 - d.LabelInclude = append(d.LabelInclude, "label1") - err1 := d.Gather(&acc) - require.NoError(t, err1) - - acc.AssertContainsTaggedFields(t, - "docker_container_cpu", - map[string]interface{}{ - "usage_total": uint64(1231652), - "container_id": "b7dfbb9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296e2173", - }, - map[string]string{ - "container_name": "etcd2", - "container_image": "quay.io:4443/coreos/etcd", - "cpu": "cpu3", - "container_version": "v2.2.2", - "engine_host": "absol", - "label1": "test_value_1", - }, - ) - - // Exclude should only include label2. - d.LabelInclude[0] = "*" - d.LabelExclude = append(d.LabelExclude, "label1") - err2 := d.Gather(&acc) - require.NoError(t, err2) - - acc.AssertContainsTaggedFields(t, - "docker_container_cpu", - map[string]interface{}{ - "usage_total": uint64(1231652), - "container_id": "b7dfbb9478a6ae55e237d4d74f8bbb753f0817192b5081334dc78476296e2173", - }, - map[string]string{ - "container_name": "etcd2", - "container_image": "quay.io:4443/coreos/etcd", - "cpu": "cpu3", - "container_version": "v2.2.2", - "engine_host": "absol", - "label2": "test_value_2", - }, - ) +} +func TestDockerGatherLabels(t *testing.T) { + for _, tt := range gatherLabelsTests { + var acc testutil.Accumulator + d := Docker{ + client: nil, + testing: true, + } + + for _, label := range tt.include { + d.LabelInclude = append(d.LabelInclude, label) + } + for _, label := range tt.exclude { + d.LabelExclude = append(d.LabelExclude, label) + } + + err := d.Gather(&acc) + require.NoError(t, err) + + var expectedErrors []string + for _, label := range tt.expected { + if !acc.HasTag("docker_container_cpu", label) { + expectedErrors = append(expectedErrors, fmt.Sprintf("%s ", label)) + } + } + + var notexpectedErrors []string + for _, label := range tt.notexpected { + if acc.HasTag("docker_container_cpu", label) { + notexpectedErrors = append(notexpectedErrors, fmt.Sprintf("%s ", label)) + } + } + + if len(expectedErrors) > 0 || len(notexpectedErrors) > 0 { + t.Errorf("Failed test for: Include: %s Exclude: %s", tt.include, tt.exclude) + } + } } func TestDockerGatherInfo(t *testing.T) { @@ -324,11 +308,6 @@ func TestDockerGatherInfo(t *testing.T) { testing: true, } - /* In order to not modify code here, we set this to false since the container structure now has - labels and the default is true. - */ - - d.LabelExclude = append(d.LabelExclude, "*") err := d.Gather(&acc) require.NoError(t, err) @@ -372,6 +351,8 @@ func TestDockerGatherInfo(t *testing.T) { "cpu": "cpu3", "container_version": "v2.2.2", "engine_host": "absol", + "label1": "test_value_1", + "label2": "test_value_2", }, ) acc.AssertContainsTaggedFields(t, @@ -418,6 +399,8 @@ func TestDockerGatherInfo(t *testing.T) { "container_name": "etcd2", "container_image": "quay.io:4443/coreos/etcd", "container_version": "v2.2.2", + "label1": "test_value_1", + "label2": "test_value_2", }, ) From aff8018f3732c44c987a8dbfa5d42a9465e27972 Mon Sep 17 00:00:00 2001 From: Shakeel Sorathia Date: Mon, 27 Mar 2017 16:48:20 -0700 Subject: [PATCH 09/10] - go fmt --- plugins/inputs/docker/docker_test.go | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/plugins/inputs/docker/docker_test.go b/plugins/inputs/docker/docker_test.go index f606dc70a504f..9de07d16a2a29 100644 --- a/plugins/inputs/docker/docker_test.go +++ b/plugins/inputs/docker/docker_test.go @@ -6,9 +6,9 @@ import ( "github.com/influxdata/telegraf/testutil" + "fmt" "github.com/docker/docker/api/types" "github.com/stretchr/testify/require" - "fmt" ) func TestDockerGatherContainerStats(t *testing.T) { @@ -251,16 +251,15 @@ var gatherLabelsTests = []struct { expected []string notexpected []string }{ - {[]string{}, []string{}, []string{"label1","label2"}, []string{}}, - {[]string{"*"}, []string{}, []string{"label1","label2"}, []string{}}, - {[]string{"lab*"}, []string{}, []string{"label1","label2"}, []string{}}, - {[]string{"label1"}, []string{}, []string{"label1"}, []string{"label2"}}, - {[]string{"label1*"}, []string{}, []string{"label1"}, []string{"label2"}}, - {[]string{}, []string{"*"}, []string{}, []string{"label1","label2"}}, - {[]string{}, []string{"lab*"}, []string{}, []string{"label1","label2"}}, - {[]string{}, []string{"label1"}, []string{"label2"}, []string{"label1"}}, - {[]string{"*"}, []string{"*"}, []string{}, []string{"label1","label2"}}, - + {[]string{}, []string{}, []string{"label1", "label2"}, []string{}}, + {[]string{"*"}, []string{}, []string{"label1", "label2"}, []string{}}, + {[]string{"lab*"}, []string{}, []string{"label1", "label2"}, []string{}}, + {[]string{"label1"}, []string{}, []string{"label1"}, []string{"label2"}}, + {[]string{"label1*"}, []string{}, []string{"label1"}, []string{"label2"}}, + {[]string{}, []string{"*"}, []string{}, []string{"label1", "label2"}}, + {[]string{}, []string{"lab*"}, []string{}, []string{"label1", "label2"}}, + {[]string{}, []string{"label1"}, []string{"label2"}, []string{"label1"}}, + {[]string{"*"}, []string{"*"}, []string{}, []string{"label1", "label2"}}, } func TestDockerGatherLabels(t *testing.T) { From f3ee8aa3beb257af5e7629f76b61c99a81e2d2d0 Mon Sep 17 00:00:00 2001 From: Shakeel Sorathia Date: Mon, 3 Apr 2017 13:05:02 -0700 Subject: [PATCH 10/10] - move filter creation to function - created a bool such that we only compile the filter on the first gather - no longer collecting errors but rather displaying them as we go along - Changelog updated --- CHANGELOG.md | 1 + plugins/inputs/docker/docker.go | 45 ++++++++++++++++++---------- plugins/inputs/docker/docker_test.go | 13 +++----- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa4b820c7e341..e7da095d4eba7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ be deprecated eventually. - [#2332](https://github.com/influxdata/telegraf/pull/2332): Add Elasticsearch 5.x output - [#2587](https://github.com/influxdata/telegraf/pull/2587): Add json timestamp units configurability - [#2597](https://github.com/influxdata/telegraf/issues/2597): Add support for Linux sysctl-fs metrics. +- [#2425](https://github.com/influxdata/telegraf/pull/2425): Support to include/exclude docker container labels as tags ### Bugfixes diff --git a/plugins/inputs/docker/docker.go b/plugins/inputs/docker/docker.go index c333d57010828..47d1db14b09ec 100644 --- a/plugins/inputs/docker/docker.go +++ b/plugins/inputs/docker/docker.go @@ -40,7 +40,8 @@ type Docker struct { client *client.Client engine_host string - testing bool + testing bool + labelFiltersCreated bool } // infoWrapper wraps client.Client.List for testing. @@ -146,22 +147,13 @@ func (d *Docker) Gather(acc telegraf.Accumulator) error { } d.client = c } - - // Create label filters - if len(d.LabelInclude) != 0 { - var err error - d.LabelFilter.labelInclude, err = filter.Compile(d.LabelInclude) - if err != nil { - return err - } - } - - if len(d.LabelExclude) != 0 { - var err error - d.LabelFilter.labelExclude, err = filter.Compile(d.LabelExclude) + // Create label filters if not already created + if !d.labelFiltersCreated { + err := d.createLabelFilters() if err != nil { return err } + d.labelFiltersCreated = true } // Get daemon info @@ -633,11 +625,32 @@ func parseSize(sizeStr string) (int64, error) { return int64(size), nil } +func (d *Docker) createLabelFilters() error { + if len(d.LabelInclude) != 0 && d.LabelFilter.labelInclude == nil { + var err error + d.LabelFilter.labelInclude, err = filter.Compile(d.LabelInclude) + if err != nil { + return err + } + } + + if len(d.LabelExclude) != 0 && d.LabelFilter.labelExclude == nil { + var err error + d.LabelFilter.labelExclude, err = filter.Compile(d.LabelExclude) + if err != nil { + return err + } + } + + return nil +} + func init() { inputs.Add("docker", func() telegraf.Input { return &Docker{ - PerDevice: true, - Timeout: internal.Duration{Duration: time.Second * 5}, + PerDevice: true, + Timeout: internal.Duration{Duration: time.Second * 5}, + labelFiltersCreated: false, } }) } diff --git a/plugins/inputs/docker/docker_test.go b/plugins/inputs/docker/docker_test.go index 9de07d16a2a29..3e2e1607b4c08 100644 --- a/plugins/inputs/docker/docker_test.go +++ b/plugins/inputs/docker/docker_test.go @@ -6,7 +6,6 @@ import ( "github.com/influxdata/telegraf/testutil" - "fmt" "github.com/docker/docker/api/types" "github.com/stretchr/testify/require" ) @@ -280,23 +279,19 @@ func TestDockerGatherLabels(t *testing.T) { err := d.Gather(&acc) require.NoError(t, err) - var expectedErrors []string for _, label := range tt.expected { if !acc.HasTag("docker_container_cpu", label) { - expectedErrors = append(expectedErrors, fmt.Sprintf("%s ", label)) + t.Errorf("Didn't get expected label of %s. Test was: Include: %s Exclude %s", + label, tt.include, tt.exclude) } } - var notexpectedErrors []string for _, label := range tt.notexpected { if acc.HasTag("docker_container_cpu", label) { - notexpectedErrors = append(notexpectedErrors, fmt.Sprintf("%s ", label)) + t.Errorf("Got unexpected label of %s. Test was: Include: %s Exclude %s", + label, tt.include, tt.exclude) } } - - if len(expectedErrors) > 0 || len(notexpectedErrors) > 0 { - t.Errorf("Failed test for: Include: %s Exclude: %s", tt.include, tt.exclude) - } } }