Skip to content

feat(logging): beta channel auto-enables verbose + rotating-file logging#35

Open
hikaps wants to merge 2 commits into
developfrom
beta-logging
Open

feat(logging): beta channel auto-enables verbose + rotating-file logging#35
hikaps wants to merge 2 commits into
developfrom
beta-logging

Conversation

@hikaps

@hikaps hikaps commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a build-time release-channel switch that makes beta builds auto-enable verbose logging to both the console and a rotating log file, while prod builds stay quiet (warnings only). QT_LOGGING_RULES still overrides in both channels.

  • New CMake flag COUCHPLAY_BETA (default OFF = prod). When ON, the couchplay GUI executable gets COUCHPLAY_BETA defined.
  • Beta main() enables all couchplay.* debug categories (QLoggingCategory::setFilterRules("couchplay.*=true")) and mirrors every message to a rotating file sink.
  • Prod builds keep category defaults (QtWarningMsg) — console warnings only.
  • Scope: GUI app only. couchplay-helper (privileged D-Bus service) is untouched — privileged ops continue to the system journal.

Rotating file sink

RotatingFileLogger (src/core/Logging.{h,cpp}) — dependency-free, thread-safe:

  • Writes to $AppLocalDataLocation/logs/couchplay.log (5 MiB × 3 backups).
  • Rotates .1 → .2 → .3 with cap enforcement (oldest beyond the cap dropped).
  • Accounts for a pre-existing file's size so a resumed near-full session still rotates.
  • Fails open: on open() failure the logger is a safe no-op, so logging never crashes the app.

CI wiring

  • beta.yml-DCOUCHPLAY_BETA=ON
  • release.yml-DCOUCHPLAY_BETA=OFF

Verification

  • Build (both channels) in fedora:41 (CI-equivalent): beta (COUCHPLAY_BETA=ON) and prod (default OFF) both configure + build couchplay; full ctest suite passes (12/12) including the new test_logging.
  • Unit test test_logging (3 slots): rotation + cap enforcement, open-failure no-op, append-to-existing size accounting.
  • Runtime mechanism: beta app creates the log file at startup at the correct QStandardPaths::AppLocalDataLocation path; the message handler writes all messages to the rotating file (verified end-to-end in the e2e container: ~3.7 MB / 34 k lines captured through the handler).

Out of scope

  • No in-app Settings toggle (channel is the sole control axis, per the request).
  • No migration of existing raw qDebug/qWarning callsites — the message handler captures all messages regardless of category.

Follow-up (not blocking)

Capturing literal couchplay.* categorized lines in a live log requires the managers to run, which needs the full interactive Wayland session (the local e2e suite, selenium-webdriver-at-spi). That suite is run manually before a beta cut per AGENTS.md; the beta binary launched successfully through the e2e entrypoint during verification.

@hikaps
hikaps force-pushed the beta-logging branch 2 times, most recently from cd2ec0a to 4965791 Compare July 8, 2026 20:58
hikaps added 2 commits July 13, 2026 16:16
Add COUCHPLAY_BETA build flag (default OFF = prod). When ON, the couchplay
GUI enables all couchplay.* debug categories (QLoggingCategory::setFilterRules)
and mirrors every message to a rotating file sink at
$AppLocalDataLocation/logs/couchplay.log (5 MiB x 3 backups).

RotatingFileLogger (src/core/Logging.{h,cpp}): dependency-free, thread-safe
file sink; rotates .1->.2->.3 with cap enforcement, accounts for pre-existing
file size, and fails open (no-op) so logging never crashes the app.

Prod builds keep category defaults (warnings only, console). QT_LOGGING_RULES
still overrides in both channels. Scope: GUI app only -- couchplay-helper
(privileged D-Bus service) is untouched (privileged ops go to the journal).

CI: beta.yml builds -DCOUCHPLAY_BETA=ON, release.yml -DCOUCHPLAY_BETA=OFF.
Unit test test_logging covers rotation, cap enforcement, open-failure no-op,
and append-to-existing size accounting.
…ve CMake option

- CMakeLists.txt: declare COUCHPLAY_BETA *above* add_subdirectory(src), which
  consumes it. Previously the option followed the subdirectory; it worked only
  because -D pre-populates the cache and the OFF default coincides with
  "undefined is falsy". If the default ever flipped to ON, a fresh no-flag
  configure would silently yield a prod binary on the first pass. Now correct by
  construction; verified both -DCOUCHPLAY_BETA=ON (macro reaches the couchplay
  target) and no-flag (cache OFF, macro absent).

- RotatingFileLogger::rotate(): vacate the oldest slot before shifting, instead
  of removing it inside the loop. This fixes the documented maxBackups==1 case
  (where the shift loop never ran, so the active->.1 rename failed on every
  rotation after the first and the active file grew unbounded) and makes
  QFile::rename reliable since each target slot is vacated before it is filled.

- test_logging: pin the .2/.3 backup cascade (a shift-only-to-.1 regression
  previously passed), replace the vacuous QVERIFY(true) with a behavioral
  no-file/no-crash check, and add testMaxBackupsOne to defend the contract
  lower bound. All 4 slots pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant