| package manager |
| |
| import ( |
| "fmt" |
| "os" |
| "strings" |
| |
| "github.com/docker/cli/cli-plugins/metadata" |
| "github.com/spf13/cobra" |
| "go.opentelemetry.io/otel" |
| "go.opentelemetry.io/otel/attribute" |
| "go.opentelemetry.io/otel/baggage" |
| ) |
| |
| const ( |
| // resourceAttributesEnvVar is the name of the envvar that includes additional |
| // resource attributes for OTEL as defined in the [OpenTelemetry specification]. |
| // |
| // [OpenTelemetry specification]: https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#general-sdk-configuration |
| resourceAttributesEnvVar = "OTEL_RESOURCE_ATTRIBUTES" |
| |
| // dockerCLIAttributePrefix is the prefix for any docker cli OTEL attributes. |
| // |
| // It is a copy of the const defined in [command.dockerCLIAttributePrefix]. |
| dockerCLIAttributePrefix = "docker.cli." |
| cobraCommandPath = attribute.Key("cobra.command_path") |
| ) |
| |
| func getPluginResourceAttributes(cmd *cobra.Command, plugin Plugin) attribute.Set { |
| commandPath := cmd.Annotations[metadata.CommandAnnotationPluginCommandPath] |
| if commandPath == "" { |
| commandPath = fmt.Sprintf("%s %s", cmd.CommandPath(), plugin.Name) |
| } |
| |
| attrSet := attribute.NewSet( |
| cobraCommandPath.String(commandPath), |
| ) |
| |
| kvs := make([]attribute.KeyValue, 0, attrSet.Len()) |
| for iter := attrSet.Iter(); iter.Next(); { |
| attr := iter.Attribute() |
| kvs = append(kvs, attribute.KeyValue{ |
| Key: dockerCLIAttributePrefix + attr.Key, |
| Value: attr.Value, |
| }) |
| } |
| return attribute.NewSet(kvs...) |
| } |
| |
| func appendPluginResourceAttributesEnvvar(env []string, cmd *cobra.Command, plugin Plugin) []string { |
| if attrs := getPluginResourceAttributes(cmd, plugin); attrs.Len() > 0 { |
| // Construct baggage members for each of the attributes. |
| // Ignore any failures as these aren't significant and |
| // represent an internal issue. |
| members := make([]baggage.Member, 0, attrs.Len()) |
| for iter := attrs.Iter(); iter.Next(); { |
| attr := iter.Attribute() |
| m, err := baggage.NewMemberRaw(string(attr.Key), attr.Value.AsString()) |
| if err != nil { |
| otel.Handle(err) |
| continue |
| } |
| members = append(members, m) |
| } |
| |
| // Combine plugin added resource attributes with ones found in the environment |
| // variable. Our own attributes should be namespaced so there shouldn't be a |
| // conflict. We do not parse the environment variable because we do not want |
| // to handle errors in user configuration. |
| attrsSlice := make([]string, 0, 2) |
| if v := strings.TrimSpace(os.Getenv(resourceAttributesEnvVar)); v != "" { |
| attrsSlice = append(attrsSlice, v) |
| } |
| if b, err := baggage.New(members...); err != nil { |
| otel.Handle(err) |
| } else if b.Len() > 0 { |
| attrsSlice = append(attrsSlice, b.String()) |
| } |
| |
| if len(attrsSlice) > 0 { |
| env = append(env, resourceAttributesEnvVar+"="+strings.Join(attrsSlice, ",")) |
| } |
| } |
| return env |
| } |