fix(ui): trim verbose startup notice; show daemon output on shutdown for external daemons
- Loading "taking longer than expected" notice: shorten the body + hint so the startup screen reads less wordy (same info, ~half the text). - Shutdown screen: when the wallet attached to an EXTERNAL daemon (no captured stdout — debug_log_path_ is only set when we spawn it), the "dragonxd output" panel was always empty, leaving just a spinner. Fall back to tailing the daemon's debug.log so the user can watch the node flush the block index and exit. Adds App::tailDaemonDebugLog() (best-effort, reads only the file tail). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+37
@@ -5742,6 +5742,39 @@ void App::beginShutdown()
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::string> App::tailDaemonDebugLog(int maxLines) const
|
||||
{
|
||||
std::vector<std::string> out;
|
||||
if (maxLines <= 0) return out;
|
||||
const std::string path = util::Platform::getDataDir() + "debug.log";
|
||||
std::error_code ec;
|
||||
const auto sz = std::filesystem::file_size(path, ec);
|
||||
if (ec || sz == 0) return out;
|
||||
std::ifstream f(path, std::ios::binary);
|
||||
if (!f) return out;
|
||||
|
||||
// Read only the last ~16 KB — plenty for a handful of lines, cheap even for a multi-GB log.
|
||||
const std::uintmax_t kTailBytes = 16 * 1024;
|
||||
const std::uintmax_t start = sz > kTailBytes ? sz - kTailBytes : 0;
|
||||
f.seekg(static_cast<std::streamoff>(start), std::ios::beg);
|
||||
std::string chunk(static_cast<std::size_t>(sz - start), '\0');
|
||||
f.read(&chunk[0], static_cast<std::streamsize>(chunk.size()));
|
||||
chunk.resize(static_cast<std::size_t>(f.gcount()));
|
||||
|
||||
std::vector<std::string> lines;
|
||||
std::string cur;
|
||||
for (char c : chunk) {
|
||||
if (c == '\n') { if (!cur.empty()) lines.push_back(cur); cur.clear(); }
|
||||
else if (c != '\r') cur.push_back(c);
|
||||
}
|
||||
if (!cur.empty()) lines.push_back(cur);
|
||||
// When we seeked into the middle of the file the first line is a fragment — drop it.
|
||||
if (start > 0 && !lines.empty()) lines.erase(lines.begin());
|
||||
if (static_cast<int>(lines.size()) > maxLines)
|
||||
lines.erase(lines.begin(), lines.end() - static_cast<std::ptrdiff_t>(maxLines));
|
||||
return lines;
|
||||
}
|
||||
|
||||
void App::renderShutdownScreen()
|
||||
{
|
||||
using namespace ui::material;
|
||||
@@ -5974,6 +6007,10 @@ void App::renderShutdownScreen()
|
||||
// -------------------------------------------------------------------
|
||||
if (daemon_controller_) {
|
||||
auto lines = daemon_controller_->recentLines(8);
|
||||
// External daemon (attached, not spawned) has no captured stdout — tail its debug.log directly
|
||||
// so the user can still watch the node flush the block index and exit.
|
||||
if (lines.empty())
|
||||
lines = tailDaemonDebugLog(8);
|
||||
if (!lines.empty()) {
|
||||
float panelW = vp_size.x * shutElem("panel-width-fraction", 0.70f);
|
||||
float panelX = cx - panelW * 0.5f;
|
||||
|
||||
Reference in New Issue
Block a user