From 2d75b5d65016f776ad11a28931dc8ceceba189f5 Mon Sep 17 00:00:00 2001 From: Matteo Cerutti Date: Fri, 12 May 2017 15:46:52 +0100 Subject: [PATCH] Adding wildcard support for container inclusion/exclusion. Solves #2734. --- plugins/inputs/docker/README.md | 8 ++++ plugins/inputs/docker/docker.go | 67 ++++++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/plugins/inputs/docker/README.md b/plugins/inputs/docker/README.md index 12741d940bcbc..771838dfecaa8 100644 --- a/plugins/inputs/docker/README.md +++ b/plugins/inputs/docker/README.md @@ -20,14 +20,22 @@ for the stat structure can be found ## To use TCP, set endpoint = "tcp://[ip]:[port]" ## To use environment variables (ie, docker-machine), set endpoint = "ENV" endpoint = "unix:///var/run/docker.sock" + ## Only collect metrics for these containers, collect all if empty container_names = [] + + ## Containers to include and exclude. Globs accepted. + ## Note that the options are ignored when using the container_names option. An empty array for both will include all containers + container_name_include = [] + container_name_exclude = [] + ## Timeout for docker list, info, and stats commands timeout = "5s" ## Whether to report for each container per-device blkio (8:0, 8:1...) and ## network (eth0, eth1, ...) stats or not perdevice = true + ## Whether to report for each container total blkio and network stats or not total = false diff --git a/plugins/inputs/docker/docker.go b/plugins/inputs/docker/docker.go index 13ade3945a676..3381782594d1b 100644 --- a/plugins/inputs/docker/docker.go +++ b/plugins/inputs/docker/docker.go @@ -24,24 +24,33 @@ type DockerLabelFilter struct { labelExclude filter.Filter } +type DockerContainerFilter struct { + containerInclude filter.Filter + containerExclude filter.Filter +} + // Docker object type Docker struct { Endpoint string ContainerNames []string + Timeout internal.Duration PerDevice bool `toml:"perdevice"` Total bool `toml:"total"` TagEnvironment []string `toml:"tag_env"` LabelInclude []string `toml:"docker_label_include"` LabelExclude []string `toml:"docker_label_exclude"` + LabelFilter DockerLabelFilter - LabelFilter DockerLabelFilter + ContainerInclude []string `toml:"container_name_include"` + ContainerExclude []string `toml:"container_name_exclude"` + ContainerFilter DockerContainerFilter client *client.Client engine_host string - testing bool - labelFiltersCreated bool + testing bool + filtersCreated bool } // infoWrapper wraps client.Client.List for testing. @@ -110,8 +119,15 @@ var sampleConfig = ` ## To use TCP, set endpoint = "tcp://[ip]:[port]" ## To use environment variables (ie, docker-machine), set endpoint = "ENV" endpoint = "unix:///var/run/docker.sock" + ## Only collect metrics for these containers, collect all if empty container_names = [] + + ## Containers to include and exclude. Globs accepted. + ## Note that an empty array for both will include all containers + container_name_include = [] + container_name_exclude = [] + ## Timeout for docker list, info, and stats commands timeout = "5s" @@ -161,13 +177,18 @@ func (d *Docker) Gather(acc telegraf.Accumulator) error { } d.client = c } + // Create label filters if not already created - if !d.labelFiltersCreated { + if !d.filtersCreated { err := d.createLabelFilters() if err != nil { return err } - d.labelFiltersCreated = true + err = d.createContainerFilters() + if err != nil { + return err + } + d.filtersCreated = true } // Get daemon info @@ -310,6 +331,12 @@ func (d *Docker) gatherContainer( if !sliceContains(cname, d.ContainerNames) { return nil } + } else { + if len(d.ContainerInclude) == 0 || !d.ContainerFilter.containerInclude.Match(cname) { + if len(d.ContainerExclude) > 0 && d.ContainerFilter.containerExclude.Match(cname) { + return nil + } + } } ctx, cancel := context.WithTimeout(context.Background(), d.Timeout.Duration) @@ -656,8 +683,28 @@ func parseSize(sizeStr string) (int64, error) { return int64(size), nil } +func (d *Docker) createContainerFilters() error { + if len(d.ContainerInclude) != 0 { + var err error + d.ContainerFilter.containerInclude, err = filter.Compile(d.ContainerInclude) + if err != nil { + return err + } + } + + if len(d.ContainerExclude) != 0 { + var err error + d.ContainerFilter.containerExclude, err = filter.Compile(d.ContainerExclude) + if err != nil { + return err + } + } + + return nil +} + func (d *Docker) createLabelFilters() error { - if len(d.LabelInclude) != 0 && d.LabelFilter.labelInclude == nil { + if len(d.LabelInclude) != 0 { var err error d.LabelFilter.labelInclude, err = filter.Compile(d.LabelInclude) if err != nil { @@ -665,7 +712,7 @@ func (d *Docker) createLabelFilters() error { } } - if len(d.LabelExclude) != 0 && d.LabelFilter.labelExclude == nil { + if len(d.LabelExclude) != 0 { var err error d.LabelFilter.labelExclude, err = filter.Compile(d.LabelExclude) if err != nil { @@ -679,9 +726,9 @@ func (d *Docker) createLabelFilters() error { func init() { inputs.Add("docker", func() telegraf.Input { return &Docker{ - PerDevice: true, - Timeout: internal.Duration{Duration: time.Second * 5}, - labelFiltersCreated: false, + PerDevice: true, + Timeout: internal.Duration{Duration: time.Second * 5}, + filtersCreated: false, } }) }