forked from lix-project/lix
Merge pull request #5769 from NixOS/ca/get-build-stats
Add a crude tracing mechansim for the build results
This commit is contained in:
commit
18e4851752
|
@ -17,6 +17,7 @@
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
@ -464,7 +465,6 @@ void DerivationGoal::inputsRealised()
|
||||||
Derivation drvResolved { *std::move(attempt) };
|
Derivation drvResolved { *std::move(attempt) };
|
||||||
|
|
||||||
auto pathResolved = writeDerivation(worker.store, drvResolved);
|
auto pathResolved = writeDerivation(worker.store, drvResolved);
|
||||||
resolvedDrv = drvResolved;
|
|
||||||
|
|
||||||
auto msg = fmt("Resolved derivation: '%s' -> '%s'",
|
auto msg = fmt("Resolved derivation: '%s' -> '%s'",
|
||||||
worker.store.printStorePath(drvPath),
|
worker.store.printStorePath(drvPath),
|
||||||
|
@ -475,9 +475,9 @@ void DerivationGoal::inputsRealised()
|
||||||
worker.store.printStorePath(pathResolved),
|
worker.store.printStorePath(pathResolved),
|
||||||
});
|
});
|
||||||
|
|
||||||
auto resolvedGoal = worker.makeDerivationGoal(
|
resolvedDrvGoal = worker.makeDerivationGoal(
|
||||||
pathResolved, wantedOutputs, buildMode);
|
pathResolved, wantedOutputs, buildMode);
|
||||||
addWaitee(resolvedGoal);
|
addWaitee(resolvedDrvGoal);
|
||||||
|
|
||||||
state = &DerivationGoal::resolvedFinished;
|
state = &DerivationGoal::resolvedFinished;
|
||||||
return;
|
return;
|
||||||
|
@ -938,16 +938,17 @@ void DerivationGoal::buildDone()
|
||||||
}
|
}
|
||||||
|
|
||||||
void DerivationGoal::resolvedFinished() {
|
void DerivationGoal::resolvedFinished() {
|
||||||
assert(resolvedDrv);
|
assert(resolvedDrvGoal);
|
||||||
|
auto resolvedDrv = *resolvedDrvGoal->drv;
|
||||||
|
|
||||||
auto resolvedHashes = staticOutputHashes(worker.store, *resolvedDrv);
|
auto resolvedHashes = staticOutputHashes(worker.store, resolvedDrv);
|
||||||
|
|
||||||
StorePathSet outputPaths;
|
StorePathSet outputPaths;
|
||||||
|
|
||||||
// `wantedOutputs` might be empty, which means “all the outputs”
|
// `wantedOutputs` might be empty, which means “all the outputs”
|
||||||
auto realWantedOutputs = wantedOutputs;
|
auto realWantedOutputs = wantedOutputs;
|
||||||
if (realWantedOutputs.empty())
|
if (realWantedOutputs.empty())
|
||||||
realWantedOutputs = resolvedDrv->outputNames();
|
realWantedOutputs = resolvedDrv.outputNames();
|
||||||
|
|
||||||
for (auto & wantedOutput : realWantedOutputs) {
|
for (auto & wantedOutput : realWantedOutputs) {
|
||||||
assert(initialOutputs.count(wantedOutput) != 0);
|
assert(initialOutputs.count(wantedOutput) != 0);
|
||||||
|
@ -979,9 +980,17 @@ void DerivationGoal::resolvedFinished() {
|
||||||
outputPaths
|
outputPaths
|
||||||
);
|
);
|
||||||
|
|
||||||
// This is potentially a bit fishy in terms of error reporting. Not sure
|
auto status = [&]() {
|
||||||
// how to do it in a cleaner way
|
auto resolvedResult = resolvedDrvGoal->getResult();
|
||||||
amDone(nrFailed == 0 ? ecSuccess : ecFailed, ex);
|
switch (resolvedResult.status) {
|
||||||
|
case BuildResult::AlreadyValid:
|
||||||
|
return BuildResult::ResolvesToAlreadyValid;
|
||||||
|
default:
|
||||||
|
return resolvedResult.status;
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
done(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
HookReply DerivationGoal::tryBuildHook()
|
HookReply DerivationGoal::tryBuildHook()
|
||||||
|
@ -1329,6 +1338,13 @@ void DerivationGoal::done(BuildResult::Status status, std::optional<Error> ex)
|
||||||
}
|
}
|
||||||
|
|
||||||
worker.updateProgress();
|
worker.updateProgress();
|
||||||
|
|
||||||
|
auto traceBuiltOutputsFile = getEnv("_NIX_TRACE_BUILT_OUTPUTS").value_or("");
|
||||||
|
if (traceBuiltOutputsFile != "") {
|
||||||
|
std::fstream fs;
|
||||||
|
fs.open(traceBuiltOutputsFile, std::fstream::out);
|
||||||
|
fs << worker.store.printStorePath(drvPath) << "\t" << result.toString() << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,8 @@ struct DerivationGoal : public Goal
|
||||||
/* The path of the derivation. */
|
/* The path of the derivation. */
|
||||||
StorePath drvPath;
|
StorePath drvPath;
|
||||||
|
|
||||||
/* The path of the corresponding resolved derivation */
|
/* The goal for the corresponding resolved derivation */
|
||||||
std::optional<BasicDerivation> resolvedDrv;
|
std::shared_ptr<DerivationGoal> resolvedDrvGoal;
|
||||||
|
|
||||||
/* The specific outputs that we need to build. Empty means all of
|
/* The specific outputs that we need to build. Empty means all of
|
||||||
them. */
|
them. */
|
||||||
|
|
|
@ -151,9 +151,33 @@ struct BuildResult
|
||||||
DependencyFailed,
|
DependencyFailed,
|
||||||
LogLimitExceeded,
|
LogLimitExceeded,
|
||||||
NotDeterministic,
|
NotDeterministic,
|
||||||
|
ResolvesToAlreadyValid,
|
||||||
} status = MiscFailure;
|
} status = MiscFailure;
|
||||||
std::string errorMsg;
|
std::string errorMsg;
|
||||||
|
|
||||||
|
std::string toString() const {
|
||||||
|
auto strStatus = [&]() {
|
||||||
|
switch (status) {
|
||||||
|
case Built: return "Built";
|
||||||
|
case Substituted: return "Substituted";
|
||||||
|
case AlreadyValid: return "AlreadyValid";
|
||||||
|
case PermanentFailure: return "PermanentFailure";
|
||||||
|
case InputRejected: return "InputRejected";
|
||||||
|
case OutputRejected: return "OutputRejected";
|
||||||
|
case TransientFailure: return "TransientFailure";
|
||||||
|
case CachedFailure: return "CachedFailure";
|
||||||
|
case TimedOut: return "TimedOut";
|
||||||
|
case MiscFailure: return "MiscFailure";
|
||||||
|
case DependencyFailed: return "DependencyFailed";
|
||||||
|
case LogLimitExceeded: return "LogLimitExceeded";
|
||||||
|
case NotDeterministic: return "NotDeterministic";
|
||||||
|
case ResolvesToAlreadyValid: return "ResolvesToAlreadyValid";
|
||||||
|
default: return "Unknown";
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
return strStatus + ((errorMsg == "") ? "" : " : " + errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
/* How many times this build was performed. */
|
/* How many times this build was performed. */
|
||||||
unsigned int timesBuilt = 0;
|
unsigned int timesBuilt = 0;
|
||||||
|
|
||||||
|
@ -170,7 +194,7 @@ struct BuildResult
|
||||||
time_t startTime = 0, stopTime = 0;
|
time_t startTime = 0, stopTime = 0;
|
||||||
|
|
||||||
bool success() {
|
bool success() {
|
||||||
return status == Built || status == Substituted || status == AlreadyValid;
|
return status == Built || status == Substituted || status == AlreadyValid || status == ResolvesToAlreadyValid;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue