Skip to content

Commit

Permalink
cli-plugins: remove docker.cli specific otel attributes after usage
Browse files Browse the repository at this point in the history
Remove the `docker.cli` prefixed attributes from
`OTEL_RESOURCE_ATTRIBUTES` after the telemetry provider has been created
within a plugin. This prevents accidentally sending the attributes to
something downstream for the user.

This also fixes an issue with compose where the self-injected `OTEL_RESOURCE_ATTRIBUTES`
would override an existing attribute in the environment file because the
"user environment" overrode the environment file, but the "user
environment" was created by the `docker` tool rather than by the user's
environment.

When `OTEL_RESOURCE_ATTRIBUTES` is empty after pruning, the environment
variable is unset.

Signed-off-by: Jonathan A. Sternberg <[email protected]>
  • Loading branch information
jsternberg committed Feb 18, 2025
1 parent cfe0605 commit ac5757f
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 3 deletions.
4 changes: 2 additions & 2 deletions cli-plugins/manager/cobra.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func AddPluginCommandStubs(dockerCli command.Cli, rootCmd *cobra.Command) (err e
}

const (
dockerCliAttributePrefix = attribute.Key("docker.cli")
dockerCliAttributePrefix = command.DockerCliAttributePrefix

cobraCommandPath = attribute.Key("cobra.command_path")
)
Expand All @@ -126,7 +126,7 @@ func getPluginResourceAttributes(cmd *cobra.Command, plugin Plugin) attribute.Se
for iter := attrSet.Iter(); iter.Next(); {
attr := iter.Attribute()
kvs = append(kvs, attribute.KeyValue{
Key: dockerCliAttributePrefix + "." + attr.Key,
Key: dockerCliAttributePrefix + attr.Key,
Value: attr.Value,
})
}
Expand Down
2 changes: 1 addition & 1 deletion cli-plugins/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const (

// ResourceAttributesEnvvar is the name of the envvar that includes additional
// resource attributes for OTEL.
ResourceAttributesEnvvar = "OTEL_RESOURCE_ATTRIBUTES"
ResourceAttributesEnvvar = command.ResourceAttributesEnvvar
)

// errPluginNotFound is the error returned when a plugin could not be found.
Expand Down
45 changes: 45 additions & 0 deletions cli/command/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"path/filepath"
"runtime"
"strconv"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -292,6 +293,7 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...CLIOption)
if cli.enableGlobalTracer {
cli.createGlobalTracerProvider(cli.baseCtx)
}
filterResourceAttributesEnvvar()

return nil
}
Expand Down Expand Up @@ -591,3 +593,46 @@ func DefaultContextStoreConfig() store.Config {
defaultStoreEndpoints...,
)
}

const (
// ResourceAttributesEnvvar is the name of the envvar that includes additional
// resource attributes for OTEL.
ResourceAttributesEnvvar = "OTEL_RESOURCE_ATTRIBUTES"

// DockerCliAttributePrefix is the prefix for any docker cli OTEL attributes.
DockerCliAttributePrefix = "docker.cli."
)

func filterResourceAttributesEnvvar() {
if v := os.Getenv(ResourceAttributesEnvvar); v != "" {
if filtered := filterResourceAttributes(v); filtered != "" {
os.Setenv(ResourceAttributesEnvvar, filtered)
} else {
os.Unsetenv(ResourceAttributesEnvvar)
}
}
}

func filterResourceAttributes(s string) string {
if trimmed := strings.TrimSpace(s); trimmed == "" {
return trimmed
}

pairs := strings.Split(s, ",")
elems := make([]string, 0, len(pairs))
for _, p := range pairs {
k, _, found := strings.Cut(p, "=")
if !found {
// Do not interact with invalid otel resources.
elems = append(elems, p)
continue
}

// Skip attributes that have our docker.cli prefix.
if strings.HasPrefix(k, DockerCliAttributePrefix) {
continue
}
elems = append(elems, p)
}
return strings.Join(elems, ",")
}

0 comments on commit ac5757f

Please sign in to comment.