Skip to content

Debug log page and tests#532

Open
epicleafies wants to merge 10 commits intobitcoin-core:qt6from
epicleafies:debug-log
Open

Debug log page and tests#532
epicleafies wants to merge 10 commits intobitcoin-core:qt6from
epicleafies:debug-log

Conversation

@epicleafies
Copy link
Copy Markdown
Contributor

@epicleafies epicleafies commented Mar 10, 2026

Created the debug log page #510.
Created functional and C++ unit tests for the debug log page.
The debug log is viewable within the page and can be viewed in an external text editor.
Debug log can be updated by the user and also auto updates.
Debug log automatically loads some of the logs and user can load more.
Screenshot from 2026-03-11 21-35-00
Screenshot from 2026-03-11 21-35-22

Copy link
Copy Markdown
Collaborator

@johnny9 johnny9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think 26e8ce7 should be pulled out into a different PR as it didn't fully address the gui test flakiness. Take a look at #533 I think it resolved the flakiness. At least i am able to run 50+ times in a row with those changes. I suspect waiting on PageStack transitions had the biggest impact.

@epicleafies epicleafies force-pushed the debug-log branch 3 times, most recently from d205a3e to 6ec0b8f Compare March 12, 2026 16:35
@hebasto
Copy link
Copy Markdown
Member

hebasto commented Mar 16, 2026

Please rebase.

Copy link
Copy Markdown
Collaborator

@johnny9 johnny9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop some of the unneeded commits that were created while we trying to resolve issues with the peer end to end test

Comment thread qml/models/peerdetailsmodel.cpp Outdated
}

void PeerDetailsModel::onModelRowsRemoved(const QModelIndex& parent, int first, int last)
void PeerDetailsModel::onModelRowsRemoved(const QModelIndex& parent, int first, int last)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop the commit 35b9c49 from this PR and open a new PR if this is still needed.

Comment thread test/functional/qml_test_peers.py Outdated
find_gui_binary,
)
from qml_driver import QmlDriver
from qml_driver import QmlDriver, QmlDriverError
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop commit 7c67c2a as i don't think it is necessary anymore

@epicleafies
Copy link
Copy Markdown
Contributor Author

All peer test fix attempts should be removed.

Copy link
Copy Markdown
Collaborator

@johnny9 johnny9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screencast.from.2026-03-28.20-10-16.mp4

Really cool set of features here. Unfortunately, it seems the html rich text rendering isnt working well on Ubuntu or Fedora. You can see the text disappearing after scrolling. It might be the case that this needs to be converted to a ListView of line items instead of an html table.

Also the spinner needs adjustment

Comment thread qml/models/nodemodel.h Outdated
QString debugLogOpenError() const { return m_debug_log_open_error; }
Q_INVOKABLE QVariantList debugLogLines(int max_lines = 10000);

QString formattedDebugLog() const { return m_formatted_debug_log; }
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of this is quite complicated. Enough so that I think it would be better to create a model specifically for parsing the debug log. DebugLogModel

@johnny9
Copy link
Copy Markdown
Collaborator

johnny9 commented Mar 30, 2026

Really cool set of features here. Unfortunately, it seems the html rich text rendering isnt working well on Ubuntu or Fedora. You can see the text disappearing after scrolling. It might be the case that this needs to be converted to a ListView of line items instead of an html table.

After testing I found that it was related to trying to render the html table layout

@epicleafies
Copy link
Copy Markdown
Contributor Author

The spinner works for me locally, I'll look into it. Does the rpc console display work for you? If so I'll probably update the debug log page so that the display is consistent.

@johnny9
Copy link
Copy Markdown
Collaborator

johnny9 commented Mar 30, 2026

The spinner works for me locally, I'll look into it. Does the rpc console display work for you? If so I'll probably update the debug log page so that the display is consistent.

the RPC console listview renders correctly but the scrolling doesnt work quite right. I left a comment on the PR on how to solve it. Switching to a listview to column layout for the debug log unfortunately means that the standard mouse selection highlight wont work. It would render exactly like we want but we'd have to think about the select+copy ux a bit. Anyway, it doesnt need to be perfect but lets at least solve this rendering problem

Add methods to NodeModel for in-app access to the Bitcoin debug log:

- debugLogPath() returns the active log file path from LogInstance().
- debugLogLines(max_lines) reads up to max_lines from the tail of the
  file using a seek-optimised strategy to avoid loading the entire
  file; debug.log on mainnet can exceed 100 MB.
- A QFileSystemWatcher monitors the file for modifications, emitting
  debugLogChanged(). The connection lambda re-adds the path after each
  signal so log rotation (delete + recreate) does not silently stop
  auto-refresh.
