Open metametadata opened 2 weeks ago
Thanks for the report!
These logs are being generated in Syft, here: https://github.com/anchore/syft/blob/8095f7b8c14d2b2abf08c9516c7617c08e9fc319/internal/task/executor.go#L103
I can see how these seem noisy. I'll see if there's some better experience we can implement.
Hi @metametadata!
I went looking for our suggestion to add CPEs if we try to match on a CPE and non are available, and it is at https://github.com/anchore/grype/blob/c87f4a0f53225269097b478b9a5ef33521e13eef/grype/search/criteria.go#L31 as a log.Warn
, and warning show up without --verbose
.
In general, if a message is something a user could do to make the scan better, we try to log.Warn
it, which will show up without --verbose
. Is the message that got hidden in all the log.Info
s visible if you don't pass --verbose
?
Without --verbose
the message Consider re-running with --add-cpes-if-none
is not printed when grype
process is executed by my Clojure app (instead of directly in an interactive terminal).
I've written about it in the similar Syft issue: https://github.com/anchore/syft/issues/3081#issuecomment-2259026478.
Maybe the similar issue should be added in the Grype repo?
Hi @metametadata thanks for the response and for connecting this with the Syft issue! I think warnings being lost when not TTY is available is not a great experience and we should treat it as a bug.
Also, thanks for mentioning it happens when Grype is invoked via a Kotlin script - this clue really helped.
For investigating, I made a simple python script that wraps Grype and repros the issue:
import subprocess
import sys
args = ["grype"]
args.extend(sys.argv[1:])
process = subprocess.Popen(
args,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
bufsize=1,
)
try:
for stdout_line in iter(process.stdout.readline, ""):
sys.stdout.write(f"out: {stdout_line}")
sys.stdout.flush()
for stderr_line in iter(process.stderr.readline, ""):
sys.stderr.write(f"err: {stderr_line}")
sys.stderr.flush()
finally:
process.stdout.close()
process.stderr.close()
process.wait()
I'm guessing this is similar to the situation for Grype in your Kotlin script: stderr and stdout are captured within the parent process and printed indirectly, so grype can write bytes to either stderr or stdout, but no tty is present.
Reproing the error:
Grype will log.Warn
if you scan a dir because it wants to be told the name of the artifact rather than assuming the dir name, which gives us a quick way to repro: scan an empty directory.
❯ grype dir:.
... snip ...
[0000] WARN no explicit name and version provided for directory source, deriving artifact ID from the given path (which is not ideal)
No vulnerabilities found
❯ python pygrype.py dir:.
out: No vulnerabilities found
❯ python pygrype.py dir:. --verbose
python pygrype.py dir:. --verbose
out: No vulnerabilities found
err: [0000] INFO grype version: 0.82.0
err: [0000] WARN no explicit name and version provided for directory source, deriving artifact ID from the given path (which is not ideal)
err: [0000] INFO task completed elapsed=54.167µs task=environment-cataloger
... snip ...
... dozens of lines of log spam hiding the warning ...
So in the second version, we can see that the warning is dropped. I can get it back with --verbose
, but then, as @metametadata points out, the warning is drowned in a bunch of log.Info
calls.
I think a reasonable requirement we should take here is: Grype (and Syft) should display log.Warn
messages, even if no tty is present, unless --quiet
is passed.
I think what's happening is this:
--verbose
, Grype (and Syft) allocate a logger tied to stderr--verbose
, log.Warns go to the TUI.These three statements make sense separately, but combine to make it so that log.Warn
s don't have anywhere to go if there's no TUI and no --verbose
.
I'll try to add some code links in a minute.
The UI setup command is here: https://github.com/anchore/grype/blob/5c2b26249fbd4885a7d10a2046ef9d600acd346f/cmd/grype/cli/cli.go#L39
I suspect the bug may be over in https://github.com/anchore/clio, which is a Terminal UI library shared by Syft and Grype.
I think a reasonable requirement we should take here is: Grype (and Syft) should display log.Warn messages, even if no tty is present, unless --quiet is passed.
Agree. I then will be able to delete --verbose
arg from my grype
calls to see WARN logs without INFO ones.
v0.82.0
There are many seemingly useless logs on
--verbose
which make the reports harder to read and can hide more important messages produced on--verbose
(such as suggesting settingadd-cpes-if-none
).Maybe they could be hidden behind some other CLI flag instead of
--verbose
?