Skip to content

Commit

Permalink
Implement global verbose flag to set logger verbosity
Browse files Browse the repository at this point in the history
and if plugin root command already implement a verbose flag pass the flag value down to plugin
  • Loading branch information
mpanchajanya committed Mar 12, 2024
1 parent 426b9bb commit 889c768
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 12 deletions.
3 changes: 0 additions & 3 deletions docs/plugindev/style_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,6 @@ Available input components:

### Feedback principles

Useful for everyone, critical to the usability of screen-readers and automation
Support verbosity flags (`-v`, `--verbose`).

`--format` to define preferred output

* Useful for humans and machine users, ie table, value, json, csv, yaml, etc
Expand Down
92 changes: 83 additions & 9 deletions pkg/command/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ import (
"github.com/vmware-tanzu/tanzu-plugin-runtime/plugin"
)

// verbose flag to set the log level
var verbose int

// NewRootCmd creates a root command.
func NewRootCmd() (*cobra.Command, error) { //nolint: gocyclo,funlen
var rootCmd = newRootCmd()
Expand All @@ -42,6 +45,9 @@ func NewRootCmd() (*cobra.Command, error) { //nolint: gocyclo,funlen
// Configure defined environment variables found in the config file
cliconfig.ConfigureEnvVariables()

// Initialize the global verbose flag to set the log level verbosity (acceptable values 1 - 9)
rootCmd.PersistentFlags().IntVar(&verbose, "verbose", 0, "number for the log level verbosity(acceptable values 1 - 9)")

rootCmd.AddCommand(
newVersionCmd(),
newPluginCmd(),
Expand All @@ -58,6 +64,7 @@ func NewRootCmd() (*cobra.Command, error) { //nolint: gocyclo,funlen
newCEIPParticipationCmd(),
newGenAllDocsCmd(),
)

if _, err := ensureCLIInstanceID(); err != nil {
return nil, errors.Wrap(err, "failed to ensure CLI ID")
}
Expand Down Expand Up @@ -240,8 +247,40 @@ func newRootCmd() *cobra.Command {
// silencing usage for now as we are getting double usage from plugins on errors
SilenceUsage: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
// Sets the verbosity of the logger if TANZU_CLI_LOG_LEVEL is set
setLoggerVerbosity()
fmt.Println(args, "args", verbose)
// Validate the verbose flag
if verbose < 0 {
log.Errorf("Invalid value for verbose flag. It should be 0 or greater")
os.Exit(1)
}

// For CLI commands: Default the verbose value to -1 If the flag is not set by user
// For Plugin commands: This won't be executed since flags are not parsed by cli but send to plugin as args
if !cmd.Flags().Changed("verbose") {
verbose = -1
}

/**
Manually parse the flags when plugin command is triggered
1. For CLI commands; all flags have been parsed and removed from the list of args and this loop will not run
2. For Plugin commands; Since CLI doesn't parse args and sends all args to plugin this loop will run to verify if verbose flag is set by the user and then passes to plugin.
*/
parseFlagsForPluginCommands(args)

log.Infof("verbose %v", verbose)

// Sets the verbosity of the logger
setLoggerVerbosity(verbose)

//TODO: Remove test logs
log.Info("I am level default")
log.V(0).Info("I am level 0")
log.V(1).Info("I am level 1")
log.V(2).Info("I am level 2")
log.V(3).Info("I am level 3")
log.V(4).Info("I am level 4")
log.V(5).Info("I am level 5")
log.V(6).Info("I am level 6")

// Ensure mutual exclusion in current contexts just in case if any plugins with old
// plugin-runtime sets k8s context as current when tanzu context is already set as current
Expand Down Expand Up @@ -290,14 +329,49 @@ func newRootCmd() *cobra.Command {
return rootCmd
}

func parseFlagsForPluginCommands(args []string) {
for i := 0; i < len(args); i++ {
arg := args[i]
if arg == "--verbose" {
if i+1 < len(args) {
nextArg := args[i+1]
// Check if the next argument is another flag
if strings.HasPrefix(nextArg, "-") {
log.Errorf("Missing value for verbose flag")
os.Exit(1)
}
// Try to convert the next argument to an integer
// If it's not an integer, CLI doesn't parse the verbose flag
if v, err := strconv.Atoi(nextArg); err == nil {
verbose = v
}
// Skip the next argument
i++
} else {
log.Errorf("Missing value for verbose flag")
os.Exit(1)
}
}
}
}

// setLoggerVerbosity sets the verbosity of the logger if TANZU_CLI_LOG_LEVEL is set
func setLoggerVerbosity() {
// Configure the log level if env variable TANZU_CLI_LOG_LEVEL is set
logLevel := os.Getenv(log.EnvTanzuCLILogLevel)
if logLevel != "" {
logValue, err := strconv.ParseInt(logLevel, 10, 32)
if err == nil {
log.SetVerbosity(int32(logValue))
func setLoggerVerbosity(verbosity int) {
// If verbose global flag is passed set the log level verbosity if not then check if env variable TANZU_CLI_LOG_LEVEL is set
if verbosity >= 0 {
// Set the log level verbosity with the verbosity value
log.SetVerbosity(int32(verbosity))

// Set the TANZU_CLI_LOG_LEVEL env with the verbosity value
_ = os.Setenv(log.EnvTanzuCLILogLevel, strconv.Itoa(verbosity))
} else {
// Configure the log level if env variable TANZU_CLI_LOG_LEVEL is set
logLevel := os.Getenv(log.EnvTanzuCLILogLevel)
if logLevel != "" {
logValue, err := strconv.ParseInt(logLevel, 10, 32)
if err == nil {
log.SetVerbosity(int32(logValue))
}
}
}
}
Expand Down

0 comments on commit 889c768

Please sign in to comment.