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

Updated dockerstatsreceiver to respect DOCKER_HOST env variable. #37589

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
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
13 changes: 13 additions & 0 deletions .chloggen/update-docker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
change_type: enhancement

component: dockerstatsreceiver

note: "Respect the `DOCKER_HOST` environment variable when resolving the Docker endpoint. The receiver now prioritizes the endpoint in the following order: YAML config > `DOCKER_HOST` env variable > default `unix:///var/run/docker.sock`."

issues: [35779]

subtext: |
- Previously, the receiver required explicit configuration of the endpoint.
- This change allows automatic detection of `DOCKER_HOST`, improving flexibility in different environments.

change_logs: []
1 change: 1 addition & 0 deletions receiver/dockerstatsreceiver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Config struct {

// MetricsBuilderConfig config. Enable or disable stats by name.
metadata.MetricsBuilderConfig `mapstructure:",squash"`
Endpoint string
}

func (config Config) Validate() error {
Expand Down
20 changes: 20 additions & 0 deletions receiver/dockerstatsreceiver/receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package dockerstatsreceiver // import "github.com/open-telemetry/opentelemetry-c
import (
"context"
"fmt"
"os"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -44,6 +45,22 @@ type metricsReceiver struct {
cancel context.CancelFunc
}

const (
defaultEndpoint = "unix:///var/run/docker.sock"
dockerHostEnv = "DOCKER_HOST"
)

func (c *Config) resolveDockerEndpoint() string {
if c.Endpoint != "" {
return c.Endpoint
}

if dockerHost := os.Getenv(dockerHostEnv); dockerHost != "" {
return dockerHost
}
return defaultEndpoint
}

func newMetricsReceiver(set receiver.Settings, config *Config) *metricsReceiver {
return &metricsReceiver{
config: config,
Expand All @@ -53,6 +70,9 @@ func newMetricsReceiver(set receiver.Settings, config *Config) *metricsReceiver
}

func (r *metricsReceiver) start(ctx context.Context, _ component.Host) error {
// Resolve the Docker endpoint before creating the client
r.config.Endpoint = r.config.resolveDockerEndpoint()

var err error
r.client, err = docker.NewDockerClient(&r.config.Config, r.settings.Logger)
if err != nil {
Expand Down
66 changes: 66 additions & 0 deletions receiver/dockerstatsreceiver/receiver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,72 @@ var (
}
)

const (
DefaultEndpoint = "unix:///var/run/docker.sock"
DockerHostEnv = "DOCKER_HOST"
)

func TestResolveDockerEndpoint(t *testing.T) {
tests := []struct {
name string
cfg Config
env string
expected string
description string
}{
{
name: "Explicit endpoint in config",
cfg: Config{Endpoint: "tcp://192.168.1.100:2375"},
expected: "tcp://192.168.1.100:2375",
description: "Should return the endpoint from the config if it's set.",
},
{
name: "DOCKER_HOST env variable set",
cfg: Config{},
env: "tcp://dockerhost:2376",
expected: "tcp://dockerhost:2376",
description: "Should return the value of the DOCKER_HOST environment variable.",
},
{
name: "Default endpoint",
cfg: Config{},
expected: defaultEndpoint,
description: "Should return the default endpoint if no config or env variable is set.",
},
{
name: "Empty DOCKER_HOST env variable",
cfg: Config{},
env: "", // Explicitly set to empty string
expected: defaultEndpoint,
description: "Should return the default endpoint if DOCKER_HOST is empty.",
},
{
name: "Config takes precedence over DOCKER_HOST",
cfg: Config{Endpoint: "tcp://config:1234"},
env: "tcp://env:5678",
expected: "tcp://config:1234",
description: "Should return the config endpoint even if DOCKER_HOST is set.",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Set the environment variable for the test
if tt.env != "" {
os.Setenv(dockerHostEnv, tt.env)
defer os.Unsetenv(dockerHostEnv)
} else {
os.Unsetenv(dockerHostEnv)
}

got := tt.cfg.resolveDockerEndpoint()
if got != tt.expected {
t.Errorf("resolveDockerEndpoint() = %v, want %v, test: %s", got, tt.expected, tt.description)
}
})
}
}

func TestNewReceiver(t *testing.T) {
cfg := &Config{
ControllerConfig: scraperhelper.ControllerConfig{
Expand Down