Adding in task attempts drilldown
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user