From 0490b9a61d9632ccdd8939ba223ba7e0fd5b9534 Mon Sep 17 00:00:00 2001 From: Antoine POPINEAU Date: Wed, 14 Dec 2016 14:12:03 +0100 Subject: [PATCH] Add Docker container environment variables as tags. Only whitelisted envvars will be processed. --- plugins/inputs/docker/README.md | 2 ++ plugins/inputs/docker/docker.go | 30 +++++++++++++++++++++++----- plugins/inputs/docker/docker_test.go | 21 ++++++++++++++++++- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/plugins/inputs/docker/README.md b/plugins/inputs/docker/README.md index 5e8910677..9c13619c9 100644 --- a/plugins/inputs/docker/README.md +++ b/plugins/inputs/docker/README.md @@ -22,6 +22,8 @@ for the stat structure can be found endpoint = "unix:///var/run/docker.sock" # Only collect metrics for these containers, collect all if empty container_names = [] + # Which environment variables should we use as a tag + gather_environment = ["ENV", "DC"] ``` ### Measurements & Fields: diff --git a/plugins/inputs/docker/docker.go b/plugins/inputs/docker/docker.go index e2c488dc8..19be2ed4d 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 DockerClient engine_host string @@ -37,6 +38,7 @@ type DockerClient interface { Info(ctx context.Context) (types.Info, error) ContainerList(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error) ContainerStats(ctx context.Context, containerID string, stream bool) (io.ReadCloser, error) + ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error) } // KB, MB, GB, TB, PB...human friendly @@ -67,6 +69,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"] ` @@ -261,6 +265,22 @@ func (d *Docker) gatherContainer( tags[k] = label } + // Add whitelisted environment variables to tags + if len(d.GatherEnvironment) > 0 { + info, err := d.client.ContainerInspect(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 21960a4d8..d250950ae 100644 --- a/plugins/inputs/docker/docker_test.go +++ b/plugins/inputs/docker/docker_test.go @@ -10,6 +10,7 @@ import ( "golang.org/x/net/context" "github.com/docker/engine-api/types" + "github.com/docker/engine-api/types/container" "github.com/docker/engine-api/types/registry" "github.com/influxdata/telegraf/testutil" @@ -384,10 +385,24 @@ func (d FakeDockerClient) ContainerStats(ctx context.Context, containerID string 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 +} + func TestDockerGatherInfo(t *testing.T) { var acc testutil.Accumulator client := FakeDockerClient{} - d := Docker{client: client} + d := Docker{client: client, GatherEnvironment: []string{"ENVVAR1", "ENVVAR2"}} err := d.Gather(&acc) @@ -433,6 +448,8 @@ func TestDockerGatherInfo(t *testing.T) { "cpu": "cpu3", "container_version": "v2.2.2", "engine_host": "absol", + "ENVVAR1": "loremipsum", + "ENVVAR2": "dolorsitamet", }, ) acc.AssertContainsTaggedFields(t, @@ -479,6 +496,8 @@ func TestDockerGatherInfo(t *testing.T) { "container_name": "etcd2", "container_image": "quay.io/coreos/etcd", "container_version": "v2.2.2", + "ENVVAR1": "loremipsum", + "ENVVAR2": "dolorsitamet", }, )