Skip to content

Commit 0b985e7

Browse files
authored
Merge pull request #5881 from thaJeztah/cleanup_otel
cli/command: un-export ResourceAttributesEnvvar, DockerCliAttributePrefix
2 parents c775585 + 8bedb69 commit 0b985e7

5 files changed

Lines changed: 134 additions & 113 deletions

File tree

cli-plugins/manager/cobra.go

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,10 @@ package manager
33
import (
44
"fmt"
55
"os"
6-
"strings"
76
"sync"
87

98
"github.com/docker/cli/cli/command"
109
"github.com/spf13/cobra"
11-
"go.opentelemetry.io/otel"
12-
"go.opentelemetry.io/otel/attribute"
13-
"go.opentelemetry.io/otel/baggage"
1410
)
1511

1612
const (
@@ -105,67 +101,3 @@ func AddPluginCommandStubs(dockerCli command.Cli, rootCmd *cobra.Command) (err e
105101
})
106102
return err
107103
}
108-
109-
const (
110-
dockerCliAttributePrefix = command.DockerCliAttributePrefix
111-
112-
cobraCommandPath = attribute.Key("cobra.command_path")
113-
)
114-
115-
func getPluginResourceAttributes(cmd *cobra.Command, plugin Plugin) attribute.Set {
116-
commandPath := cmd.Annotations[CommandAnnotationPluginCommandPath]
117-
if commandPath == "" {
118-
commandPath = fmt.Sprintf("%s %s", cmd.CommandPath(), plugin.Name)
119-
}
120-
121-
attrSet := attribute.NewSet(
122-
cobraCommandPath.String(commandPath),
123-
)
124-
125-
kvs := make([]attribute.KeyValue, 0, attrSet.Len())
126-
for iter := attrSet.Iter(); iter.Next(); {
127-
attr := iter.Attribute()
128-
kvs = append(kvs, attribute.KeyValue{
129-
Key: dockerCliAttributePrefix + attr.Key,
130-
Value: attr.Value,
131-
})
132-
}
133-
return attribute.NewSet(kvs...)
134-
}
135-
136-
func appendPluginResourceAttributesEnvvar(env []string, cmd *cobra.Command, plugin Plugin) []string {
137-
if attrs := getPluginResourceAttributes(cmd, plugin); attrs.Len() > 0 {
138-
// Construct baggage members for each of the attributes.
139-
// Ignore any failures as these aren't significant and
140-
// represent an internal issue.
141-
members := make([]baggage.Member, 0, attrs.Len())
142-
for iter := attrs.Iter(); iter.Next(); {
143-
attr := iter.Attribute()
144-
m, err := baggage.NewMemberRaw(string(attr.Key), attr.Value.AsString())
145-
if err != nil {
146-
otel.Handle(err)
147-
continue
148-
}
149-
members = append(members, m)
150-
}
151-
152-
// Combine plugin added resource attributes with ones found in the environment
153-
// variable. Our own attributes should be namespaced so there shouldn't be a
154-
// conflict. We do not parse the environment variable because we do not want
155-
// to handle errors in user configuration.
156-
attrsSlice := make([]string, 0, 2)
157-
if v := strings.TrimSpace(os.Getenv(ResourceAttributesEnvvar)); v != "" {
158-
attrsSlice = append(attrsSlice, v)
159-
}
160-
if b, err := baggage.New(members...); err != nil {
161-
otel.Handle(err)
162-
} else if b.Len() > 0 {
163-
attrsSlice = append(attrsSlice, b.String())
164-
}
165-
166-
if len(attrsSlice) > 0 {
167-
env = append(env, ResourceAttributesEnvvar+"="+strings.Join(attrsSlice, ","))
168-
}
169-
}
170-
return env
171-
}

cli-plugins/manager/manager.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ const (
2626

2727
// ResourceAttributesEnvvar is the name of the envvar that includes additional
2828
// resource attributes for OTEL.
29-
ResourceAttributesEnvvar = command.ResourceAttributesEnvvar
29+
//
30+
// Deprecated: The "OTEL_RESOURCE_ATTRIBUTES" env-var is part of the OpenTelemetry specification; users should define their own const for this. This const will be removed in the next release.
31+
ResourceAttributesEnvvar = "OTEL_RESOURCE_ATTRIBUTES"
3032
)
3133

