Hi all! This is meant to be a general spot for describing how users tell Syft, Grype, and friends what output goes where. This is meant to start as a discussion and morph into something more authoritative we can link to in PR comments or whatever after the discussion concludes.
First up, some terms! There are 3 kinds of output that tools make:
- program output - this is the SBOM for Syft, the list of matches for grype, etc. By default, it goes to stdout in table format.
- Terminal UI output - this is fancy stuff like spinners, progress bars, realtime updating counts of packages, etc. By default, it goes to stderr if stderr is a TTY and is discarded otherwise.
- Logging output - this is logging. It has a level (error/warn/info/debug/trace) and a destination. By default the level is
warn
(meaning less severe messages are dropped) and the destination is stderr.
Then, there four configuration knobs:
quiet
e.g. a user has passed--quiet
. This should have the effect that nothing is going to the terminal besides program output.- Verbosity/log level determine what the log level is. For example
SYFT_LOG_LEVEL=debug
in the environment or-vv
on the command line should set the logger to keep messages atdebug
and above. - Presence/absence of a TTY - tools should only attempt to do fancy terminal things if they are in a fancy terminal. No point in filling GitHub actions log output with control characters meant to redraw progress bars, for example.
- A log file config, e.g.
SYFT_LOG_FILE=/tmp/log.txt
. This is a path on the local file system that will log to that path in addition to sderr.
None of these 4 affect program output, but rather logging and TUI output.
Here’s a table showing how these settings interact (first row is default behavior):
TTY Present | Quiet | Log File Set | Logging Destination | TUI Destination |
---|---|---|---|---|
Yes | No | No | stderr | stderr |
Yes | No | Yes | stderr and log file | stderr |
Yes | Yes | No | discard | discard |
Yes | Yes | Yes | log file only | discard |
No | No | No | stderr | discard |
No | No | Yes | stderr and log file | discard |
No | Yes | No | discard | discard |
No | Yes | Yes | log file only | discard |
Note that verbosity / log level is not in this table. That’s because verbosity / log level directly sets the level the logger will print, but this table describes where. In other words, if you’re in a row on this table where logs go to a file, and you pass -vvv
, you get trace logs in that file.
Program output is much simpler. By default, program output goes to stdout in table format. Other formats can be specified like -o json
to print JSON to stdout, or -o json=/some/path.json
to save the JSON file to a path without printing it.
One question I have right off the bat is: Should setting log file
prevent messages from the logger from going to stderr?
Let’s discuss a bit and then decide if this is the direction we want to commit to.