opam icon indicating copy to clipboard operation
opam copied to clipboard

In verbose mode, errors are sent to stdout

Open LasseBlaauwbroek opened this issue 3 years ago • 9 comments

When executing an install command in --verbose mode, any messages that are printed to /dev/stderr by a build command are redirected to /dev/stdout by Opam. It would be better if they would still end up in /dev/stderror, because this allows for easy separation of errors and normal messages.

LasseBlaauwbroek avatar Jan 04 '21 07:01 LasseBlaauwbroek

You can use for that the environment variable OPAMMERGEOUT

rjbou avatar Jan 04 '21 09:01 rjbou

Ah, I didn't know about that one. Thanks. However, I just tried to run

export OPAMMERGEOUT=0 && opam install . --verbose 1> /dev/null

on my project, and it does not display any errors, even though I know that running the exact same build command that Opam uses does produce warnings on stderr. So either I'm using it wrong, or there is a bug somewhere.

LasseBlaauwbroek avatar Jan 04 '21 10:01 LasseBlaauwbroek

It unmerges outputs for command outputs files. By default, stderr & stdout are merged in .out file. Those files are in .opam/log (unless you select another one with OPAMLOGS). They are displayed in the error report when an error occurs. In a successful run, file names are not logged at all (we should at least add it at a 2+ debugging level). For the moment you can clean your log dir (or create a temp new one) and look at those files: pkg-xxx-.info file gives the command ran, and pkg-xxx.{err,out} corresponding outputs (if unmerged).

On direct opam output, stderr is used for debug logs and error reports.

rjbou avatar Jan 04 '21 12:01 rjbou

Note that even during a successful run, warnings can still be printed to stderr by the build command. Given that OPAMMERGEOUT can separate pkg-xxx.err and pkg-xxx.out, it would make sense to me that --verbose mode would also send these logs to the proper terminal outputs. Or am I still misunderstanding?

LasseBlaauwbroek avatar Jan 04 '21 12:01 LasseBlaauwbroek

It makes sense yes, but it's not so trivial (display x.err in stderr) to implement as it need to give the context. As some actions are done in parallel, user can't know from which action originates the warning. One solution could be, when outputs are unmerged, to display a warning report, like the errors one.

@AltGr what's the original reason for the merged outputs?

rjbou avatar Jan 05 '21 11:01 rjbou

From experience, although it's counter-intuitive, you generally lose more information by separating stderr and stdout ; the reason being that relative ordering generally matters, and is in many cases a more relevant information than wether each line was printed to stdout or stderr. For example, a compiler may print the context to stdout, then an error to stderr.

I believe --verbose will only work for stdout, if you disable output merging, which might be your issue. I don't know what your use-case is, but you might be interested in the --json output which includes the build logs.

AltGr avatar Jan 18 '21 10:01 AltGr

From experience, although it's counter-intuitive, you generally lose more information by separating stderr and stdout

Yes, this is indeed true. However, in this case, a large amount of information was printed on stdout, and I wanted to know if there were warnings printed to stderr at all. Then it is useful just to check if something gets printed to stderr at all. However, I guess I can also look at pkg-xxx.err instead. So this is not a super critical problem, just unexpected.

I don't know what your use-case is, but you might be interested in the --json output which includes the build logs.

That is indeed an interesting option. However, on opam 2.0.7, when I run opam install xxx -v --json=test.json, the resulting json does not contain a build log, nor a link to a file containing a log:

{"opam-version":"2.0.7","command-line":["opam","reinstall",".","--json=test.json","--verbose"],"command-line":["opam","reinstall",".","--json=test.json","--verbose"],"switch":"/home/lasse/Documents/Projects/Tactician/develop","request":{"action":"reinstall","install":["coq-tactician.8.11.dev"],"remove":[],"upgrade":[],"criteria":"-changed,-count[version-lag:,false]"},"solution":[{"remove":{"name":"coq-tactician","version":"8.11.dev"}},{"install":{"name":"coq-tactician","version":"8.11.dev"}}],"results":[{"action":{"build":{"name":"coq-tactician","version":"8.11.dev"}},"result":"OK","duration":4.4425950050354},{"action":{"remove":{"name":"coq-tactician","version":"8.11.dev"}},"result":"OK","duration":0.0446019172668457},{"action":{"install":{"name":"coq-tactician","version":"8.11.dev"}},"result":"OK","duration":5.933771848678589}]}

LasseBlaauwbroek avatar Jan 18 '21 15:01 LasseBlaauwbroek

Mhm, but now that I'm trying this again, it seems that there are also problems with he logs:

  1. Opam only keeps logs in .opam/log/ when a build fails, even if set set OPAMKEEPLOGS.
  2. Opam does not respect OPAMLOGS. Log files always end op in .opam/logs/, even if I set something like export OPAMLOGS=$(pwd).

LasseBlaauwbroek avatar Jan 18 '21 16:01 LasseBlaauwbroek

This was discussed this morning. Steps:

  • [ ] https://github.com/ocaml/opam/issues/4490#issuecomment-762339185 needs to be triaged/reproduced/fixed
  • [ ] We need to verify that OPAMMERGEOUT=0 is behaving correctly w.r.t. the logs written in ~/.opam
  • [ ] Propose for opam 2.2 that OPAMMERGEOUT=0 opam --verbose should write always write the stderr logs to stderr (once that's been double-checked that it's not already the case!)

dra27 avatar Jun 25 '21 11:06 dra27