Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Containers can now be identified by the container ID #6473

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions plugins/inputs/docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ to gather stats from the [Engine API](https://docs.docker.com/engine/api/v1.24/)
## Deprecated (1.4.0), use container_name_include
container_names = []

## Set the source tag for the metrics to the container ID hostname, eg first 12 chars
source_tag = false

## Containers to include and exclude. Collect all if empty. Globs accepted.
container_name_include = []
container_name_exclude = []
Expand Down Expand Up @@ -93,6 +96,17 @@ volumes:
- /var/run/docker.sock:/var/run/docker.sock
```

#### source tag

Selecting the containers measurements can be tricky if you have many containers with the same name.
To alleviate this issue you can set the below value to `true`

```toml
source_tag = true
```

This will cause all measurements to have the `source` tag be set to the first 12 characters of the container id. The first 12 characters is the common hostname for containers that have no explicit hostname set, as defined by docker.

#### Kubernetes Labels

Kubernetes may add many labels to your containers, if they are not needed you
Expand Down
16 changes: 16 additions & 0 deletions plugins/inputs/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ type Docker struct {
ContainerStateInclude []string `toml:"container_state_include"`
ContainerStateExclude []string `toml:"container_state_exclude"`

IncludeSourceTag bool `toml:"source_tag"`

Log telegraf.Logger

tlsint.ClientConfig
Expand Down Expand Up @@ -90,6 +92,9 @@ var sampleConfig = `
## Only collect metrics for these containers, collect all if empty
container_names = []

## Set the source tag for the metrics to the container ID hostname, eg first 12 chars
source_tag = false

## Containers to include and exclude. Globs accepted.
## Note that an empty array for both will include all containers
container_name_include = []
Expand Down Expand Up @@ -412,6 +417,13 @@ func (d *Docker) gatherInfo(acc telegraf.Accumulator) error {
return nil
}

func hostnameFromID(id string) string {
if len(id) > 12 {
return id[0:12]
}
return id
}

func (d *Docker) gatherContainer(
container types.Container,
acc telegraf.Accumulator,
Expand Down Expand Up @@ -443,6 +455,10 @@ func (d *Docker) gatherContainer(
"container_version": imageVersion,
}

if d.IncludeSourceTag {
tags["source"] = hostnameFromID(container.ID)
}

ctx, cancel := context.WithTimeout(context.Background(), d.Timeout.Duration)
defer cancel()

Expand Down
40 changes: 38 additions & 2 deletions plugins/inputs/docker/docker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -629,8 +629,9 @@ func TestContainerStatus(t *testing.T) {
return &client, nil
}
d = Docker{
Log: testutil.Logger{},
newClient: newClientFunc,
Log: testutil.Logger{},
newClient: newClientFunc,
IncludeSourceTag: true,
}
)

Expand Down Expand Up @@ -673,6 +674,7 @@ func TestContainerStatus(t *testing.T) {
"label2": "test_value_2",
"server_version": "17.09.0-ce",
"container_status": tt.expect.Status,
"source": "e2173b9478a6",
})
})
}
Expand Down Expand Up @@ -1017,3 +1019,37 @@ func TestContainerName(t *testing.T) {
})
}
}

func TestHostnameFromID(t *testing.T) {
tests := []struct {
name string
id string
expect string
}{
{
name: "Real ID",
id: "565e3a55f5843cfdd4aa5659a1a75e4e78d47f73c3c483f782fe4a26fc8caa07",
expect: "565e3a55f584",
},
{
name: "Short ID",
id: "shortid123",
expect: "shortid123",
},
{
name: "No ID",
id: "",
expect: "shortid123",
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
output := hostnameFromID(test.id)
if test.expect != output {
t.Logf("Container ID for hostname is wrong. Want: %s, Got: %s", output, test.expect)
}
})
}

}
15 changes: 15 additions & 0 deletions plugins/inputs/docker_log/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ The docker plugin uses the [Official Docker Client][] to gather logs from the
# docker_label_include = []
# docker_label_exclude = []

## Set the source tag for the metrics to the container ID hostname, eg first 12 chars
source_tag = false

## Optional TLS Config
# tls_ca = "/etc/telegraf/ca.pem"
# tls_cert = "/etc/telegraf/cert.pem"
Expand All @@ -58,6 +61,17 @@ When using the `"ENV"` endpoint, the connection is configured using the

[env]: https://godoc.org/github.com/moby/moby/client#NewEnvClient

### source tag

Selecting the containers can be tricky if you have many containers with the same name.
To alleviate this issue you can set the below value to `true`

```toml
source_tag = true
```

This will cause all data points to have the `source` tag be set to the first 12 characters of the container id. The first 12 characters is the common hostname for containers that have no explicit hostname set, as defined by docker.

### Metrics

- docker_log
Expand All @@ -66,6 +80,7 @@ When using the `"ENV"` endpoint, the connection is configured using the
- container_version
- container_name
- stream (stdout, stderr, or tty)
- source
- fields:
- container_id
- message
Expand Down
15 changes: 15 additions & 0 deletions plugins/inputs/docker_log/docker_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ var sampleConfig = `
# docker_label_include = []
# docker_label_exclude = []

## Set the source tag for the metrics to the container ID hostname, eg first 12 chars
source_tag = false

## Optional TLS Config
# tls_ca = "/etc/telegraf/ca.pem"
# tls_cert = "/etc/telegraf/cert.pem"
Expand Down Expand Up @@ -82,6 +85,7 @@ type DockerLogs struct {
ContainerExclude []string `toml:"container_name_exclude"`
ContainerStateInclude []string `toml:"container_state_include"`
ContainerStateExclude []string `toml:"container_state_exclude"`
IncludeSourceTag bool `toml:"source_tag"`

tlsint.ClientConfig

Expand Down Expand Up @@ -258,6 +262,10 @@ func (d *DockerLogs) tailContainerLogs(
"container_version": imageVersion,
}

if d.IncludeSourceTag {
tags["source"] = hostnameFromID(container.ID)
}

// Add matching container labels as tags
for k, label := range container.Labels {
if d.labelFilter.Match(k) {
Expand Down Expand Up @@ -435,3 +443,10 @@ func init() {
}
})
}

func hostnameFromID(id string) string {
if len(id) > 12 {
return id[0:12]
}
return id
}
9 changes: 6 additions & 3 deletions plugins/inputs/docker_log/docker_log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ func Test(t *testing.T) {
"container_image": "influxdata/telegraf",
"container_version": "1.11.0",
"stream": "tty",
"source": "deadbeef",
},
map[string]interface{}{
"container_id": "deadbeef",
Expand Down Expand Up @@ -141,6 +142,7 @@ func Test(t *testing.T) {
"container_image": "influxdata/telegraf",
"container_version": "1.11.0",
"stream": "stdout",
"source": "deadbeef",
},
map[string]interface{}{
"container_id": "deadbeef",
Expand All @@ -155,9 +157,10 @@ func Test(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
var acc testutil.Accumulator
plugin := &DockerLogs{
Timeout: internal.Duration{Duration: time.Second * 5},
newClient: func(string, *tls.Config) (Client, error) { return tt.client, nil },
containerList: make(map[string]context.CancelFunc),
Timeout: internal.Duration{Duration: time.Second * 5},
newClient: func(string, *tls.Config) (Client, error) { return tt.client, nil },
containerList: make(map[string]context.CancelFunc),
IncludeSourceTag: true,
}

err := plugin.Init()
Expand Down