Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: logger initialization before flags parsing #7372

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions pkg/commands/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func loadPluginCommands() []*cobra.Command {
var commands []*cobra.Command
plugins, err := plugin.NewManager().LoadAll(ctx)
if err != nil {
log.DebugContext(ctx, "No plugins loaded")
log.DeferredLogger.Debug("No plugins loaded")
return nil
}
for _, p := range plugins {
Expand Down Expand Up @@ -160,13 +160,13 @@ func initConfig(configFile string, pathChanged bool) error {
if err := viper.ReadInConfig(); err != nil {
if errors.Is(err, os.ErrNotExist) {
if !pathChanged {
log.Debugf("Default config file %q not found, using built in values", log.FilePath(configFile))
log.DeferredLogger.Debug(fmt.Sprintf("Default config file %q not found, using built in values", log.FilePath(configFile)))
return nil
}
}
return xerrors.Errorf("config file %q loading error: %s", configFile, err)
}
log.Info("Loaded", log.FilePath(configFile))
log.DeferredLogger.Info("Loaded", log.FilePath(configFile))
return nil
}

Expand Down Expand Up @@ -216,6 +216,8 @@ func NewRootCommand(globalFlags *flag.GlobalFlagGroup) *cobra.Command {

// Initialize logger
log.InitLogger(globalOptions.Debug, globalOptions.Quiet)
// Print log messages waiting for logger initialization
log.DeferredLogger.PrintLogs()

return nil
},
Expand Down
10 changes: 5 additions & 5 deletions pkg/flag/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,10 @@ func (f *Flag[T]) Parse() error {
}

if f.Deprecated != "" && f.isSet() {
log.Warnf(`"--%s" is deprecated. %s`, f.Name, f.Deprecated)
log.DeferredLogger.Warn(fmt.Sprintf(`"--%s" is deprecated. %s`, f.Name, f.Deprecated))
}
if f.Removed != "" && f.isSet() {
log.Errorf(`"--%s" was removed. %s`, f.Name, f.Removed)
log.DeferredLogger.Error(fmt.Sprintf(`"--%s" was removed. %s`, f.Name, f.Removed))
return xerrors.Errorf(`removed flag ("--%s")`, f.Name)
}

Expand All @@ -140,7 +140,7 @@ func (f *Flag[T]) parse() any {
}
v = viper.Get(alias.ConfigName)
if v != nil {
log.Warnf("'%s' in config file is deprecated. Use '%s' instead.", alias.ConfigName, f.ConfigName)
log.DeferredLogger.Warn(fmt.Sprintf("'%s' in config file is deprecated. Use '%s' instead.", alias.ConfigName, f.ConfigName))
return v
}
}
Expand Down Expand Up @@ -307,7 +307,7 @@ func (f *Flag[T]) BindEnv() error {
}
if alias.Deprecated {
if _, ok := os.LookupEnv(envAlias); ok {
log.Warnf("'%s' is deprecated. Use '%s' instead.", envAlias, envName)
log.DeferredLogger.Warn(fmt.Sprintf("'%s' is deprecated. Use '%s' instead.", envAlias, envName))
}
}
}
Expand Down Expand Up @@ -848,7 +848,7 @@ func (a flagAliases) NormalizeFunc() func(*pflag.FlagSet, string) pflag.Normaliz
if alias.deprecated {
// NormalizeFunc is called several times
alias.once.Do(func() {
log.Warnf("'--%s' is deprecated. Use '--%s' instead.", name, alias.formalName)
log.DeferredLogger.Warn(fmt.Sprintf("'--%s' is deprecated. Use '--%s' instead.", name, alias.formalName))
})
}
name = alias.formalName
Expand Down
56 changes: 56 additions & 0 deletions pkg/log/deferred.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package log

// DeferredLogger are needed to save logs and print them after calling `PrintLogs()` command.
// for example, this may be necessary when the logger is not yet initialized, but messages need to be transmitted
// in this case, the messages are saved and printed after the logger is initialized
var DeferredLogger deferredLogger

type deferredLogger struct {
deferredLogs []deferredLog
}

type deferredLog struct {
logFunc func(format string, args ...any)
message string
args []any
}

func (d *deferredLogger) Debug(message string, args ...any) {
d.deferredLogs = append(d.deferredLogs, deferredLog{
logFunc: Debug,
message: message,
args: args,
})
}

func (d *deferredLogger) Info(message string, args ...any) {
d.deferredLogs = append(d.deferredLogs, deferredLog{
logFunc: Info,
message: message,
args: args,
})
}

func (d *deferredLogger) Warn(message string, args ...any) {
d.deferredLogs = append(d.deferredLogs, deferredLog{
logFunc: Warn,
message: message,
args: args,
})
}

func (d *deferredLogger) Error(message string, args ...any) {
d.deferredLogs = append(d.deferredLogs, deferredLog{
logFunc: Error,
message: message,
args: args,
})
}

func (d *deferredLogger) PrintLogs() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add this into:

trivy/pkg/log/logger.go

Lines 38 to 42 in 6ad1098

func InitLogger(debug, disable bool) {
level := lo.Ternary(debug, slog.LevelDebug, slog.LevelInfo)
out := lo.Ternary(disable, io.Discard, io.Writer(os.Stderr))
slog.SetDefault(New(NewHandler(out, &Options{Level: level})))
}

But perhaps it won't be entirely obvious

for _, l := range d.deferredLogs {
l.logFunc(l.message, l.args...)
}
// Clear deferredLogs
d.deferredLogs = nil
}
Loading