- refreshDebugLog(full_load) loads or incrementally prepends new lines.
  A rotation fallback resets to a full load if the anchor line
  disappears from the fetched window.
- buildFormattedDebugLog() renders the loaded lines as an HTML table
  with filtering (setDebugLogFilter) and theme colour injection via
  write-only Q_PROPERTYs set by Binding elements in QML.
- openDebugLogFile() opens debug.log in the system default editor via
  QDesktopServices.

Unit tests cover: debugLogPath() matching LogInstance(), missing-file
error reporting, error clearing on successful read, line content and
truncation to max_lines.
Add SettingsDebugLog, a read-only viewer for the Bitcoin debug log
accessible via Settings → About → Developer Options → Open Debug Log.

Features:
- Full-text search with 150 ms debounce; filtering runs in C++.
- Auto-refresh: QFileSystemWatcher triggers a 500 ms debounce timer
  so rapid writes during startup coalesce into a single refresh.
- Scroll-aware "new entries" pill showing how many lines arrived while
  the user was scrolled away from the top.
- "Load more" button when the log is truncated (default limit 1000
  lines); each press adds 1000 more.
- Timestamps shown as relative labels ("just now", "5 min ago", etc.)
  updated every 60 s.

Also honour -disablewallet in SetupAppMode(): previously the flag was
silently ignored in ENABLE_WALLET builds. Guard
WalletQmlController::initialize() so it bails out early when no wallet
loader is present.

Add objectName annotations to NodeRunner, NodeSettings, SettingsAbout,
and the developer settings entry so the test automation bridge can
navigate the UI programmatically.

Functional test walks Settings → About → Developer Options → Debug Log
and verifies: visibility, non-empty log, search filter and clear,
manual refresh, auto-refresh on file append, and back navigation.
Requires -DENABLE_TEST_AUTOMATION=ON.

QML unit test covers the debugLogOpenError binding logic in
DeveloperOptions without the C++ plugin dependency.
The class defined wait_for_property twice; Python silently used the
second (value-equality) definition, making the predicate-based overload
unreachable and breaking any caller that passed a lambda.  Merge both
into a single method that accepts either a callable predicate or a plain
value (treated as equality).
- Change doubling-loop break from >= to > so the loop continues when
  filtered.size() == limit with a partial file read, keeping has_more
  consistent with the > check used to compute it; snapshot limit to a
  local variable for clarity.
- Reset nodeModel.debugLogFilter to "" in Component.onCompleted so a
  stale search filter from a previous visit cannot silently reduce the
  displayed count on re-entry.
Introduce a reusable scrollable monospace text display backed by a
list model, intended to be shared between the RPC console and the
debug log page. Built on Flickable + Column + Repeater so child
heights sum exactly and the scrollbar stays stable on long rows;
virtualization is deliberately omitted and callers must bound the
model size.

Supports optional left/right columns around the main content column
(e.g. line numbers + relative time for the debug log, or timestamps
for the console), configurable content text format so consumers opt
into RichText explicitly, theme-aware selection colours, and
coalesced auto-scroll so bulk appends schedule a single scroll.
Add a Settings > Debug Log page backed by a new DebugLogModel,
accessible from NodeSettings. The page renders debug.log entries
newest-first using the shared MonospaceOutputView component with
line numbers on the left and relative timestamps on the right,
offers in-memory search, a refresh action, an "open in external
editor" action, and a "Load more" affordance bounded by a hard cap.

DebugLogModel reads the log off the GUI thread via QtConcurrent so
a noisy node cannot stall the UI, coalesces bursts of file-watcher
events through a trailing-refresh guard, and emits a newLinesAdded
signal that drives a "N new entries" pill when the user has
scrolled away from the newest row.
The standalone DebugLogModel (added in d7055a9) fully replaces the
debug-log reader that lived inside NodeModel. No QML code on the
current tip references any of the removed properties, signals, or
invokable methods — they are dead code left over from the earlier
implementation.

Remove 11 Q_PROPERTYs, 6 signals, all debug-log member functions
and state (QFileSystemWatcher, formatted HTML builder, filter/colour
setters, refresh/load-more logic), the corresponding unit test file,
and its CMakeLists entry.
The Debug Log page is now reached via Settings → Debug Log
(NodeSettings.qml, added in d7055a9). The older route through
Settings → About → Developer Options → Debug Log is orphaned.

Remove the debugLogViewerRequested signal and "Open Debug Log"
Setting row from DeveloperOptions.qml, the corresponding handler
and debugLogPage Component from SettingsDeveloper.qml, the QML
test for the removed binding (tst_developeroptions.qml), and
update the functional test navigation path to use the new route.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants