diff --git a/plugins/inputs/docker/docker.go b/plugins/inputs/docker/docker.go index c436db40239f9..395c45feb3054 100644 --- a/plugins/inputs/docker/docker.go +++ b/plugins/inputs/docker/docker.go @@ -24,23 +24,32 @@ type DockerLabelFilter struct { labelExclude filter.Filter } +type DockerContainerFilter struct { + containerInclude filter.Filter + containerExclude filter.Filter +} + // Docker object type Docker struct { Endpoint string ContainerNames []string + + ContainerInclude []string `toml:"container_name_include"` + ContainerExclude []string `toml:"container_name_exclude"` + ContainerFilter DockerContainerFilter + Timeout internal.Duration PerDevice bool `toml:"perdevice"` Total bool `toml:"total"` + LabelInclude []string `toml:"docker_label_include"` LabelExclude []string `toml:"docker_label_exclude"` - LabelFilter DockerLabelFilter client *client.Client engine_host string testing bool - labelFiltersCreated bool onlyRunning bool `toml:"only_running"` } @@ -99,8 +108,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" @@ -152,14 +168,6 @@ func (d *Docker) Gather(acc telegraf.Accumulator) error { } d.client = c } - // Create label filters if not already created - if !d.labelFiltersCreated { - err := d.createLabelFilters() - if err != nil { - return err - } - d.labelFiltersCreated = true - } // Get daemon info err := d.gatherInfo(acc) @@ -182,7 +190,6 @@ func (d *Docker) Gather(acc telegraf.Accumulator) error { for _, container := range containers { go func(c types.Container) { defer wg.Done() - if (d.onlyRunning && c.State == "running") || (!d.onlyRunning) { err := d.gatherContainer(c, acc) if err != nil { @@ -306,6 +313,12 @@ func (d *Docker) gatherContainer( } } + 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) defer cancel() r, err := statsWrapper(d.client, ctx, container.ID, false) @@ -633,8 +646,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 { @@ -642,7 +675,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 { @@ -654,11 +687,13 @@ func (d *Docker) createLabelFilters() error { } func init() { + d := Docker{} + d.PerDevice = true + d.Timeout = internal.Duration{Duration: time.Second * 5} + d.createContainerFilters() + d.createLabelFilters() + inputs.Add("docker", func() telegraf.Input { - return &Docker{ - PerDevice: true, - Timeout: internal.Duration{Duration: time.Second * 5}, - labelFiltersCreated: false, - } + return &d }) }