From dc6c59dc1495b29293c10ab21d93c527e0d6a066 Mon Sep 17 00:00:00 2001 From: AdamClark <40688281+AClarkie@users.noreply.github.com> Date: Sat, 29 Aug 2020 06:47:22 +0100 Subject: [PATCH] Print command output in line (#1354) This is an attempt to log helm exec output as the helm exec command is running. It only prints if the --debug flag is set. Co-authored-by: Yusuke Kuoka --- pkg/helmexec/id.go | 13 +++++++++++++ pkg/helmexec/log.go | 27 +++++++++++++++++++++++++++ pkg/helmexec/runner.go | 25 ++++++++++++++++++++----- 3 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 pkg/helmexec/id.go create mode 100644 pkg/helmexec/log.go diff --git a/pkg/helmexec/id.go b/pkg/helmexec/id.go new file mode 100644 index 00000000..84d75609 --- /dev/null +++ b/pkg/helmexec/id.go @@ -0,0 +1,13 @@ +package helmexec + +import "math/rand" + +var executionIDComponents = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + +func newExecutionID() string { + b := make([]rune, 5) + for i := range b { + b[i] = executionIDComponents[rand.Intn(len(executionIDComponents))] + } + return string(b) +} diff --git a/pkg/helmexec/log.go b/pkg/helmexec/log.go new file mode 100644 index 00000000..d2134705 --- /dev/null +++ b/pkg/helmexec/log.go @@ -0,0 +1,27 @@ +package helmexec + +import ( + "go.uber.org/zap" + "strings" +) + +type logWriterGenerator struct { + log *zap.SugaredLogger +} + +func (g logWriterGenerator) Writer(prefix string) *logWriter { + return &logWriter{ + log: g.log, + prefix: prefix, + } +} + +type logWriter struct { + log *zap.SugaredLogger + prefix string +} + +func (w *logWriter) Write(p []byte) (int, error) { + w.log.Debugf("%s%s", w.prefix, strings.TrimSpace(string(p))) + return len(p), nil +} diff --git a/pkg/helmexec/runner.go b/pkg/helmexec/runner.go index 8762c11d..c798f48e 100644 --- a/pkg/helmexec/runner.go +++ b/pkg/helmexec/runner.go @@ -4,12 +4,14 @@ import ( "bytes" "errors" "fmt" - "go.uber.org/zap" "io" "os" "os/exec" + "path/filepath" "strings" "syscall" + + "go.uber.org/zap" ) const ( @@ -34,21 +36,34 @@ func (shell ShellRunner) Execute(cmd string, args []string, env map[string]strin preparedCmd := exec.Command(cmd, args...) preparedCmd.Dir = shell.Dir preparedCmd.Env = mergeEnv(os.Environ(), env) - return Output(preparedCmd) + return Output(preparedCmd, &logWriterGenerator{ + log: shell.Logger, + }) } -func Output(c *exec.Cmd) ([]byte, error) { +func Output(c *exec.Cmd, logWriterGenerators ...*logWriterGenerator) ([]byte, error) { if c.Stdout != nil { return nil, errors.New("exec: Stdout already set") } if c.Stderr != nil { return nil, errors.New("exec: Stderr already set") } + var stdout bytes.Buffer var stderr bytes.Buffer var combined bytes.Buffer - c.Stdout = io.MultiWriter(&stdout, &combined) - c.Stderr = io.MultiWriter(&stderr, &combined) + + var logWriters []io.Writer + + id := newExecutionID() + for _, g := range logWriterGenerators { + logPrefix := fmt.Sprintf("%s:%s> ", filepath.Base(c.Path), id) + logWriters = append(logWriters, g.Writer(logPrefix)) + } + + c.Stdout = io.MultiWriter(append([]io.Writer{&stdout, &combined}, logWriters...)...) + c.Stderr = io.MultiWriter(append([]io.Writer{&stderr, &combined}, logWriters...)...) + err := c.Run() if err != nil {