github.com/telepresenceio/telepresence/v2@v2.20.0-pro.6.0.20240517030216-236ea954e789/pkg/client/cli/cmd/loglevel.go (about)

     1  package cmd
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/sirupsen/logrus"
    10  	"github.com/spf13/cobra"
    11  	"google.golang.org/protobuf/types/known/durationpb"
    12  
    13  	"github.com/telepresenceio/telepresence/rpc/v2/connector"
    14  	"github.com/telepresenceio/telepresence/v2/pkg/client/cli/ann"
    15  	"github.com/telepresenceio/telepresence/v2/pkg/client/cli/connect"
    16  	"github.com/telepresenceio/telepresence/v2/pkg/client/cli/daemon"
    17  	"github.com/telepresenceio/telepresence/v2/pkg/errcat"
    18  )
    19  
    20  const defaultDuration = 30 * time.Minute
    21  
    22  type logLevelCommand struct {
    23  	duration   time.Duration
    24  	localOnly  bool
    25  	remoteOnly bool
    26  }
    27  
    28  func logLevelArg(cmd *cobra.Command, args []string) error {
    29  	if len(args) != 1 {
    30  		return errors.New("accepts exactly one argument (the log level)")
    31  	}
    32  	lvl, err := logrus.ParseLevel(args[0])
    33  	if err != nil {
    34  		return err
    35  	}
    36  	switch lvl {
    37  	case logrus.PanicLevel, logrus.FatalLevel:
    38  		return fmt.Errorf("unsupported log level: %s", lvl)
    39  	}
    40  	return nil
    41  }
    42  
    43  func loglevel() *cobra.Command {
    44  	lvs := logrus.AllLevels[2:] // Don't include `panic` and `fatal`
    45  	lvStrs := make([]string, len(lvs))
    46  	for i, lv := range lvs {
    47  		lvStrs[i] = lv.String()
    48  	}
    49  	lls := logLevelCommand{}
    50  	cmd := &cobra.Command{
    51  		Use:       fmt.Sprintf("loglevel <%s>", strings.Join(lvStrs, ",")),
    52  		Args:      logLevelArg,
    53  		Short:     "Temporarily change the log-level of the traffic-manager, traffic-agent, and user and root daemons",
    54  		RunE:      lls.setTempLogLevel,
    55  		ValidArgs: lvStrs,
    56  		Annotations: map[string]string{
    57  			ann.Session: ann.Required,
    58  		},
    59  	}
    60  	flags := cmd.Flags()
    61  	flags.DurationVarP(&lls.duration, "duration", "d", defaultDuration, "The time that the log-level will be in effect (0s means indefinitely)")
    62  	flags.BoolVarP(&lls.localOnly, "local-only", "l", false, "Only affect the user and root daemons")
    63  	flags.BoolVarP(&lls.remoteOnly, "remote-only", "r", false, "Only affect the traffic-manager and traffic-agents")
    64  	return cmd
    65  }
    66  
    67  func (lls *logLevelCommand) setTempLogLevel(cmd *cobra.Command, args []string) error {
    68  	rq := &connector.LogLevelRequest{LogLevel: args[0], Duration: durationpb.New(lls.duration)}
    69  	switch {
    70  	case lls.localOnly && lls.remoteOnly:
    71  		return errcat.User.New("the local-only and remote-only options are mutually exclusive")
    72  	case lls.localOnly:
    73  		rq.Scope = connector.LogLevelRequest_LOCAL_ONLY
    74  	case lls.remoteOnly:
    75  		rq.Scope = connector.LogLevelRequest_REMOTE_ONLY
    76  	}
    77  
    78  	if err := connect.InitCommand(cmd); err != nil {
    79  		return err
    80  	}
    81  	ctx := cmd.Context()
    82  	userD := daemon.GetUserClient(ctx)
    83  	_, err := userD.SetLogLevel(ctx, rq)
    84  	return err
    85  }