3234
// errPluginNotFound is the error returned when a plugin could not be found.

cli-plugins/manager/telemetry.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package manager
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"strings"
7+
8+
"github.com/spf13/cobra"
9+
"go.opentelemetry.io/otel"
10+
"go.opentelemetry.io/otel/attribute"
11+
"go.opentelemetry.io/otel/baggage"
12+
)
13+
14+
const (
15+
// resourceAttributesEnvVar is the name of the envvar that includes additional
16+
// resource attributes for OTEL as defined in the [OpenTelemetry specification].
17+
//
18+
// [OpenTelemetry specification]: https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#general-sdk-configuration
19+
resourceAttributesEnvVar = "OTEL_RESOURCE_ATTRIBUTES"
20+
21+
// dockerCLIAttributePrefix is the prefix for any docker cli OTEL attributes.
22+
//
23+
// It is a copy of the const defined in [command.dockerCLIAttributePrefix].
24+
dockerCLIAttributePrefix = "docker.cli."
25+
cobraCommandPath = attribute.Key("cobra.command_path")
26+
)
27+
28+
func getPluginResourceAttributes(cmd *cobra.Command, plugin Plugin) attribute.Set {
29+
commandPath := cmd.Annotations[CommandAnnotationPluginCommandPath]
30+
if commandPath == "" {
31+
commandPath = fmt.Sprintf("%s %s", cmd.CommandPath(), plugin.Name)
32+
}
33+
34+
attrSet := attribute.NewSet(
35+
cobraCommandPath.String(commandPath),
36+
)
37+
38+
kvs := make([]attribute.KeyValue, 0, attrSet.Len())
39+
for iter := attrSet.Iter(); iter.Next(); {
40+
attr := iter.Attribute()
41+
kvs = append(kvs, attribute.KeyValue{
42+
Key: dockerCLIAttributePrefix + attr.Key,
43+
Value: attr.Value,
44+
})
45+
}
46+
return attribute.NewSet(kvs...)
47+
}
48+
49+
func appendPluginResourceAttributesEnvvar(env []string, cmd *cobra.Command, plugin Plugin) []string {
50+
if attrs := getPluginResourceAttributes(cmd, plugin); attrs.Len() > 0 {
51+
// Construct baggage members for each of the attributes.
52+
// Ignore any failures as these aren't significant and
53+
// represent an internal issue.
54+
members := make([]baggage.Member, 0, attrs.Len())
55+
for iter := attrs.Iter(); iter.Next(); {
56+
attr := iter.Attribute()
57+
m, err := baggage.NewMemberRaw(string(attr.Key), attr.Value.AsString())
58+
if err != nil {
59+
otel.Handle(err)
60+
continue
61+
}
62+
members = append(members, m)
63+
}
64+
65+
// Combine plugin added resource attributes with ones found in the environment
66+
// variable. Our own attributes should be namespaced so there shouldn't be a
67+
// conflict. We do not parse the environment variable because we do not want
68+
// to handle errors in user configuration.
69+
attrsSlice := make([]string, 0, 2)
70+
if v := strings.TrimSpace(os.Getenv(resourceAttributesEnvVar)); v != "" {
71+
attrsSlice = append(attrsSlice, v)
72+
}
73+
if b, err := baggage.New(members...); err != nil {
74+
otel.Handle(err)
75+
} else if b.Len() > 0 {
76+
attrsSlice = append(attrsSlice, b.String())
77+
}
78+
79+
if len(attrsSlice) > 0 {
80+
env = append(env, resourceAttributesEnvVar+"="+strings.Join(attrsSlice, ","))
81+
}
82+
}
83+
return env
84+
}

cli/command/cli.go

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"path/filepath"
1212
"runtime"
1313
"strconv"
14-
"strings"
1514
"sync"
1615
"time"
1716

