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

Add log-level flag for skopeo #2514

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

robbmanes
Copy link

PR containers/image#2713 should really be type Tracef rather than Debugf, but skopeo doesn't support any log level except what the --debug flag offers.

More-or-less copy the --log-level behavior from podman for compatibility and this should allow for Trace logrus levels to work.

Keep the debug flag for backwards compatibility as well and it make it mutually exclusive with --debug.

@robbmanes
Copy link
Author

First time actually pushing a cobra change and making sure a global log level is applied to the containers org, would appreciate fact-checking to make sure I didn't break anything.

Keep the debug flag for backwards compatibility, but support other log
levels.

Signed-off-by: Robb Manes <[email protected]>
Copy link
Contributor

@mtrmac mtrmac left a comment

Choose a reason for hiding this comment

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

Thanks! Yes, having this option makes sense.

  • skopeo.1.md needs updating
  • Non-blocking: Unit tests for the log level parsing (perhaps split from .before into a smaller function?), covering (--log-level={valid,invalid}, --debug, both set, neither) would be nice.

var defaultUserAgent = "skopeo/" + version.Version

type globalOptions struct {
debug bool // Enable debug output
logLevel string // Set log level at or above debug (trace, etc)
Copy link
Contributor

Choose a reason for hiding this comment

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

The comment is incorrect – --log-level=fatal would also work.

@@ -79,6 +84,7 @@ func createApp() (*cobra.Command, *globalOptions) {
var dummyVersion bool
rootCommand.Flags().BoolVarP(&dummyVersion, "version", "v", false, "Version for Skopeo")
rootCommand.PersistentFlags().BoolVar(&opts.debug, "debug", false, "enable debug output")
rootCommand.PersistentFlags().StringVar(&opts.logLevel, "log-level", defaultLogLevel, fmt.Sprintf("Log messages above specified level (%s)", strings.Join(logLevels, ", ")))
Copy link
Contributor

Choose a reason for hiding this comment

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

Contrary to Podman’s practice, I think it makes much more sense to not set default option values. With option values defaulted at the CLI level, the code later has difficulty telling apart actual user input from the hard-coded defaults (or from values that come from config files).

@@ -19,10 +19,15 @@ import (
// and will be populated by the Makefile
var gitCommit = ""

// Supported logrus log levels
var logLevels = []string{"trace", "debug", "info", "warn", "warning", "error", "fatal", "panic"}
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be built from logrus.AllLevels, not hard-coded in Skopeo.

Copy link
Contributor

Choose a reason for hiding this comment

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

… second thought, all of logrus is deprecated. Nowadays the standard-library logging defines fewer levels: https://pkg.go.dev/log/slog#Level .

We probably do want “trace”; but maybe we can avoid committing to fatal/panic for now?

@@ -19,10 +19,15 @@ import (
// and will be populated by the Makefile
var gitCommit = ""

// Supported logrus log levels
var logLevels = []string{"trace", "debug", "info", "warn", "warning", "error", "fatal", "panic"}
var defaultLogLevel = "warn"
Copy link
Contributor

Choose a reason for hiding this comment

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

The default of logrus is actually info, but, anyway, see elsewhere, this should not need to exist.

Comment on lines +130 to +141
var found bool
for _, l := range logLevels {
if l == strings.ToLower(logLevel) {
found = true
break
}
}

if !found {
logrus.Fatal("Log Level %s is not supported, choose from: %s\n", logLevel, strings.Join(logLevels, ", "))
}

Copy link
Contributor

Choose a reason for hiding this comment

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

This is unnecessary, logrus.ParseLevel already fails if the input is invalid.


logrus.SetLevel(level)
if logrus.IsLevelEnabled(logrus.InfoLevel) {
logrus.Infof("Filtering at log level %s", logrus.GetLevel())
Copy link
Contributor

Choose a reason for hiding this comment

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

I’d prefer not starting every command output with such a line. (“info” is the default level).

  • There’s the UNIX tradition of “in simple cases, on success, print nothing”.
  • Some (mistaken?) users fail callers if anything has been printed to stderr
  • Anyway, longer scripts that include calls to Skopeo would probably want to collect full stderr output, and having that contain lines like this (with no context and possibly no other output following) seems unclean to me.

With a strict enough parsing, the users should be confident that the output exactly matches their expectations. We don’t have ls dir confirming “yes, I am reading dir”.

}

logrus.SetLevel(level)
if logrus.IsLevelEnabled(logrus.InfoLevel) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Infof already includes an IsLevelEnabled check; this is optimizing out only the GetLevel call, a single atomic load. I think that’s not worth the extra code.

@@ -114,9 +121,34 @@ func createApp() (*cobra.Command, *globalOptions) {

// before is run by the cli package for any command, before running the command-specific handler.
func (opts *globalOptions) before(cmd *cobra.Command, args []string) error {
// Set logging level based on debug or logLevel flags
Copy link
Contributor

Choose a reason for hiding this comment

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

Using both --log-level and --debug should fail because the user has probably made a mistake.

One way to do that would be to use NewOptionalStringValue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants