diff --git a/data_for_test.go b/data_for_test.go index 3600335..6aeb270 100644 --- a/data_for_test.go +++ b/data_for_test.go @@ -631,7 +631,8 @@ var suites = []FixtureSuite{ { Name: "otel-cli span exec echo", Config: FixtureConfig{ - CliArgs: []string{"exec", "--service", "main_test.go", "--name", "test-span-123", "--kind", "server", "echo hello world"}, + // intentionally calling a command with no args bc it's a special case in exec.go + CliArgs: []string{"exec", "--service", "main_test.go", "--name", "test-span-123", "--kind", "server", "echo"}, Env: map[string]string{ "OTEL_EXPORTER_OTLP_ENDPOINT": "{{endpoint}}", "TRACEPARENT": "00-edededededededededededededed9000-edededededededed-01", @@ -643,7 +644,7 @@ var suites = []FixtureSuite{ "span_id": "*", "trace_id": "edededededededededededededed9000", }, - CliOutput: "hello world\n", + CliOutput: "\n", SpanCount: 1, }, }, @@ -655,7 +656,7 @@ var suites = []FixtureSuite{ Config: FixtureConfig{ CliArgs: []string{ "exec", "--name", "outer", "--endpoint", "{{endpoint}}", "--fail", "--verbose", "--", - "./otel-cli", "exec", "--name", "inner", "--endpoint", "{{endpoint}}", "--tp-required", "--fail", "--verbose", "echo hello world"}, + "./otel-cli", "exec", "--name", "inner", "--endpoint", "{{endpoint}}", "--tp-required", "--fail", "--verbose", "echo", "hello world"}, }, Expect: Results{ Config: otelcli.DefaultConfig(), diff --git a/otelcli/exec.go b/otelcli/exec.go index 7d136b2..b31b51e 100644 --- a/otelcli/exec.go +++ b/otelcli/exec.go @@ -1,11 +1,12 @@ package otelcli import ( + "bytes" "context" + "encoding/csv" "fmt" "os" "os/exec" - "runtime" "strings" "time" @@ -42,26 +43,22 @@ func init() { } func doExec(cmd *cobra.Command, args []string) { - // joining the string here is kinda gross... but should be fine - // there might be a better way in Cobra, maybe require passing it after a '--'? - commandString := strings.Join(args, " ") - // put the command in the attributes, before creating the span so it gets picked up - config.Attributes["command"] = commandString + config.Attributes["command"] = args[0] + config.Attributes["arguments"] = "" - span := NewProtobufSpanWithConfig(config) + var child *exec.Cmd + if len(args) > 1 { + // CSV-join the arguments to send as an attribute + buf := bytes.NewBuffer([]byte{}) + csv.NewWriter(buf).WriteAll([][]string{args[1:]}) + config.Attributes["arguments"] = buf.String() - // use cmd.exe to launch PowerShell on Windows - var shell string - if runtime.GOOS == "windows" { - shell = "cmd.exe" - commandString = "/C powershell " + commandString + child = exec.Command(args[0], args[1:]...) } else { - shell = "/bin/sh" + child = exec.Command(args[0]) } - child := exec.Command(shell, "-c", commandString) - // attach all stdio to the parent's handles child.Stdin = os.Stdin child.Stdout = os.Stdout @@ -78,6 +75,8 @@ func doExec(cmd *cobra.Command, args []string) { } } + span := NewProtobufSpanWithConfig(config) + // set the traceparent to the current span to be available to the child process if config.IsRecording() { tp := traceparentFromSpan(span)