Add an option to print the logs in a machine-readable format#3073
Add an option to print the logs in a machine-readable format#3073edolstra merged 8 commits intoNixOS:masterfrom
Conversation
src/nix/main.cc
Outdated
| .shortName('L') | ||
| .description("print full build logs on stderr") | ||
| .set(&printBuildLogs, true); | ||
| .description("print full build logs on stderr. DEPRECATED, use '--log-format bar-with-logs' instead") |
There was a problem hiding this comment.
This message implies that -L is also deprecated, which should not be the case.
There was a problem hiding this comment.
Indeed. I've removed it altogether. Tell me if you still want a depreciation warning on --print-build-logs
src/libutil/logging.cc
Outdated
| logFormatJSON, | ||
| logFormatBar, | ||
| logFormatBarWithLogs, | ||
| } LogFormat; |
There was a problem hiding this comment.
Can you move most of this to src/nix? That way src/libutil only contains the abstract Logger class and the implementations are in src/nix.
There was a problem hiding this comment.
Or alternatively to src/libmain.
There was a problem hiding this comment.
I've moved most of it to libmain. The implementation of SimpleLogger is still in that file, and JSONLogger is also still in libutil (because it's strongly tied to handleJSONLogMessage and that one is used in libstore). Does that look good?
src/libutil/logging.cc
Outdated
|
|
||
| nlohmann::json jsonActivityType(ActivityType type) override | ||
| { | ||
| switch (type) { |
There was a problem hiding this comment.
I think it's more maintainable to log the activity type and result type as a numerical value.
There was a problem hiding this comment.
It's an annoying tradeoff to make because magic numbers are definitely not user-friendly, but I agree these custom-print functions will probably cause some issue at some point (unless there's a way to auto-generate it?).
I've removed the custom json logger in 1e893d4, so we're back to numerical values.
|
I'm having some second-though on that PR: The internal json isn't really nice to work with from outside of Nix, so it would be nicer to first settle on a nicer format before being tied to a non-so-nice representation |
|
What makes it not so nice to use? |
|
There's a number of small things which either make it non-intuitive or require some non-trivial logic to get some useful information from it. In particular I noted:
(note that I'm not at all saying that it's a bad format per se, it seems to work quite well inside of Nix, but it's probably not a good format for an external consumption by a client which doesn't know the internals of Nix) |
|
I'm lacking of time to work on this right now. @edolstra What do you think of renaming the |
|
@regnat Yes, I think this looks good as-is. |
src/libmain/loggers.cc
Outdated
| logFormatRaw, | ||
| logFormatJSON, | ||
| logFormatBar, | ||
| logFormatBarWithLogs, |
There was a problem hiding this comment.
What is bar-with-logs? Is it the same as nix --print-build-logs / -L?
There was a problem hiding this comment.
src/libmain/loggers.cc
Outdated
| case logFormatBarWithLogs: | ||
| return createProgressBar(true); | ||
| default: | ||
| throw Error(format("Invalid log format '%i'") % logFormat); |
There was a problem hiding this comment.
This should be written as
throw Error("invalid log format '%i'", logFormat);
Also note that exception messages are not capitalized.
|
and now with documentation. @edolstra is there anything else you would like to see happening for this PR? |
|
Just noticed that this somehow cause |
|
@regnat I don't think the sandboxed builder should emit any logs, this is the real issue IMO. |
|
stracing the nix-daemon: pid 12635 is a build sandbox |
|
when the sandbox starts, it closes all the existing file descriptors except 1 and 2 (and 12 twice), so that's why writing to FD 4 is not possible. |
|
This is probably caused by which means that the child has the wrong logger if |
bd8a216 to
4a43d51
Compare
|
@edolstra I've fixed the file descriptor issue (was apparently due to |
src/libmain/progress-bar.cc
Outdated
|
|
||
| if (type == actBuild) { | ||
| auto name = storePathToName(getS(fields, 0)); | ||
| auto name = getName(fields, 4); |
There was a problem hiding this comment.
This no longer abbreviates the name, i.e. the progress bar now looks like this:
[1/0/2 built, 16.7 MiB DL] building /nix/store/g29xgw3fy960ghskj45x4x1mjv6jv3l2-nix-tarball-2.4pre7196_d94cc07 (autoconfPhase): autoreconf: running: ...
There was a problem hiding this comment.
Indeed, this was happening when using an older daemon (because the messages sent back by the daemon have been extended to include the (abbreviated) derivation name, but there's a fallback code for old daemons that don't do it, but it was missing a call to storePathToName).
Should be good now
src/libmain/progress-bar.cc
Outdated
| return fields[n].s; | ||
| } | ||
|
|
||
| static std::string storePathToName(std::string path) |
There was a problem hiding this comment.
Maybe use the original version? std::string_view is cheaper than std::string.
|
Might I ping this? :) |
73851d6 to
aa251ad
Compare
Add a new `--log-format` cli argument to change the format of the logs. The possible values are - raw (the default one for old-style commands) - bar (the default one for new-style commands) - bar-with-logs (equivalent to `--print-build-logs`) - internal-json (the internal machine-readable json format)
Make the printing of the build logs systematically go through the logger, and replicate the behavior of `no-build-output` by having two different loggers (one that prints the build logs and one that doesn't)
|
I've been reminded of this last week, so I rebased this on top of the latest master and simplified it as much as I could (well, nearly rewritten it from scratch actually 🤔 ), let me know what you think |
src/libmain/loggers.cc
Outdated
| @@ -0,0 +1,51 @@ | |||
| #include "loggers.hh" | |||
| #include "../nix/progress-bar.hh" | |||
There was a problem hiding this comment.
This makes libmain depend on nix, which is a layering violation. It means you can't link against libmain anymore.
There was a problem hiding this comment.
Mh that's annoying 🤔
I moved progress-bar to libmain to fix that, but it also required moving paths to libutil to prevent libmain from depending on libexpr. Not sure if that's a great idea
Needed so that we can include it as a logger in loggers.cc without adding a dependency on nix This also requires moving names.hh to libutil to prevent a circular dependency between libmain and libexpr
|
Merged, thanks! |
Add a
--log-formatoption which can be used to print the logs in json (pretty similar to the json logger used internally) so that external tools can easily consume it.This required moving things around a bit because nix 2.0-style commands where overriding the logging mechanism to display the status bar (which made the
--log-formatoption unusable). As a nice side effect, nix 1.0-style commands can now use--log-format barto get the status bar