@@ -586,46 +585,3 @@ func DefaultContextStoreConfig() store.Config {
586585
defaultStoreEndpoints...,
587586
)
588587
}
589-
590-
const (
591-
// ResourceAttributesEnvvar is the name of the envvar that includes additional
592-
// resource attributes for OTEL.
593-
ResourceAttributesEnvvar = "OTEL_RESOURCE_ATTRIBUTES"
594-
595-
// DockerCliAttributePrefix is the prefix for any docker cli OTEL attributes.
596-
DockerCliAttributePrefix = "docker.cli."
597-
)
598-
599-
func filterResourceAttributesEnvvar() {
600-
if v := os.Getenv(ResourceAttributesEnvvar); v != "" {
601-
if filtered := filterResourceAttributes(v); filtered != "" {
602-
os.Setenv(ResourceAttributesEnvvar, filtered)
603-
} else {
604-
os.Unsetenv(ResourceAttributesEnvvar)
605-
}
606-
}
607-
}
608-
609-
func filterResourceAttributes(s string) string {
610-
if trimmed := strings.TrimSpace(s); trimmed == "" {
611-
return trimmed
612-
}
613-
614-
pairs := strings.Split(s, ",")
615-
elems := make([]string, 0, len(pairs))
616-
for _, p := range pairs {
617-
k, _, found := strings.Cut(p, "=")
618-
if !found {
619-
// Do not interact with invalid otel resources.
620-
elems = append(elems, p)
621-
continue
622-
}
623-
624-
// Skip attributes that have our docker.cli prefix.
625-
if strings.HasPrefix(k, DockerCliAttributePrefix) {
626-
continue
627-
}
628-
elems = append(elems, p)
629-
}
630-
return strings.Join(elems, ",")
631-
}

cli/command/telemetry.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"os"
66
"path/filepath"
7+
"strings"
78
"sync"
89
"time"
910

@@ -216,3 +217,49 @@ func (r *cliReader) ForceFlush(ctx context.Context) error {
216217
func deltaTemporality(_ sdkmetric.InstrumentKind) metricdata.Temporality {
217218
return metricdata.DeltaTemporality
218219
}
220+
221+
// resourceAttributesEnvVar is the name of the envvar that includes additional
222+
// resource attributes for OTEL as defined in the [OpenTelemetry specification].
223+
//
224+
// [OpenTelemetry specification]: https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#general-sdk-configuration
225+
const resourceAttributesEnvVar = "OTEL_RESOURCE_ATTRIBUTES"
226+
227+
func filterResourceAttributesEnvvar() {
228+
if v := os.Getenv(resourceAttributesEnvVar); v != "" {
229+
if filtered := filterResourceAttributes(v); filtered != "" {
230+
_ = os.Setenv(resourceAttributesEnvVar, filtered)
231+
} else {
232+
_ = os.Unsetenv(resourceAttributesEnvVar)
233+
}
234+
}
235+
}
236+
237+
// dockerCLIAttributePrefix is the prefix for any docker cli OTEL attributes.
238+
// When updating, make sure to also update the copy in cli-plugins/manager.
239+
//
240+
// TODO(thaJeztah): move telemetry-related code to an (internal) package to reduce dependency on cli/command in cli-plugins, which has too many imports.
241+
const dockerCLIAttributePrefix = "docker.cli."
242+
243+
func filterResourceAttributes(s string) string {
244+
if trimmed := strings.TrimSpace(s); trimmed == "" {
245+
return trimmed
246+
}
247+
248+
pairs := strings.Split(s, ",")
249+
elems := make([]string, 0, len(pairs))
250+
for _, p := range pairs {
251+
k, _, found := strings.Cut(p, "=")
252+
if !found {
253+
// Do not interact with invalid otel resources.
254+
elems = append(elems, p)
255+
continue
256+
}
257+
258+
// Skip attributes that have our docker.cli prefix.
259+
if strings.HasPrefix(k, dockerCLIAttributePrefix) {
260+
continue
261+
}
262+
elems = append(elems, p)
263+
}
264+
return strings.Join(elems, ",")
265+
}

0 commit comments

Comments
 (0)