-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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 an option to print the logs in a machine-readable format #3073
Conversation
src/nix/main.cc
Outdated
@@ -79,8 +78,8 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs | |||
mkFlag() | |||
.longName("print-build-logs") | |||
.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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This message implies that -L
is also deprecated, which should not be the case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or alternatively to src/libmain
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is bar-with-logs
? Is it the same as nix --print-build-logs / -L
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be written as
throw Error("invalid log format '%i'", logFormat);
Also note that exception messages are not capitalized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 5bc2744
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
@@ -153,7 +164,7 @@ class ProgressBar : public Logger | |||
state->activitiesByType[type].its.emplace(act, i); | |||
|
|||
if (type == actBuild) { | |||
auto name = storePathToName(getS(fields, 0)); | |||
auto name = getName(fields, 4); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
@@ -17,20 +16,32 @@ static std::string getS(const std::vector<Logger::Field> & fields, size_t n) | |||
return fields[n].s; | |||
} | |||
|
|||
static std::string storePathToName(std::string path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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-format
option 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-format
option unusable). As a nice side effect, nix 1.0-style commands can now use--log-format bar
to get the status bar