github.com/grahambrereton-form3/tilt@v0.10.18/internal/k8s/logging_kubectl_runner.go (about) 1 package k8s 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/windmilleng/tilt/pkg/logger" 8 ) 9 10 // wraps a kubectlRunner with logging 11 type loggingKubectlRunner struct { 12 kubectlLogLevel KubectlLogLevel 13 runner kubectlRunner 14 } 15 16 var _ kubectlRunner = loggingKubectlRunner{} 17 18 func (k loggingKubectlRunner) logExecStart(ctx context.Context, args []string, stdin string) { 19 if k.kubectlLogLevel == 0 { 20 return 21 } 22 23 logger.Get(ctx).Infof("Running: %q\n", append([]string{"tilt", "kubectl"}, args...)) 24 25 if stdin != "" { 26 logger.Get(ctx).Infof("stdin: '%s'\n", stdin) 27 } 28 } 29 30 func (k loggingKubectlRunner) logExecStop(ctx context.Context, stdout, stderr string) { 31 if k.kubectlLogLevel == 0 { 32 return 33 } 34 35 logger.Get(ctx).Infof("kubectl stdout: '%s'\nkubectl stderr: '%s'\n", stdout, stderr) 36 } 37 38 func (k loggingKubectlRunner) adjustedVerbosity(argv []string) []string { 39 if k.kubectlLogLevel == 0 { 40 // don't add -v0 so that in the normal case we're not doing anything surprising 41 return argv 42 } 43 // We're not gonna worry about the case where the input args already have a -v. 44 // Empirically, kubectl's behavior is to use the last -v arg it receives, so some call that specifies its own 45 // -v would get its -v, and not whatever the user specified on the command line. 46 // This isn't necessarily ideal (maybe we want to use the max, or always prefer k.kubectlLogLevel?), but: 47 // 1. We aren't calling this with any other -v at the moment. 48 // 2. Doing it right would mean handling ["-v" "4"], ["-v4"], ["-v=4"], and maybe others? really we'd ought to just 49 // call whatever arg parser kubectl uses. 50 return append([]string{"-v", fmt.Sprintf("%d", k.kubectlLogLevel)}, argv...) 51 } 52 53 func (k loggingKubectlRunner) exec(ctx context.Context, argv []string) (stdout string, stderr string, err error) { 54 argv = k.adjustedVerbosity(argv) 55 k.logExecStart(ctx, argv, "") 56 stdout, stderr, err = k.runner.exec(ctx, argv) 57 k.logExecStop(ctx, stdout, stderr) 58 return stdout, stderr, err 59 } 60 61 func (k loggingKubectlRunner) execWithStdin(ctx context.Context, argv []string, stdin string) (stdout string, stderr string, err error) { 62 argv = k.adjustedVerbosity(argv) 63 k.logExecStart(ctx, argv, stdin) 64 stdout, stderr, err = k.runner.execWithStdin(ctx, argv, stdin) 65 k.logExecStop(ctx, stdout, stderr) 66 return stdout, stderr, err 67 } 68 69 type KubectlLogLevel = int 70 71 func ProvideKubectlRunner(kubeContext KubeContext, logLevel KubectlLogLevel) kubectlRunner { 72 return loggingKubectlRunner{ 73 kubectlLogLevel: logLevel, 74 runner: realKubectlRunner{ 75 kubeContext: kubeContext, 76 }, 77 } 78 }