From cd0702e2ba93ddfa540adc68edbece5eeef34af9 Mon Sep 17 00:00:00 2001 From: rsingh2411 Date: Tue, 28 Mar 2017 10:11:18 +0000 Subject: [PATCH] Add Docker container environment variables as tags. Only whitelisted #2580 --- plugins/inputs/docker/docker.go | 41 ++++++++++++++++++++++++---- plugins/inputs/docker/docker_test.go | 9 ++++-- plugins/inputs/docker/fake_client.go | 15 ++++++++++ 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/plugins/inputs/docker/docker.go b/plugins/inputs/docker/docker.go index ec192efd5e5d3..9b159de60640c 100644 --- a/plugins/inputs/docker/docker.go +++ b/plugins/inputs/docker/docker.go @@ -22,11 +22,12 @@ import ( // Docker object type Docker struct { - Endpoint string - ContainerNames []string - Timeout internal.Duration - PerDevice bool `toml:"perdevice"` - Total bool `toml:"total"` + Endpoint string + ContainerNames []string + Timeout internal.Duration + PerDevice bool `toml:"perdevice"` + Total bool `toml:"total"` + GatherEnvironment []string `toml:"gather_environment"` client *client.Client engine_host string @@ -70,6 +71,18 @@ func statsWrapper( return fc.ContainerStats(ctx, containerID, stream) } +func inspectWrapper( + c *client.Client, + ctx context.Context, + containerID string, +) (types.ContainerJSON, error) { + if c != nil { + return c.ContainerInspect(ctx, containerID) + } + fc := FakeDockerClient{} + return fc.ContainerInspect(ctx, containerID) +} + // KB, MB, GB, TB, PB...human friendly const ( KB = 1000 @@ -98,6 +111,8 @@ var sampleConfig = ` perdevice = true ## Whether to report for each container total blkio and network stats or not total = false + ## Which environment variables should we use as a tag + gather_environment = ["ENV", "DC"] ` @@ -296,6 +311,22 @@ func (d *Docker) gatherContainer( tags[k] = label } + // Add whitelisted environment variables to tags + if len(d.GatherEnvironment) > 0 { + info, err := inspectWrapper(d.client, ctx, container.ID) + if err != nil { + return fmt.Errorf("Error getting docker container inspect: %s", err.Error()) + } + + for _, envvar := range info.Config.Env { + kvs := strings.SplitN(envvar, "=", 2) + if !sliceContains(kvs[0], d.GatherEnvironment) { + continue + } + tags[kvs[0]] = kvs[1] + } + } + gatherContainerStats(v, acc, tags, container.ID, d.PerDevice, d.Total) return nil diff --git a/plugins/inputs/docker/docker_test.go b/plugins/inputs/docker/docker_test.go index f0add03ea20c4..712288654e897 100644 --- a/plugins/inputs/docker/docker_test.go +++ b/plugins/inputs/docker/docker_test.go @@ -247,8 +247,9 @@ func testStats() *types.StatsJSON { func TestDockerGatherInfo(t *testing.T) { var acc testutil.Accumulator d := Docker{ - client: nil, - testing: true, + client: nil, + testing: true, + GatherEnvironment: []string{"ENVVAR1", "ENVVAR2"}, } err := d.Gather(&acc) @@ -294,6 +295,8 @@ func TestDockerGatherInfo(t *testing.T) { "cpu": "cpu3", "container_version": "v2.2.2", "engine_host": "absol", + "ENVVAR1": "loremipsum", + "ENVVAR2": "dolorsitamet", }, ) acc.AssertContainsTaggedFields(t, @@ -340,6 +343,8 @@ func TestDockerGatherInfo(t *testing.T) { "container_name": "etcd2", "container_image": "quay.io:4443/coreos/etcd", "container_version": "v2.2.2", + "ENVVAR1": "loremipsum", + "ENVVAR2": "dolorsitamet", }, ) diff --git a/plugins/inputs/docker/fake_client.go b/plugins/inputs/docker/fake_client.go index 03da23198a890..6e2a2d4ec06de 100644 --- a/plugins/inputs/docker/fake_client.go +++ b/plugins/inputs/docker/fake_client.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/registry" ) @@ -141,3 +142,17 @@ func (d FakeDockerClient) ContainerStats(ctx context.Context, containerID string stat.Body = ioutil.NopCloser(strings.NewReader(jsonStat)) return stat, nil } + +func (d FakeDockerClient) ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error) { + json := types.ContainerJSON{ + Config: &container.Config{ + Env: []string{ + "ENVVAR1=loremipsum", + "ENVVAR2=dolorsitamet", + "PATH=/bin:/sbin", + }, + }, + } + + return json, nil +}