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  }