Adding in task attempts drilldown

This commit is contained in:
Ian Roddis
2022-01-06 15:20:06 -04:00
parent 1786b53f7b
commit 856e5bd2f4
7 changed files with 151 additions and 51 deletions

View File

@@ -392,62 +392,52 @@ namespace daggy::daggyd {
ss << '}';
}
else {
std::unordered_map<RunState, size_t> stateCounts;
for (const auto &[_, state] : run.taskRunStates) {
stateCounts[state]++;
}
ss << R"(<html>
<header>
<title>Details for RunID )"
<< runID << R"(</title>
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>mermaid.initialize({startOnLoad:true});</script>
</header>
<body>
<center>
<div class="mermaid">
)"
<< "graph LR;\n";
<h2>Summary</h2>
<table><tr><th>Run ID</th><th>Tag</th><th>State</th>
<th>#Tasks</th>
<th>Queued</th><th>Running</th><th>Retry</th>
<th>Errored</th><th>Completed</th></tr>
<tr>)"
<< "<td>" << runID << "</td>"
<< "<td>" << run.dagSpec.tag << "</td>"
<< "<td>" << run.dagStateChanges.back().state << "</td>"
<< "<td>" << run.dagSpec.tasks.size() << "</td>"
<< "<td>" << stateCounts[RunState::QUEUED] << "</td>"
<< "<td>" << stateCounts[RunState::RUNNING] << "</td>"
<< "<td>" << stateCounts[RunState::RETRY] << "</td>"
<< "<td>" << stateCounts[RunState::ERRORED] << "</td>"
<< "<td>" << stateCounts[RunState::COMPLETED] << "</td>"
<< "</tr></table>"
<< "<h2>Task Details</h2>"
<< "<table><tr><th>Task Name</th><th> State</th><th>Last "
"Update</th><th> Logs</th></tr>";
std::unordered_map<std::string, std::unordered_set<std::string>>
taskClassMap;
for (const auto &[taskName, task] : run.dagSpec.tasks) {
taskClassMap[task.definedName].emplace(taskName);
ss << "<tr>"
<< "<td>" << taskName << "</td>"
<< "<td>" << run.taskRunStates.at(taskName) << "</td>"
<< "<td>"
<< timePointToString(run.taskStateChanges.at(taskName).back().time)
<< "</td>"
<< "<td><a href=\"/v1/dagrun/" << runID << "/task/" << taskName
<< "\">Logs</a>"
<< "</tr>";
}
for (const auto &[taskName, task] : run.dagSpec.tasks) {
for (const auto &child : task.children) {
for (const auto &ci : taskClassMap[child]) {
ss << " " << taskName << "-->" << ci << '\n';
}
}
ss << "click " << taskName << " href \"/v1/dagrun/" << runID << "/task/"
<< taskName << "\"\n";
ss << "style " << taskName << " fill: #";
switch (run.taskStateChanges[taskName].back().state) {
case RunState::QUEUED:
ss << "55f";
break;
case RunState::RUNNING:
ss << "5a5";
break;
case RunState::RETRY:
ss << "55a";
break;
case RunState::ERRORED:
ss << "55F";
break;
case RunState::COMPLETED:
ss << "5f5";
break;
case RunState::KILLED:
ss << "fff";
break;
case RunState::PAUSED:
ss << "333";
break;
}
ss << '\n';
}
ss << "</div><center></body></html>";
ss << "</table></center></body></html>";
response.send(Pistache::Http::Code::Ok, ss.str());
}
response.send(Pistache::Http::Code::Ok, ss.str());
}
void Server::handleGetDAGRunState(const Pistache::Rest::Request &request,
@@ -557,14 +547,53 @@ namespace daggy::daggyd {
auto runID = request.param(":runID").as<DAGRunID>();
auto taskName = request.param(":taskName").as<std::string>();
bool isJSON = requestIsForJSON(request);
try {
auto task = logger_.getTask(runID, taskName);
response.send(Pistache::Http::Code::Ok, taskToJSON(task));
std::stringstream ss;
if (isJSON) {
Task task;
try {
task = logger_.getTask(runID, taskName);
}
catch (std::exception &e) {
REQ_RESPONSE(Not_Found, e.what());
}
ss << taskToJSON(task);
}
catch (std::exception &e) {
REQ_RESPONSE(Not_Found, e.what());
else {
std::optional<loggers::dag_run::TaskRecord> tr;
try {
tr.emplace(logger_.getTaskRecord(runID, taskName));
}
catch (std::exception &e) {
REQ_RESPONSE(Not_Found, e.what());
}
ss << "<html><title>Task Details for " << runID << " / " << taskName
<< "</title><body>"
<< "<table>"
<< "<tr><th>Name</th><td>" << taskName << "</td></tr>"
<< "<tr><th>State</th><td>" << tr->state << "</td></tr>"
<< "<tr><th>Definition</th><td>" << taskToJSON(tr->task)
<< "</td></tr>"
<< "<tr><th colspan=2>Attempts</th></tr>";
std::sort(tr->attempts.begin(), tr->attempts.end(),
[](const auto &a, const auto &b) {
return a.startTime < b.startTime;
});
for (size_t i = 0; i < tr->attempts.size(); ++i) {
const auto &attempt = tr->attempts[i];
ss << "<tr><td valign=top>" << timePointToString(attempt.startTime)
<< "</td><td><pre>rc: " << attempt.rc
<< "\n\nstdout:\n--------------\n"
<< attempt.outputLog << "\n\nstderr:\n--------------\n"
<< attempt.errorLog << "</pre></td></tr>";
}
ss << "</table></body></html>";
}
response.send(Pistache::Http::Code::Ok, ss.str());
}
void Server::handleGetTaskState(const Pistache::Rest::Request &request,