From bdfe0bdeb009d01f1804290d17af7e78dacb389e Mon Sep 17 00:00:00 2001 From: Lior Vaisman Date: Thu, 30 Jun 2022 14:49:55 +0300 Subject: [PATCH 1/2] change log level to use verbosity and quiet flags --- internal/commands/config.go | 23 +++++++++++++++++++++-- internal/commands/flags.go | 12 ++++-------- internal/commands/root.go | 10 +++------- internal/config/models.go | 10 ++++++---- internal/logger/global.go | 2 +- internal/logger/logger.go | 15 +++++++++++++++ internal/logger/zerolog.go | 6 ++++-- 7 files changed, 54 insertions(+), 24 deletions(-) diff --git a/internal/commands/config.go b/internal/commands/config.go index 3fbc754..c3fc894 100644 --- a/internal/commands/config.go +++ b/internal/commands/config.go @@ -1,12 +1,15 @@ package commands -import "github.com/aquasecurity/chain-bench/internal/config" +import ( + "github.com/aquasecurity/chain-bench/internal/config" + "github.com/aquasecurity/chain-bench/internal/logger" +) func generateCliConfig() *config.Configuration { return &config.Configuration{ LogConfiguration: &config.LogConfiguration{ LogFilePath: logFilePath, - LogLevel: logLevel, + LogLevel: determineLogLevel(), LogFormat: logFormat, NoColor: noColor, }, @@ -15,3 +18,19 @@ func generateCliConfig() *config.Configuration { AccessToken: accessToken, } } + +func determineLogLevel() logger.LogLevel { + if isQuiet { + return logger.ErrorLevel + } + + if verbosity == 0 { // if no cli flag, prefer default/config file + return "" + } + + if verbosity == 1 { + return logger.DebugLevel + } + + return logger.TraceLevel +} diff --git a/internal/commands/flags.go b/internal/commands/flags.go index 8758e7a..7a81d02 100644 --- a/internal/commands/flags.go +++ b/internal/commands/flags.go @@ -17,18 +17,14 @@ var ( logFilePathFlagName = "log-file" logFilePathShortFlag = "l" - // logLevel the minimum log level - logLevel string - logLevelFlagName = "log-level" - // logFormat the format of the logs logFormat string logFormatFlagName = "log-format" - // verbose should log to console - verbose bool - verboseFlagName = "verbose" - verboseShortFlag = "v" + // number if flags determinds log level verbosiry (0 - info, 1 - debug, 2 - trace) + verbosity int + verbosityFlagName = "verbose" + verbosityShortFlag = "v" // noColor disables output color noColor bool diff --git a/internal/commands/root.go b/internal/commands/root.go index 5d23ec4..f084ccb 100644 --- a/internal/commands/root.go +++ b/internal/commands/root.go @@ -48,7 +48,6 @@ func NewChainBenchCommand(version string) *cobra.Command { func initLogger() error { logConfig := chainbenchConfig.LogConfiguration - if err := logger.InitLogger(logConfig.LogLevel, logConfig.LogFormat, logConfig.LogFilePath, logConfig.NoColor); err != nil { return fmt.Errorf("failed to init logger - %s", err.Error()) } @@ -61,7 +60,7 @@ func initialize(rootCmd *cobra.Command) { rootCmd.PersistentFlags().BoolVarP(&isQuiet, isQuietFlagName, isQuietShortFlag, false, - "silence logs and report findings, cannot be used without using the -o flag") + "silence logs, prints only error messages") rootCmd.PersistentFlags().StringVarP(&outputFilePath, outputFilePathFlagName, outputFilePathShortFlag, "", "the path to a file that will contain the results of the scanning") @@ -71,13 +70,10 @@ func initialize(rootCmd *cobra.Command) { rootCmd.PersistentFlags().StringVarP(&logFilePath, logFilePathFlagName, logFilePathShortFlag, "", "set to print logs into a file") - rootCmd.PersistentFlags().StringVar(&logLevel, logLevelFlagName, "", - "sets the minimum log level (debug, info, warning, error, panic)") rootCmd.PersistentFlags().StringVar(&logFormat, logFormatFlagName, "", fmt.Sprintf("sets the format of the logs (%s, %s)", logger.NormalFormat, logger.JsonFormat)) - rootCmd.PersistentFlags().BoolVarP(&verbose, verboseFlagName, verboseShortFlag, false, - "set to print logs to console") + rootCmd.PersistentFlags().CountVarP(&verbosity, verbosityFlagName, verbosityShortFlag, + "set the verbosity level (-v: debug, -vv: trace), default: info") rootCmd.PersistentFlags().BoolVar(&noColor, noColorFlagName, false, "disables output color") - } diff --git a/internal/config/models.go b/internal/config/models.go index ac235c8..861d0d0 100644 --- a/internal/config/models.go +++ b/internal/config/models.go @@ -1,5 +1,7 @@ package config +import "github.com/aquasecurity/chain-bench/internal/logger" + type Configuration struct { LogConfiguration *LogConfiguration `mapstructure:"logs"` OutputFilePath string `mapstructure:"output_path"` @@ -8,8 +10,8 @@ type Configuration struct { } type LogConfiguration struct { - LogFilePath string `mapstructure:"log_path"` - LogLevel string `mapstructure:"log_level"` - LogFormat string `mapstructure:"log_format"` - NoColor bool `mapstructure:"no_color"` + LogFilePath string `mapstructure:"log_path"` + LogLevel logger.LogLevel `mapstructure:"log_level"` + LogFormat string `mapstructure:"log_format"` + NoColor bool `mapstructure:"no_color"` } diff --git a/internal/logger/global.go b/internal/logger/global.go index e2063cc..599eeac 100644 --- a/internal/logger/global.go +++ b/internal/logger/global.go @@ -19,7 +19,7 @@ const ( ) // InitLogger initiates the global logger -func InitLogger(logLevel string, logFormat string, filePath string, noColor bool) error { +func InitLogger(logLevel LogLevel, logFormat string, filePath string, noColor bool) error { logFile := io.Discard consoleOutput := os.Stdout diff --git a/internal/logger/logger.go b/internal/logger/logger.go index f12488d..d3301d3 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -17,6 +17,21 @@ type Logger interface { Panicf(msg string, v ...interface{}) } +type LogLevel string + +const ( + TraceLevel LogLevel = "trace" + DebugLevel = "debug" + InfoLevel = "info" + WarnLevel = "warn" + ErrorLevel = "error" + PanicLevel = "panic" +) + +func (l LogLevel) String() string { + return string(l) +} + type ArgonLogger struct { context string } diff --git a/internal/logger/zerolog.go b/internal/logger/zerolog.go index 211aefc..e1a3052 100644 --- a/internal/logger/zerolog.go +++ b/internal/logger/zerolog.go @@ -13,10 +13,12 @@ var ( normalFileWriter zerolog.ConsoleWriter = zerolog.ConsoleWriter{Out: io.Discard, TimeFormat: "2006-01-02T15:04:05Z07:00", NoColor: true} ) -func setLogLevel(levelName string) error { +func setLogLevel(levelName LogLevel) error { var level zerolog.Level - switch strings.ToUpper(levelName) { + switch strings.ToUpper(levelName.String()) { + case "TRACE": + level = zerolog.TraceLevel case "DEBUG": level = zerolog.DebugLevel case "INFO": From a587185cd781fc86b70249cb1aae54279f8dabfb Mon Sep 17 00:00:00 2001 From: Lior Vaisman Date: Thu, 30 Jun 2022 17:25:34 +0300 Subject: [PATCH 2/2] print error details as debug --- internal/commands/root.go | 7 ++++--- internal/logger/global.go | 18 ++++++++++++------ internal/scm-clients/github/adapter.go | 22 +++++++++++----------- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/internal/commands/root.go b/internal/commands/root.go index f084ccb..5ffae1e 100644 --- a/internal/commands/root.go +++ b/internal/commands/root.go @@ -27,9 +27,10 @@ func Execute(version string) error { func NewChainBenchCommand(version string) *cobra.Command { return &cobra.Command{ - Use: "chain-bench", - Short: "Run CIS Benchmarks checks against your software supply chain", - Version: version, + Use: "chain-bench", + Short: "Run CIS Benchmarks checks against your software supply chain", + Version: version, + SilenceUsage: true, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { var err error diff --git a/internal/logger/global.go b/internal/logger/global.go index 599eeac..4058d4a 100644 --- a/internal/logger/global.go +++ b/internal/logger/global.go @@ -80,19 +80,17 @@ func FetchingFinished(msg string, icon emoji.Emoji) { } func Error(err error, msg string) error { + logger.Error().Msgf(msg) if err != nil { - logger.Error().Str("error", err.Error()).Msg(msg) - } else { - logger.Error().Msgf(msg) + logger.Debug().Str("error", err.Error()).Msg(msg) } return err } func Errorf(err error, msg string, v ...interface{}) error { + logger.Error().Msgf(msg, v...) if err != nil { - logger.Error().Str("error", err.Error()).Msgf(msg, v...) - } else { - logger.Error().Msgf(msg, v...) + logger.Debug().Str("error", err.Error()).Msgf(msg, v...) } return err } @@ -104,6 +102,14 @@ func Warnf(msg string, v ...interface{}) { logger.Warn().Msgf(msg, v...) } +func WarnE(err error, msg string) error { + logger.Warn().Msg(msg) + if err != nil { + logger.Debug().Str("error", err.Error()).Msgf(msg) + } + return err +} + func Panic(msg string) { logger.Panic().Msg(msg) } diff --git a/internal/scm-clients/github/adapter.go b/internal/scm-clients/github/adapter.go index 2bb0f4a..c73e526 100644 --- a/internal/scm-clients/github/adapter.go +++ b/internal/scm-clients/github/adapter.go @@ -49,24 +49,24 @@ func (ca *ClientAdapterImpl) GetRepository(owner string, repo string) (*models.R commits, _, err := ca.client.ListCommits(owner, repo, &github.CommitsListOptions{Since: time.Now().AddDate(0, -3, 0)}) if err != nil { - logger.Error(err, "error in fetching commits data") + logger.WarnE(err, "failed to fetch commits data") } branches, err := ca.ListRepositoryBranches(owner, repo) if err != nil { - logger.Error(err, "error in fetching branches data") + logger.WarnE(err, "failed to fetch branches data") } isRepoContainsSecurityMD := ca.isRepositoryContainsSecurityMdFile(owner, repo, utils.GetValue(rep.DefaultBranch)) collaborators, _, err := ca.client.ListRepositoryCollaborators(owner, repo) if err != nil { - logger.Error(err, "error in fetching collaborators data") + logger.WarnE(err, "failed to fetch collaborators data") } hooks, _, err := ca.client.ListRepositoryHooks(owner, repo) if err != nil { - logger.Error(err, "error in fetching hooks data") + logger.WarnE(err, "failed to fetch hooks data") } return toRepository(rep, branches, toUsers(collaborators), toHooks(hooks), toCommits(commits), isRepoContainsSecurityMD), nil @@ -84,7 +84,7 @@ func (ca *ClientAdapterImpl) ListRepositoryBranches(owner string, repo string) ( for _, b := range branches { commit, _, err := ca.client.GetCommit(owner, repo, utils.GetValue(b.Commit.SHA)) if err != nil { - logger.Error(err, "error in fetching branches commit") + logger.WarnE(err, "failed to fetch branches commit") } else { branch := &github.Branch{ Name: b.Name, @@ -111,17 +111,17 @@ func (ca *ClientAdapterImpl) isRepositoryContainsSecurityMdFile(owner, repo, def return false } -// GetRepositoryBranch implements clients.ClientAdapter +// GetCommit implements clients.ClientAdapter func (ca *ClientAdapterImpl) GetCommit(owner string, repo string, sha string) (*models.RepositoryCommit, error) { commit, _, err := ca.client.GetCommit(owner, repo, sha) if err != nil { - logger.Error(err, "error in fetching branch protection") + logger.Error(err, "error in fetching commit") return nil, err } return toCommit(commit), nil } -// GetRepositoryBranch implements clients.ClientAdapter +// GetBranchProtection implements clients.ClientAdapter func (ca *ClientAdapterImpl) GetBranchProtection(owner string, repo string, branch string) (*models.Protection, error) { prot, _, err := ca.client.GetBranchProtection(owner, repo, branch) if err != nil { @@ -131,7 +131,7 @@ func (ca *ClientAdapterImpl) GetBranchProtection(owner string, repo string, bran sc, _, err := ca.client.GetSignaturesOfProtectedBranch(owner, repo, branch) if err != nil { - logger.Error(err, "error in fetching commit signature protection") + logger.WarnE(err, "failed to fetch commit signature protection") } return toBranchProtection(prot, sc), nil } @@ -144,7 +144,7 @@ func (ca *ClientAdapterImpl) GetOrganization(owner string) (*models.Organization } hooks, _, err := ca.client.ListOrganizationHooks(owner) if err != nil { - logger.Error(err, "error in fetching organization hooks") + logger.WarnE(err, "failed to fetch organization hooks") } return toOrganization(org, toHooks(hooks)), nil } @@ -173,7 +173,7 @@ func (ca *ClientAdapterImpl) GetRegistry(organization *models.Organization) (*mo for _, packageType := range packagesTypes { pkgs, _, err := ca.client.ListOrganizationPackages(*organization.Login, packageType) if err != nil { - logger.Error(err, "error in fetching org packages") + logger.WarnE(err, "failed to fetch org packages") packages = nil break }