diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2016-04-25T14·47+0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2016-04-25T17·18+0200 |
commit | 5761827d5bd90efda9ba2183ac30ad73d51de6bf (patch) | |
tree | 4f99fc2bf540e598cff211bcbb454378bdcdee85 | |
parent | 6e1b09927930f47bfdf024dad4accd5583e2c5d2 (diff) |
Show the log tail when a build fails
If --no-build-output is given (which will become the default for the "nix" command at least), show the last 10 lines of the build output if the build fails.
-rw-r--r-- | src/libmain/shared.cc | 2 | ||||
-rw-r--r-- | src/libstore/build.cc | 54 | ||||
-rw-r--r-- | src/libstore/globals.cc | 1 | ||||
-rw-r--r-- | src/libstore/globals.hh | 8 | ||||
-rw-r--r-- | src/libstore/remote-store.cc | 2 | ||||
-rw-r--r-- | src/nix-daemon/nix-daemon.cc | 2 |
6 files changed, 54 insertions, 15 deletions
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index 0d9f9af73e16..0b6311516ad4 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -171,7 +171,7 @@ struct LegacyArgs : public MixCommonArgs : MixCommonArgs(programName), parseArg(parseArg) { mkFlag('Q', "no-build-output", "do not show build output", - &settings.buildVerbosity, lvlVomit); + &settings.verboseBuild, false); mkFlag('K', "keep-failed", "keep temporary directories of failed builds", &settings.keepFailed); diff --git a/src/libstore/build.cc b/src/libstore/build.cc index f680b3737895..3830d7a671e8 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -747,6 +747,11 @@ private: /* Number of bytes received from the builder's stdout/stderr. */ unsigned long logSize; + /* The most recent log lines. */ + std::list<std::string> logTail; + + std::string currentLogLine; + /* Pipe for the builder's standard output/error. */ Pipe builderOut; @@ -872,6 +877,7 @@ private: /* Callback used by the worker to write to the log. */ void handleChildOutput(int fd, const string & data) override; void handleEOF(int fd) override; + void flushLine(); /* Return the set of (in)valid paths. */ PathSet checkPathValidity(bool returnValid, bool checkHash); @@ -1462,11 +1468,19 @@ void DerivationGoal::buildDone() if (pathExists(chrootRootDir + i)) rename((chrootRootDir + i).c_str(), i.c_str()); + std::string msg = (format("builder for ‘%1%’ %2%") + % drvPath % statusToString(status)).str(); + + if (!settings.verboseBuild && !logTail.empty()) { + msg += (format("; last %d log lines:") % logTail.size()).str(); + for (auto & line : logTail) + msg += "\n " + line; + } + if (diskFull) - printMsg(lvlError, "note: build failure may have been caused by lack of free disk space"); + msg += "\nnote: build failure may have been caused by lack of free disk space"; - throw BuildError(format("builder for ‘%1%’ %2%") - % drvPath % statusToString(status)); + throw BuildError(msg); } /* Compute the FS closure of the outputs and register them as @@ -2920,8 +2934,20 @@ void DerivationGoal::handleChildOutput(int fd, const string & data) done(BuildResult::LogLimitExceeded); return; } - if (verbosity >= settings.buildVerbosity) - printMsg(lvlError, filterANSIEscapes(data, true)); // FIXME + + for (size_t pos = 0; true; ) { + auto newline = data.find('\n', pos); + + if (newline == std::string::npos) { + currentLogLine.append(data, pos, std::string::npos); + break; + } + + currentLogLine.append(data, pos, newline - pos); + flushLine(); + pos = newline + 1; + } + if (bzLogFile) { int err; BZ2_bzWrite(&err, bzLogFile, (unsigned char *) data.data(), data.size()); @@ -2937,10 +2963,23 @@ void DerivationGoal::handleChildOutput(int fd, const string & data) void DerivationGoal::handleEOF(int fd) { + flushLine(); worker.wakeUp(shared_from_this()); } +void DerivationGoal::flushLine() +{ + if (settings.verboseBuild) + printMsg(lvlInfo, filterANSIEscapes(currentLogLine, true)); + else { + logTail.push_back(currentLogLine); + if (logTail.size() > settings.logLines) logTail.pop_front(); + } + currentLogLine = ""; +} + + PathSet DerivationGoal::checkPathValidity(bool returnValid, bool checkHash) { PathSet result; @@ -3341,10 +3380,7 @@ void SubstitutionGoal::finished() void SubstitutionGoal::handleChildOutput(int fd, const string & data) { assert(fd == logPipe.readSide); - if (verbosity >= settings.buildVerbosity) - printMsg(lvlError, data); // FIXME - /* Don't write substitution output to a log file for now. We - probably should, though. */ + printMsg(lvlError, data); // FIXME } diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index f4c41d715f35..90539ea85420 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -28,7 +28,6 @@ Settings::Settings() keepFailed = false; keepGoing = false; tryFallback = false; - buildVerbosity = lvlError; maxBuildJobs = 1; buildCores = 1; #ifdef _SC_NPROCESSORS_ONLN diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index 8fa49e2dc120..60251ef421bf 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -78,8 +78,12 @@ struct Settings { instead. */ bool tryFallback; - /* Verbosity level for build output. */ - Verbosity buildVerbosity; + /* Whether to show build log output in real time. */ + bool verboseBuild = true; + + /* If verboseBuild is false, the number of lines of the tail of + the log to show if a build fails. */ + size_t logLines = 10; /* Maximum number of parallel build jobs. 0 means unlimited. */ unsigned int maxBuildJobs; diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 831f4a83e029..4663291b9171 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -120,7 +120,7 @@ void RemoteStore::setOptions(ref<Connection> conn) if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 2) conn->to << settings.useBuildHook; if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 4) - conn->to << settings.buildVerbosity + conn->to << (settings.verboseBuild ? lvlError : lvlVomit) << 0 // obsolete log type << 0 /* obsolete print build trace */; if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 6) diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc index fbac852e0bd8..3c2e0521028c 100644 --- a/src/nix-daemon/nix-daemon.cc +++ b/src/nix-daemon/nix-daemon.cc @@ -443,7 +443,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe if (GET_PROTOCOL_MINOR(clientVersion) >= 2) settings.useBuildHook = readInt(from) != 0; if (GET_PROTOCOL_MINOR(clientVersion) >= 4) { - settings.buildVerbosity = (Verbosity) readInt(from); + settings.verboseBuild = lvlError == (Verbosity) readInt(from); readInt(from); // obsolete logType readInt(from); // obsolete printBuildTrace } |