cli-plugins: remove docker.cli specific otel attributes after usage
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 <jonathan.sternberg@docker.com>
This commit is contained in:
parent
cfe0605616
commit
8890a1c929
@ -107,7 +107,7 @@ func AddPluginCommandStubs(dockerCli command.Cli, rootCmd *cobra.Command) (err e
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
dockerCliAttributePrefix = attribute.Key("docker.cli")
|
dockerCliAttributePrefix = command.DockerCliAttributePrefix
|
||||||
|
|
||||||
cobraCommandPath = attribute.Key("cobra.command_path")
|
cobraCommandPath = attribute.Key("cobra.command_path")
|
||||||
)
|
)
|
||||||
@ -126,7 +126,7 @@ func getPluginResourceAttributes(cmd *cobra.Command, plugin Plugin) attribute.Se
|
|||||||
for iter := attrSet.Iter(); iter.Next(); {
|
for iter := attrSet.Iter(); iter.Next(); {
|
||||||
attr := iter.Attribute()
|
attr := iter.Attribute()
|
||||||
kvs = append(kvs, attribute.KeyValue{
|
kvs = append(kvs, attribute.KeyValue{
|
||||||
Key: dockerCliAttributePrefix + "." + attr.Key,
|
Key: dockerCliAttributePrefix + attr.Key,
|
||||||
Value: attr.Value,
|
Value: attr.Value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -135,12 +135,10 @@ func getPluginResourceAttributes(cmd *cobra.Command, plugin Plugin) attribute.Se
|
|||||||
|
|
||||||
func appendPluginResourceAttributesEnvvar(env []string, cmd *cobra.Command, plugin Plugin) []string {
|
func appendPluginResourceAttributesEnvvar(env []string, cmd *cobra.Command, plugin Plugin) []string {
|
||||||
if attrs := getPluginResourceAttributes(cmd, plugin); attrs.Len() > 0 {
|
if attrs := getPluginResourceAttributes(cmd, plugin); attrs.Len() > 0 {
|
||||||
// values in environment variables need to be in baggage format
|
|
||||||
// otel/baggage package can be used after update to v1.22, currently it encodes incorrectly
|
|
||||||
// Construct baggage members for each of the attributes.
|
// Construct baggage members for each of the attributes.
|
||||||
// Ignore any failures as these aren't significant and
|
// Ignore any failures as these aren't significant and
|
||||||
// represent an internal issue.
|
// represent an internal issue.
|
||||||
var b baggage.Baggage
|
members := make([]baggage.Member, 0, attrs.Len())
|
||||||
for iter := attrs.Iter(); iter.Next(); {
|
for iter := attrs.Iter(); iter.Next(); {
|
||||||
attr := iter.Attribute()
|
attr := iter.Attribute()
|
||||||
m, err := baggage.NewMemberRaw(string(attr.Key), attr.Value.AsString())
|
m, err := baggage.NewMemberRaw(string(attr.Key), attr.Value.AsString())
|
||||||
@ -148,13 +146,7 @@ func appendPluginResourceAttributesEnvvar(env []string, cmd *cobra.Command, plug
|
|||||||
otel.Handle(err)
|
otel.Handle(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
members = append(members, m)
|
||||||
newB, err := b.SetMember(m)
|
|
||||||
if err != nil {
|
|
||||||
otel.Handle(err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
b = newB
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combine plugin added resource attributes with ones found in the environment
|
// Combine plugin added resource attributes with ones found in the environment
|
||||||
@ -165,8 +157,10 @@ func appendPluginResourceAttributesEnvvar(env []string, cmd *cobra.Command, plug
|
|||||||
if v := strings.TrimSpace(os.Getenv(ResourceAttributesEnvvar)); v != "" {
|
if v := strings.TrimSpace(os.Getenv(ResourceAttributesEnvvar)); v != "" {
|
||||||
attrsSlice = append(attrsSlice, v)
|
attrsSlice = append(attrsSlice, v)
|
||||||
}
|
}
|
||||||
if v := b.String(); v != "" {
|
if b, err := baggage.New(members...); err != nil {
|
||||||
attrsSlice = append(attrsSlice, v)
|
otel.Handle(err)
|
||||||
|
} else if b.Len() > 0 {
|
||||||
|
attrsSlice = append(attrsSlice, b.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(attrsSlice) > 0 {
|
if len(attrsSlice) > 0 {
|
||||||
|
@ -26,7 +26,7 @@ const (
|
|||||||
|
|
||||||
// ResourceAttributesEnvvar is the name of the envvar that includes additional
|
// ResourceAttributesEnvvar is the name of the envvar that includes additional
|
||||||
// resource attributes for OTEL.
|
// resource attributes for OTEL.
|
||||||
ResourceAttributesEnvvar = "OTEL_RESOURCE_ATTRIBUTES"
|
ResourceAttributesEnvvar = command.ResourceAttributesEnvvar
|
||||||
)
|
)
|
||||||
|
|
||||||
// errPluginNotFound is the error returned when a plugin could not be found.
|
// errPluginNotFound is the error returned when a plugin could not be found.
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -292,6 +293,7 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions, ops ...CLIOption)
|
|||||||
if cli.enableGlobalTracer {
|
if cli.enableGlobalTracer {
|
||||||
cli.createGlobalTracerProvider(cli.baseCtx)
|
cli.createGlobalTracerProvider(cli.baseCtx)
|
||||||
}
|
}
|
||||||
|
filterResourceAttributesEnvvar()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -591,3 +593,46 @@ func DefaultContextStoreConfig() store.Config {
|
|||||||
defaultStoreEndpoints...,
|
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, ",")
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user