Skip to content

Commit

Permalink
[receiver/dockerstats] Add optional resource attributes (open-telemet…
Browse files Browse the repository at this point in the history
…ry#21185)

**Description:** <Describe what has changed.>
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue.
Ex. Adding a feature - Explain what this achieves.-->
Add `container.image.id` and `container.command_line` as optional
resource attributes, disabled by default.



**Link to tracking Issue:** <Issue number if applicable>

Tracking issue
open-telemetry#21092

**Testing:** <Describe what testing was performed and which tests were
added.>

Until this point, all resource attributes have been enabled by default,
resulting in the coupling of the
[test](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/7bf5d66fae6c1c5360ec2875948f2c2adab6c44f/receiver/dockerstatsreceiver/receiver_test.go#L191)
to the default configuration. In order to test the current
implementation with the new resource attributes enabled & disabled, a
minor refactoring was required in the `TestScrapeV2` test, allowing to
pass different configurations for each test.

Refer to the following commit 508dbee9aa9a22c1ca79f16bba5abeecceeb9c48
to check the refactor in the test.

**Documentation:** <Describe the documentation added.>

New resource attributes documentation was generated by `mdatagen`.
  • Loading branch information
marcsanmi authored and Caleb-Hurshman committed Jul 6, 2023
1 parent 9e4b437 commit 338cdb3
Show file tree
Hide file tree
Showing 19 changed files with 2,159 additions and 744 deletions.
16 changes: 16 additions & 0 deletions .chloggen/docker-add-optional-resource-attributes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: dockerstatsreceiver

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: "Add `container.image.id` and `container.command_line` optional resource attributes"

# One or more tracking issues related to the change
issues: [21092]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:
2 changes: 2 additions & 0 deletions receiver/dockerstatsreceiver/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -718,8 +718,10 @@ Time elapsed since container start time.

| Name | Description | Values | Enabled |
| ---- | ----------- | ------ | ------- |
| container.command_line | The full command executed by the container. | Any Str | false |
| container.hostname | The hostname of the container. | Any Str | true |
| container.id | The ID of the container. | Any Str | true |
| container.image.id | The ID of the container image. | Any Str | false |
| container.image.name | The name of the docker image in use by the container. | Any Str | true |
| container.name | The name of the container. | Any Str | true |
| container.runtime | The runtime of the container. For this receiver, it will always be 'docker'. | Any Str | true |
18 changes: 13 additions & 5 deletions receiver/dockerstatsreceiver/internal/metadata/generated_config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,14 @@ all_set:
container.uptime:
enabled: true
resource_attributes:
container.command_line:
enabled: true
container.hostname:
enabled: true
container.id:
enabled: true
container.image.id:
enabled: true
container.image.name:
enabled: true
container.name:
Expand Down Expand Up @@ -283,10 +287,14 @@ none_set:
container.uptime:
enabled: false
resource_attributes:
container.command_line:
enabled: false
container.hostname:
enabled: false
container.id:
enabled: false
container.image.id:
enabled: false
container.image.name:
enabled: false
container.name:
Expand Down
8 changes: 8 additions & 0 deletions receiver/dockerstatsreceiver/metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ resource_attributes:
description: "The hostname of the container."
type: string
enabled: true
container.image.id:
description: "The ID of the container image."
type: string
enabled: false
container.command_line:
description: "The full command executed by the container."
type: string
enabled: false

attributes:
core:
Expand Down
5 changes: 4 additions & 1 deletion receiver/dockerstatsreceiver/receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,10 @@ func (r *receiver) recordContainerStats(now pcommon.Timestamp, containerStats *d
metadata.WithContainerHostname(container.Config.Hostname),
metadata.WithContainerID(container.ID),
metadata.WithContainerImageName(container.Config.Image),
metadata.WithContainerName(strings.TrimPrefix(container.Name, "/")))
metadata.WithContainerName(strings.TrimPrefix(container.Name, "/")),
metadata.WithContainerImageID(container.Image),
metadata.WithContainerCommandLine(strings.Join(container.Config.Cmd, " ")),
)

for k, label := range r.config.EnvVarsToMetricLabels {
label := label
Expand Down
99 changes: 86 additions & 13 deletions receiver/dockerstatsreceiver/receiver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ var (
ContainerMemoryAnon: metricEnabled,
ContainerMemoryFile: metricEnabled,
}

resourceAttributeEnabled = metadata.ResourceAttributeConfig{Enabled: true}
allResourceAttributesEnabled = metadata.ResourceAttributesConfig{
ContainerCommandLine: resourceAttributeEnabled,
ContainerHostname: resourceAttributeEnabled,
ContainerID: resourceAttributeEnabled,
ContainerImageID: resourceAttributeEnabled,
ContainerImageName: resourceAttributeEnabled,
ContainerName: resourceAttributeEnabled,
ContainerRuntime: resourceAttributeEnabled,
}
)

func TestNewReceiver(t *testing.T) {
Expand Down Expand Up @@ -145,6 +156,7 @@ func TestScrapeV2(t *testing.T) {
desc string
expectedMetricsFile string
mockDockerEngine func(t *testing.T) *httptest.Server
cfgBuilder *testConfigBuilder
}{
{
desc: "scrapeV2_single_container",
Expand All @@ -160,6 +172,9 @@ func TestScrapeV2(t *testing.T) {
require.NoError(t, err)
return mockServer
},
cfgBuilder: newTestConfigBuilder().
withDefaultLabels().
withMetrics(allMetricsEnabled),
},
{
desc: "scrapeV2_two_containers",
Expand All @@ -180,6 +195,9 @@ func TestScrapeV2(t *testing.T) {
require.NoError(t, err)
return mockServer
},
cfgBuilder: newTestConfigBuilder().
withDefaultLabels().
withMetrics(allMetricsEnabled),
},
{
desc: "scrapeV2_no_pids_stats",
Expand All @@ -195,6 +213,9 @@ func TestScrapeV2(t *testing.T) {
require.NoError(t, err)
return mockServer
},
cfgBuilder: newTestConfigBuilder().
withDefaultLabels().
withMetrics(allMetricsEnabled),
},
{
desc: "scrapeV2_pid_stats_max",
Expand All @@ -210,6 +231,9 @@ func TestScrapeV2(t *testing.T) {
require.NoError(t, err)
return mockServer
},
cfgBuilder: newTestConfigBuilder().
withDefaultLabels().
withMetrics(allMetricsEnabled),
},
{
desc: "cgroups_v2_container",
Expand All @@ -224,6 +248,27 @@ func TestScrapeV2(t *testing.T) {
require.NoError(t, err)
return mockServer
},
cfgBuilder: newTestConfigBuilder().
withDefaultLabels().
withMetrics(allMetricsEnabled),
},
{
desc: "scrapeV2_single_container_with_optional_resource_attributes",
expectedMetricsFile: filepath.Join(mockFolder, "single_container_with_optional_resource_attributes", "expected_metrics.yaml"),
mockDockerEngine: func(t *testing.T) *httptest.Server {
containerID := "73364842ef014441cac89fed05df19463b1230db25a31252cdf82e754f1ec581"
mockServer, err := dockerMockServer(&map[string]string{
"/v1.23/containers/json": filepath.Join(mockFolder, "single_container_with_optional_resource_attributes", "containers.json"),
"/v1.23/containers/" + containerID + "/json": filepath.Join(mockFolder, "single_container_with_optional_resource_attributes", "container.json"),
"/v1.23/containers/" + containerID + "/stats": filepath.Join(mockFolder, "single_container_with_optional_resource_attributes", "stats.json"),
})
require.NoError(t, err)
return mockServer
},
cfgBuilder: newTestConfigBuilder().
withDefaultLabels().
withMetrics(allMetricsEnabled).
withResourceAttributes(allResourceAttributesEnabled),
},
}

Expand All @@ -232,19 +277,8 @@ func TestScrapeV2(t *testing.T) {
mockDockerEngine := tc.mockDockerEngine(t)
defer mockDockerEngine.Close()

cfg := createDefaultConfig().(*Config)
cfg.Endpoint = mockDockerEngine.URL
cfg.EnvVarsToMetricLabels = map[string]string{
"ENV_VAR": "env-var-metric-label",
"ENV_VAR_2": "env-var-metric-label-2",
}
cfg.ContainerLabelsToMetricLabels = map[string]string{
"container.label": "container-metric-label",
"container.label.2": "container-metric-label-2",
}
cfg.MetricsBuilderConfig.Metrics = allMetricsEnabled

receiver := newReceiver(receivertest.NewNopCreateSettings(), cfg)
receiver := newReceiver(
receivertest.NewNopCreateSettings(), tc.cfgBuilder.withEndpoint(mockDockerEngine.URL).build())
err := receiver.start(context.Background(), componenttest.NewNopHost())
require.NoError(t, err)

Expand Down Expand Up @@ -335,3 +369,42 @@ func dockerMockServer(urlToFile *map[string]string) (*httptest.Server, error) {
_, _ = rw.Write(data)
})), nil
}

type testConfigBuilder struct {
config *Config
}

func newTestConfigBuilder() *testConfigBuilder {
return &testConfigBuilder{config: createDefaultConfig().(*Config)}
}

func (cb *testConfigBuilder) withEndpoint(endpoint string) *testConfigBuilder {
cb.config.Endpoint = endpoint
return cb
}

func (cb *testConfigBuilder) withMetrics(ms metadata.MetricsConfig) *testConfigBuilder {
cb.config.MetricsBuilderConfig.Metrics = ms
return cb
}

func (cb *testConfigBuilder) withResourceAttributes(ras metadata.ResourceAttributesConfig) *testConfigBuilder {
cb.config.MetricsBuilderConfig.ResourceAttributes = ras
return cb
}

func (cb *testConfigBuilder) withDefaultLabels() *testConfigBuilder {
cb.config.EnvVarsToMetricLabels = map[string]string{
"ENV_VAR": "env-var-metric-label",
"ENV_VAR_2": "env-var-metric-label-2",
}
cb.config.ContainerLabelsToMetricLabels = map[string]string{
"container.label": "container-metric-label",
"container.label.2": "container-metric-label-2",
}
return cb
}

func (cb *testConfigBuilder) build() *Config {
return cb.config
}
Loading

0 comments on commit 338cdb3

Please sign in to comment.